@@ -1195,5 +1195,185 @@ define i1 @extract_value_smul_fail(i8 %xx, i8 %yy) {
1195
1195
ret i1 %r
1196
1196
}
1197
1197
1198
+ define i1 @test_sign_pos (float %x ) {
1199
+ ; CHECK-LABEL: @test_sign_pos(
1200
+ ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1201
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FABS]] to i32
1202
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1
1203
+ ; CHECK-NEXT: ret i1 [[SIGN]]
1204
+ ;
1205
+ %fabs = call float @llvm.fabs.f32 (float %x )
1206
+ %y = bitcast float %fabs to i32
1207
+ %sign = icmp sgt i32 %y , -1
1208
+ ret i1 %sign
1209
+ }
1210
+
1211
+ define i1 @test_sign_neg (float %x ) {
1212
+ ; CHECK-LABEL: @test_sign_neg(
1213
+ ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1214
+ ; CHECK-NEXT: [[FNABS:%.*]] = fneg float [[FABS]]
1215
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FNABS]] to i32
1216
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp slt i32 [[Y]], 0
1217
+ ; CHECK-NEXT: ret i1 [[SIGN]]
1218
+ ;
1219
+ %fabs = call float @llvm.fabs.f32 (float %x )
1220
+ %fnabs = fneg float %fabs
1221
+ %y = bitcast float %fnabs to i32
1222
+ %sign = icmp slt i32 %y , 0
1223
+ ret i1 %sign
1224
+ }
1225
+
1226
+ define <2 x i1 > @test_sign_pos_vec (<2 x float > %x ) {
1227
+ ; CHECK-LABEL: @test_sign_pos_vec(
1228
+ ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
1229
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x float> [[FABS]] to <2 x i32>
1230
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer
1231
+ ; CHECK-NEXT: ret <2 x i1> [[SIGN]]
1232
+ ;
1233
+ %fabs = call <2 x float > @llvm.fabs.v2f32 (<2 x float > %x )
1234
+ %y = bitcast <2 x float > %fabs to <2 x i32 >
1235
+ %sign = icmp slt <2 x i32 > %y , zeroinitializer
1236
+ ret <2 x i1 > %sign
1237
+ }
1238
+
1239
+ define i32 @test_inf_only (float nofpclass(nan sub norm zero) %x ) {
1240
+ ; CHECK-LABEL: @test_inf_only(
1241
+ ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1242
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
1243
+ ; CHECK-NEXT: ret i32 [[AND]]
1244
+ ;
1245
+ %y = bitcast float %x to i32
1246
+ %and = and i32 %y , 2147483647
1247
+ ret i32 %and
1248
+ }
1249
+
1250
+ define i32 @test_zero_only (float nofpclass(nan sub norm inf) %x ) {
1251
+ ; CHECK-LABEL: @test_zero_only(
1252
+ ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1253
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
1254
+ ; CHECK-NEXT: ret i32 [[AND]]
1255
+ ;
1256
+ %y = bitcast float %x to i32
1257
+ %and = and i32 %y , 2147483647
1258
+ ret i32 %and
1259
+ }
1260
+
1261
+ define i80 @test_zero_only_non_ieee (x86_fp80 nofpclass(nan sub norm inf) %x ) {
1262
+ ; CHECK-LABEL: @test_zero_only_non_ieee(
1263
+ ; CHECK-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[X:%.*]])
1264
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast x86_fp80 [[TMP1]] to i80
1265
+ ; CHECK-NEXT: ret i80 [[AND]]
1266
+ ;
1267
+ %y = bitcast x86_fp80 %x to i80
1268
+ %and = and i80 %y , 604462909807314587353087
1269
+ ret i80 %and
1270
+ }
1271
+
1272
+ define i32 @test_inf_nan_only (float nofpclass(sub norm zero) %x ) {
1273
+ ; CHECK-LABEL: @test_inf_nan_only(
1274
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1275
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1276
+ ; CHECK-NEXT: ret i32 [[AND]]
1277
+ ;
1278
+ %y = bitcast float %x to i32
1279
+ %and = and i32 %y , 2130706432
1280
+ ret i32 %and
1281
+ }
1282
+
1283
+ define i32 @test_sub_zero_only (float nofpclass(nan norm inf) %x ) {
1284
+ ; CHECK-LABEL: @test_sub_zero_only(
1285
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1286
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1287
+ ; CHECK-NEXT: ret i32 [[AND]]
1288
+ ;
1289
+ %y = bitcast float %x to i32
1290
+ %and = and i32 %y , 2130706432
1291
+ ret i32 %and
1292
+ }
1293
+
1294
+ define i32 @test_inf_zero_only (float nofpclass(nan norm sub ) %x ) {
1295
+ ; CHECK-LABEL: @test_inf_zero_only(
1296
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1297
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 16777215
1298
+ ; CHECK-NEXT: ret i32 [[AND]]
1299
+ ;
1300
+ %y = bitcast float %x to i32
1301
+ %and = and i32 %y , 16777215
1302
+ ret i32 %and
1303
+ }
1304
+
1305
+ define i1 @test_simplify_icmp (i32 %x ) {
1306
+ ; CHECK-LABEL: @test_simplify_icmp(
1307
+ ; CHECK-NEXT: [[CAST1:%.*]] = uitofp i32 [[X:%.*]] to double
1308
+ ; CHECK-NEXT: [[CAST2:%.*]] = bitcast double [[CAST1]] to i64
1309
+ ; CHECK-NEXT: [[MASK:%.*]] = and i64 [[CAST2]], -140737488355328
1310
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[MASK]], -1970324836974592
1311
+ ; CHECK-NEXT: ret i1 [[CMP]]
1312
+ ;
1313
+ %cast1 = uitofp i32 %x to double
1314
+ %cast2 = bitcast double %cast1 to i64
1315
+ %mask = and i64 %cast2 , -140737488355328
1316
+ %cmp = icmp eq i64 %mask , -1970324836974592
1317
+ ret i1 %cmp
1318
+ }
1319
+
1320
+ define i16 @test_simplify_mask (i32 %ui , float %x ) {
1321
+ ; CHECK-LABEL: @test_simplify_mask(
1322
+ ; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[UI:%.*]] to float
1323
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[CONV]], [[X:%.*]]
1324
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
1325
+ ; CHECK: if.end:
1326
+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[CONV]] to i32
1327
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[CAST]], 16
1328
+ ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i16
1329
+ ; CHECK-NEXT: [[AND:%.*]] = and i16 [[TRUNC]], -32768
1330
+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint i16 [[AND]], 31744
1331
+ ; CHECK-NEXT: ret i16 [[OR]]
1332
+ ; CHECK: if.else:
1333
+ ; CHECK-NEXT: ret i16 0
1334
+ ;
1335
+ %conv = uitofp i32 %ui to float
1336
+ %cmp = fcmp olt float %x , %conv
1337
+ br i1 %cmp , label %if.else , label %if.end
1338
+
1339
+ if.end:
1340
+ %cast = bitcast float %conv to i32
1341
+ %shr = lshr i32 %cast , 16
1342
+ %trunc = trunc i32 %shr to i16
1343
+ %and = and i16 %trunc , -32768
1344
+ %or = or disjoint i16 %and , 31744
1345
+ ret i16 %or
1346
+
1347
+ if.else:
1348
+ ret i16 0
1349
+ }
1350
+
1351
+ ; TODO: %cmp always evaluates to false
1352
+
1353
+ define i1 @test_simplify_icmp2 (double %x ) {
1354
+ ; CHECK-LABEL: @test_simplify_icmp2(
1355
+ ; CHECK-NEXT: [[ABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
1356
+ ; CHECK-NEXT: [[COND:%.*]] = fcmp oeq double [[ABS]], 0x7FF0000000000000
1357
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1358
+ ; CHECK: if.then:
1359
+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast double [[X]] to i64
1360
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CAST]], 3458764513820540928
1361
+ ; CHECK-NEXT: ret i1 [[CMP]]
1362
+ ; CHECK: if.else:
1363
+ ; CHECK-NEXT: ret i1 false
1364
+ ;
1365
+ %abs = tail call double @llvm.fabs.f64 (double %x )
1366
+ %cond = fcmp oeq double %abs , 0x7FF0000000000000
1367
+ br i1 %cond , label %if.then , label %if.else
1368
+
1369
+ if.then:
1370
+ %cast = bitcast double %x to i64
1371
+ %cmp = icmp eq i64 %cast , 3458764513820540928
1372
+ ret i1 %cmp
1373
+
1374
+ if.else:
1375
+ ret i1 false
1376
+ }
1377
+
1198
1378
declare void @use (i1 )
1199
1379
declare void @sink (i8 )
0 commit comments