@@ -1276,3 +1276,182 @@ define <2 x float> @test_select_neg_negx_x_wrong_type(<2 x float> %value) {
12761276 %value.addr.0.i = select i1 %a1 , <2 x float > %fneg.i , <2 x float > %value
12771277 ret <2 x float > %value.addr.0.i
12781278}
1279+
1280+ define i1 @test_fabs_used_by_fcmp (float %x , float %y ) {
1281+ ; CHECK-LABEL: @test_fabs_used_by_fcmp(
1282+ ; CHECK-NEXT: [[SEL:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1283+ ; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[SEL]], [[Y:%.*]]
1284+ ; CHECK-NEXT: ret i1 [[CMP2]]
1285+ ;
1286+ %cmp = fcmp oge float %x , 0 .000000e+00
1287+ %neg = fneg float %x
1288+ %sel = select i1 %cmp , float %x , float %neg
1289+ %cmp2 = fcmp olt float %sel , %y
1290+ ret i1 %cmp2
1291+ }
1292+
1293+ define float @test_fabs_used_by_fpop_nnan_nsz (float %x , float %y ) {
1294+ ; CHECK-LABEL: @test_fabs_used_by_fpop_nnan_nsz(
1295+ ; CHECK-NEXT: [[SEL:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1296+ ; CHECK-NEXT: [[ADD:%.*]] = fadd nnan nsz float [[SEL]], [[Y:%.*]]
1297+ ; CHECK-NEXT: ret float [[ADD]]
1298+ ;
1299+ %cmp = fcmp oge float %x , 0 .000000e+00
1300+ %neg = fneg float %x
1301+ %sel = select i1 %cmp , float %x , float %neg
1302+ %add = fadd nnan nsz float %sel , %y
1303+ ret float %add
1304+ }
1305+
1306+ define i1 @test_fabs_fsub_used_by_fcmp (float %x , float %y ) {
1307+ ; CHECK-LABEL: @test_fabs_fsub_used_by_fcmp(
1308+ ; CHECK-NEXT: [[SEL:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1309+ ; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[SEL]], [[Y:%.*]]
1310+ ; CHECK-NEXT: ret i1 [[CMP2]]
1311+ ;
1312+ %cmp = fcmp ogt float %x , 0 .000000e+00
1313+ %neg = fsub float 0 .000000e+00 , %x
1314+ %sel = select i1 %cmp , float %x , float %neg
1315+ %cmp2 = fcmp olt float %sel , %y
1316+ ret i1 %cmp2
1317+ }
1318+
1319+ define float @test_fabs_fsub_used_by_fpop_nnan (float %x , float %y ) {
1320+ ; CHECK-LABEL: @test_fabs_fsub_used_by_fpop_nnan(
1321+ ; CHECK-NEXT: [[SEL:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1322+ ; CHECK-NEXT: [[ADD:%.*]] = fadd nnan float [[SEL]], [[Y:%.*]]
1323+ ; CHECK-NEXT: ret float [[ADD]]
1324+ ;
1325+ %cmp = fcmp ogt float %x , 0 .000000e+00
1326+ %neg = fsub float 0 .000000e+00 , %x
1327+ %sel = select i1 %cmp , float %x , float %neg
1328+ %add = fadd nnan float %sel , %y
1329+ ret float %add
1330+ }
1331+
1332+ ; TODO: fadd ignores the sign bit of NaN.
1333+ define float @test_fabs_used_by_fpop_nsz (float %x , float %y ) {
1334+ ; CHECK-LABEL: @test_fabs_used_by_fpop_nsz(
1335+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1336+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1337+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1338+ ; CHECK-NEXT: [[ADD:%.*]] = fadd nsz float [[SEL]], [[Y:%.*]]
1339+ ; CHECK-NEXT: ret float [[ADD]]
1340+ ;
1341+ %cmp = fcmp oge float %x , 0 .000000e+00
1342+ %neg = fneg float %x
1343+ %sel = select i1 %cmp , float %x , float %neg
1344+ %add = fadd nsz float %sel , %y
1345+ ret float %add
1346+ }
1347+
1348+ ; TODO: copysign ignores the sign bit of NaN magnitude.
1349+ define float @test_fabs_used_by_fcopysign_mag (float %x , float %y ) {
1350+ ; CHECK-LABEL: @test_fabs_used_by_fcopysign_mag(
1351+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X1:%.*]], 0.000000e+00
1352+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X1]]
1353+ ; CHECK-NEXT: [[X:%.*]] = select i1 [[CMP]], float [[X1]], float [[NEG]]
1354+ ; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[Y:%.*]])
1355+ ; CHECK-NEXT: ret float [[COPYSIGN]]
1356+ ;
1357+ %cmp = fcmp oge float %x , 0 .000000e+00
1358+ %neg = fneg float %x
1359+ %sel = select i1 %cmp , float %x , float %neg
1360+ %copysign = call float @llvm.copysign.f32 (float %sel , float %y )
1361+ ret float %copysign
1362+ }
1363+
1364+
1365+ ; Negative tests
1366+
1367+ define float @test_fabs_used_by_fpop_nnan (float %x , float %y ) {
1368+ ; CHECK-LABEL: @test_fabs_used_by_fpop_nnan(
1369+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1370+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1371+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1372+ ; CHECK-NEXT: [[ADD:%.*]] = fadd nnan float [[SEL]], [[Y:%.*]]
1373+ ; CHECK-NEXT: ret float [[ADD]]
1374+ ;
1375+ %cmp = fcmp oge float %x , 0 .000000e+00
1376+ %neg = fneg float %x
1377+ %sel = select i1 %cmp , float %x , float %neg
1378+ %add = fadd nnan float %sel , %y
1379+ ret float %add
1380+ }
1381+
1382+ define i1 @test_fabs_used_by_fcmp_multiuse (float %x , float %y ) {
1383+ ; CHECK-LABEL: @test_fabs_used_by_fcmp_multiuse(
1384+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1385+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1386+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1387+ ; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[SEL]], [[Y:%.*]]
1388+ ; CHECK-NEXT: call void @use(float [[SEL]])
1389+ ; CHECK-NEXT: ret i1 [[CMP2]]
1390+ ;
1391+ %cmp = fcmp oge float %x , 0 .000000e+00
1392+ %neg = fneg float %x
1393+ %sel = select i1 %cmp , float %x , float %neg
1394+ %cmp2 = fcmp olt float %sel , %y
1395+ call void @use (float %sel )
1396+ ret i1 %cmp2
1397+ }
1398+
1399+ define float @test_fabs_used_by_fcopysign_sign (float %x , float %y ) {
1400+ ; CHECK-LABEL: @test_fabs_used_by_fcopysign_sign(
1401+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1402+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1403+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1404+ ; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[Y:%.*]], float [[SEL]])
1405+ ; CHECK-NEXT: ret float [[COPYSIGN]]
1406+ ;
1407+ %cmp = fcmp oge float %x , 0 .000000e+00
1408+ %neg = fneg float %x
1409+ %sel = select i1 %cmp , float %x , float %neg
1410+ %copysign = call float @llvm.copysign.f32 (float %y , float %sel )
1411+ ret float %copysign
1412+ }
1413+
1414+ define float @test_fabs_used_by_maxnum (float %x , float %y ) {
1415+ ; CHECK-LABEL: @test_fabs_used_by_maxnum(
1416+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1417+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1418+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1419+ ; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[Y:%.*]], float [[SEL]])
1420+ ; CHECK-NEXT: ret float [[MAX]]
1421+ ;
1422+ %cmp = fcmp oge float %x , 0 .000000e+00
1423+ %neg = fneg float %x
1424+ %sel = select i1 %cmp , float %x , float %neg
1425+ %max = call float @llvm.maxnum.f32 (float %y , float %sel )
1426+ ret float %max
1427+ }
1428+
1429+ define float @test_fabs_used_by_canonicalize (float %x ) {
1430+ ; CHECK-LABEL: @test_fabs_used_by_canonicalize(
1431+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1432+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1433+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1434+ ; CHECK-NEXT: [[CANON:%.*]] = call float @llvm.canonicalize.f32(float [[SEL]])
1435+ ; CHECK-NEXT: ret float [[CANON]]
1436+ ;
1437+ %cmp = fcmp oge float %x , 0 .000000e+00
1438+ %neg = fneg float %x
1439+ %sel = select i1 %cmp , float %x , float %neg
1440+ %canon = call float @llvm.canonicalize.f32 (float %sel )
1441+ ret float %canon
1442+ }
1443+
1444+ define float @test_fabs_used_by_select (float %x , i1 %cond ) {
1445+ ; CHECK-LABEL: @test_fabs_used_by_select(
1446+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
1447+ ; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X]]
1448+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[NEG]]
1449+ ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND:%.*]], float [[SEL]], float 0.000000e+00
1450+ ; CHECK-NEXT: ret float [[SEL2]]
1451+ ;
1452+ %cmp = fcmp oge float %x , 0 .000000e+00
1453+ %neg = fneg float %x
1454+ %sel = select i1 %cmp , float %x , float %neg
1455+ %sel2 = select i1 %cond , float %sel , float 0 .000000e+00
1456+ ret float %sel2
1457+ }
0 commit comments