@@ -999,5 +999,185 @@ define i1 @extract_value_smul_fail(i8 %xx, i8 %yy) {
999
999
ret i1 %r
1000
1000
}
1001
1001
1002
+ define i1 @test_sign_pos (float %x ) {
1003
+ ; CHECK-LABEL: @test_sign_pos(
1004
+ ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1005
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FABS]] to i32
1006
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1
1007
+ ; CHECK-NEXT: ret i1 [[SIGN]]
1008
+ ;
1009
+ %fabs = call float @llvm.fabs.f32 (float %x )
1010
+ %y = bitcast float %fabs to i32
1011
+ %sign = icmp sgt i32 %y , -1
1012
+ ret i1 %sign
1013
+ }
1014
+
1015
+ define i1 @test_sign_neg (float %x ) {
1016
+ ; CHECK-LABEL: @test_sign_neg(
1017
+ ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1018
+ ; CHECK-NEXT: [[FNABS:%.*]] = fneg float [[FABS]]
1019
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FNABS]] to i32
1020
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp slt i32 [[Y]], 0
1021
+ ; CHECK-NEXT: ret i1 [[SIGN]]
1022
+ ;
1023
+ %fabs = call float @llvm.fabs.f32 (float %x )
1024
+ %fnabs = fneg float %fabs
1025
+ %y = bitcast float %fnabs to i32
1026
+ %sign = icmp slt i32 %y , 0
1027
+ ret i1 %sign
1028
+ }
1029
+
1030
+ define <2 x i1 > @test_sign_pos_vec (<2 x float > %x ) {
1031
+ ; CHECK-LABEL: @test_sign_pos_vec(
1032
+ ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
1033
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x float> [[FABS]] to <2 x i32>
1034
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer
1035
+ ; CHECK-NEXT: ret <2 x i1> [[SIGN]]
1036
+ ;
1037
+ %fabs = call <2 x float > @llvm.fabs.v2f32 (<2 x float > %x )
1038
+ %y = bitcast <2 x float > %fabs to <2 x i32 >
1039
+ %sign = icmp slt <2 x i32 > %y , zeroinitializer
1040
+ ret <2 x i1 > %sign
1041
+ }
1042
+
1043
+ define i32 @test_inf_only (float nofpclass(nan sub norm zero) %x ) {
1044
+ ; CHECK-LABEL: @test_inf_only(
1045
+ ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1046
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
1047
+ ; CHECK-NEXT: ret i32 [[AND]]
1048
+ ;
1049
+ %y = bitcast float %x to i32
1050
+ %and = and i32 %y , 2147483647
1051
+ ret i32 %and
1052
+ }
1053
+
1054
+ define i32 @test_zero_only (float nofpclass(nan sub norm inf) %x ) {
1055
+ ; CHECK-LABEL: @test_zero_only(
1056
+ ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1057
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
1058
+ ; CHECK-NEXT: ret i32 [[AND]]
1059
+ ;
1060
+ %y = bitcast float %x to i32
1061
+ %and = and i32 %y , 2147483647
1062
+ ret i32 %and
1063
+ }
1064
+
1065
+ define i80 @test_zero_only_non_ieee (x86_fp80 nofpclass(nan sub norm inf) %x ) {
1066
+ ; CHECK-LABEL: @test_zero_only_non_ieee(
1067
+ ; CHECK-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[X:%.*]])
1068
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast x86_fp80 [[TMP1]] to i80
1069
+ ; CHECK-NEXT: ret i80 [[AND]]
1070
+ ;
1071
+ %y = bitcast x86_fp80 %x to i80
1072
+ %and = and i80 %y , 604462909807314587353087
1073
+ ret i80 %and
1074
+ }
1075
+
1076
+ define i32 @test_inf_nan_only (float nofpclass(sub norm zero) %x ) {
1077
+ ; CHECK-LABEL: @test_inf_nan_only(
1078
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1079
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1080
+ ; CHECK-NEXT: ret i32 [[AND]]
1081
+ ;
1082
+ %y = bitcast float %x to i32
1083
+ %and = and i32 %y , 2130706432
1084
+ ret i32 %and
1085
+ }
1086
+
1087
+ define i32 @test_sub_zero_only (float nofpclass(nan norm inf) %x ) {
1088
+ ; CHECK-LABEL: @test_sub_zero_only(
1089
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1090
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1091
+ ; CHECK-NEXT: ret i32 [[AND]]
1092
+ ;
1093
+ %y = bitcast float %x to i32
1094
+ %and = and i32 %y , 2130706432
1095
+ ret i32 %and
1096
+ }
1097
+
1098
+ define i32 @test_inf_zero_only (float nofpclass(nan norm sub ) %x ) {
1099
+ ; CHECK-LABEL: @test_inf_zero_only(
1100
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1101
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 16777215
1102
+ ; CHECK-NEXT: ret i32 [[AND]]
1103
+ ;
1104
+ %y = bitcast float %x to i32
1105
+ %and = and i32 %y , 16777215
1106
+ ret i32 %and
1107
+ }
1108
+
1109
+ define i1 @test_simplify_icmp (i32 %x ) {
1110
+ ; CHECK-LABEL: @test_simplify_icmp(
1111
+ ; CHECK-NEXT: [[CAST1:%.*]] = uitofp i32 [[X:%.*]] to double
1112
+ ; CHECK-NEXT: [[CAST2:%.*]] = bitcast double [[CAST1]] to i64
1113
+ ; CHECK-NEXT: [[MASK:%.*]] = and i64 [[CAST2]], -140737488355328
1114
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[MASK]], -1970324836974592
1115
+ ; CHECK-NEXT: ret i1 [[CMP]]
1116
+ ;
1117
+ %cast1 = uitofp i32 %x to double
1118
+ %cast2 = bitcast double %cast1 to i64
1119
+ %mask = and i64 %cast2 , -140737488355328
1120
+ %cmp = icmp eq i64 %mask , -1970324836974592
1121
+ ret i1 %cmp
1122
+ }
1123
+
1124
+ define i16 @test_simplify_mask (i32 %ui , float %x ) {
1125
+ ; CHECK-LABEL: @test_simplify_mask(
1126
+ ; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[UI:%.*]] to float
1127
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[CONV]], [[X:%.*]]
1128
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
1129
+ ; CHECK: if.end:
1130
+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[CONV]] to i32
1131
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[CAST]], 16
1132
+ ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i16
1133
+ ; CHECK-NEXT: [[AND:%.*]] = and i16 [[TRUNC]], -32768
1134
+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint i16 [[AND]], 31744
1135
+ ; CHECK-NEXT: ret i16 [[OR]]
1136
+ ; CHECK: if.else:
1137
+ ; CHECK-NEXT: ret i16 0
1138
+ ;
1139
+ %conv = uitofp i32 %ui to float
1140
+ %cmp = fcmp olt float %x , %conv
1141
+ br i1 %cmp , label %if.else , label %if.end
1142
+
1143
+ if.end:
1144
+ %cast = bitcast float %conv to i32
1145
+ %shr = lshr i32 %cast , 16
1146
+ %trunc = trunc i32 %shr to i16
1147
+ %and = and i16 %trunc , -32768
1148
+ %or = or disjoint i16 %and , 31744
1149
+ ret i16 %or
1150
+
1151
+ if.else:
1152
+ ret i16 0
1153
+ }
1154
+
1155
+ ; TODO: %cmp always evaluates to false
1156
+
1157
+ define i1 @test_simplify_icmp2 (double %x ) {
1158
+ ; CHECK-LABEL: @test_simplify_icmp2(
1159
+ ; CHECK-NEXT: [[ABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
1160
+ ; CHECK-NEXT: [[COND:%.*]] = fcmp oeq double [[ABS]], 0x7FF0000000000000
1161
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1162
+ ; CHECK: if.then:
1163
+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast double [[X]] to i64
1164
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CAST]], 3458764513820540928
1165
+ ; CHECK-NEXT: ret i1 [[CMP]]
1166
+ ; CHECK: if.else:
1167
+ ; CHECK-NEXT: ret i1 false
1168
+ ;
1169
+ %abs = tail call double @llvm.fabs.f64 (double %x )
1170
+ %cond = fcmp oeq double %abs , 0x7FF0000000000000
1171
+ br i1 %cond , label %if.then , label %if.else
1172
+
1173
+ if.then:
1174
+ %cast = bitcast double %x to i64
1175
+ %cmp = icmp eq i64 %cast , 3458764513820540928
1176
+ ret i1 %cmp
1177
+
1178
+ if.else:
1179
+ ret i1 false
1180
+ }
1181
+
1002
1182
declare void @use (i1 )
1003
1183
declare void @sink (i8 )
0 commit comments