@@ -1255,17 +1255,190 @@ define <2 x i32> @test_mul_canonicalize_vec(<2 x i32> %x, <2 x i32> %y) {
12551255
12561256define i32 @test_mul_canonicalize_multiple_uses (i32 %x , i32 %y ) {
12571257; CHECK-LABEL: @test_mul_canonicalize_multiple_uses(
1258+ ; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1259+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1260+ ; CHECK-NEXT: ret i32 [[MUL2]]
1261+ ;
1262+ %neg = sub i32 0 , %x
1263+ %mul = mul i32 %neg , %y
1264+ %mul2 = mul i32 %mul , %neg
1265+ ret i32 %mul2
1266+ }
1267+
1268+ define i32 @mul_nsw_mul_nsw_neg (i32 %x , i32 %y ) {
1269+ ; CHECK-LABEL: @mul_nsw_mul_nsw_neg(
1270+ ; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1271+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1272+ ; CHECK-NEXT: ret i32 [[MUL2]]
1273+ ;
1274+ %neg = sub i32 0 , %x
1275+ %mul = mul nsw i32 %neg , %y
1276+ %mul2 = mul nsw i32 %mul , %neg
1277+ ret i32 %mul2
1278+ }
1279+
1280+ define i32 @mul_mul_nsw_neg (i32 %x ,i32 %y ) {
1281+ ; CHECK-LABEL: @mul_mul_nsw_neg(
1282+ ; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1283+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1284+ ; CHECK-NEXT: ret i32 [[MUL2]]
1285+ ;
1286+ %neg = sub i32 0 , %x
1287+ %mul = mul nsw i32 %neg , %y
1288+ %mul2 = mul i32 %mul , %neg
1289+ ret i32 %mul2
1290+ }
1291+
1292+ define i32 @mul_nsw_mul_neg (i32 %x ,i32 %y ) {
1293+ ; CHECK-LABEL: @mul_nsw_mul_neg(
1294+ ; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1295+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1296+ ; CHECK-NEXT: ret i32 [[MUL2]]
1297+ ;
1298+ %neg = sub i32 0 , %x
1299+ %mul = mul i32 %neg , %y
1300+ %mul2 = mul nsw i32 %mul , %neg
1301+ ret i32 %mul2
1302+ }
1303+
1304+ define i32 @mul_nsw_mul_neg_onearg (i32 %x ) {
1305+ ; CHECK-LABEL: @mul_nsw_mul_neg_onearg(
1306+ ; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]
1307+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1308+ ; CHECK-NEXT: ret i32 [[MUL2]]
1309+ ;
1310+ %neg = sub i32 0 , %x
1311+ %mul = mul i32 %neg , %x
1312+ %mul2 = mul nsw i32 %mul , %neg
1313+ ret i32 %mul2
1314+ }
1315+
1316+ define i8 @mul_mul_nsw_neg_onearg (i8 %x ) {
1317+ ; CHECK-LABEL: @mul_mul_nsw_neg_onearg(
1318+ ; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i8 [[X:%.*]], [[X]]
1319+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i8 [[MUL_NEG]], [[X]]
1320+ ; CHECK-NEXT: ret i8 [[MUL2]]
1321+ ;
1322+ %neg = sub i8 0 , %x
1323+ %mul = mul nsw i8 %neg , %x
1324+ %mul2 = mul i8 %mul , %neg
1325+ ret i8 %mul2
1326+ }
1327+
1328+ define i32 @mul_nsw_mul_nsw_neg_onearg (i32 %x ) {
1329+ ; CHECK-LABEL: @mul_nsw_mul_nsw_neg_onearg(
1330+ ; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]
1331+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1332+ ; CHECK-NEXT: ret i32 [[MUL2]]
1333+ ;
1334+ %neg = sub i32 0 , %x
1335+ %mul = mul nsw i32 %neg , %x
1336+ %mul2 = mul nsw i32 %mul , %neg
1337+ ret i32 %mul2
1338+ }
1339+
1340+ define i32 @mul_nsw_shl_nsw_neg (i32 %x , i32 %y ) {
1341+ ; CHECK-LABEL: @mul_nsw_shl_nsw_neg(
1342+ ; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
1343+ ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1344+ ; CHECK-NEXT: ret i32 [[MUL]]
1345+ ;
1346+ %neg = sub i32 0 , %x
1347+ %shl = shl nsw i32 %neg , %y
1348+ %mul = mul nsw i32 %shl , %neg
1349+ ret i32 %mul
1350+ }
1351+
1352+ define i32 @mul_shl_nsw_neg (i32 %x ,i32 %y ) {
1353+ ; CHECK-LABEL: @mul_shl_nsw_neg(
1354+ ; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
1355+ ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1356+ ; CHECK-NEXT: ret i32 [[MUL]]
1357+ ;
1358+ %neg = sub i32 0 , %x
1359+ %shl = shl nsw i32 %neg , %y
1360+ %mul = mul i32 %shl , %neg
1361+ ret i32 %mul
1362+ }
1363+
1364+ define i32 @mul_nsw_shl_neg (i32 %x ,i32 %y ) {
1365+ ; CHECK-LABEL: @mul_nsw_shl_neg(
1366+ ; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
1367+ ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1368+ ; CHECK-NEXT: ret i32 [[MUL]]
1369+ ;
1370+ %neg = sub i32 0 , %x
1371+ %shl = shl i32 %neg , %y
1372+ %mul = mul nsw i32 %shl , %neg
1373+ ret i32 %mul
1374+ }
1375+
1376+ define i32 @mul_nsw_shl_neg_onearg (i32 %x ) {
1377+ ; CHECK-LABEL: @mul_nsw_shl_neg_onearg(
1378+ ; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[X]]
1379+ ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1380+ ; CHECK-NEXT: ret i32 [[MUL]]
1381+ ;
1382+ %neg = sub i32 0 , %x
1383+ %shl = shl i32 %neg , %x
1384+ %mul = mul nsw i32 %shl , %neg
1385+ ret i32 %mul
1386+ }
1387+
1388+ define i8 @mul_shl_nsw_neg_onearg (i8 %x ) {
1389+ ; CHECK-LABEL: @mul_shl_nsw_neg_onearg(
1390+ ; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i8 [[X:%.*]], [[X]]
1391+ ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[SHL_NEG]], [[X]]
1392+ ; CHECK-NEXT: ret i8 [[MUL]]
1393+ ;
1394+ %neg = sub i8 0 , %x
1395+ %shl = shl nsw i8 %neg , %x
1396+ %mul = mul i8 %shl , %neg
1397+ ret i8 %mul
1398+ }
1399+
1400+ define i32 @mul_nsw_shl_nsw_neg_onearg (i32 %x ) {
1401+ ; CHECK-LABEL: @mul_nsw_shl_nsw_neg_onearg(
1402+ ; CHECK-NEXT: [[SHL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]
1403+ ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1404+ ; CHECK-NEXT: ret i32 [[MUL]]
1405+ ;
1406+ %neg = sub i32 0 , %x
1407+ %shl = mul nsw i32 %neg , %x
1408+ %mul = mul nsw i32 %shl , %neg
1409+ ret i32 %mul
1410+ }
1411+
1412+ define i32 @mul_use_mul_neg (i32 %x ,i32 %y ) {
1413+ ; CHECK-LABEL: @mul_use_mul_neg(
12581414; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
12591415; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[NEG]], [[Y:%.*]]
1416+ ; CHECK-NEXT: call void @use32(i32 [[MUL]])
12601417; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL]], [[NEG]]
12611418; CHECK-NEXT: ret i32 [[MUL2]]
12621419;
12631420 %neg = sub i32 0 , %x
12641421 %mul = mul i32 %neg , %y
1422+ call void @use32 (i32 %mul )
12651423 %mul2 = mul i32 %mul , %neg
12661424 ret i32 %mul2
12671425}
12681426
1427+ define i32 @mul_shl_use_mul_neg (i32 %x ,i32 %y ) {
1428+ ; CHECK-LABEL: @mul_shl_use_mul_neg(
1429+ ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
1430+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[NEG]], [[Y:%.*]]
1431+ ; CHECK-NEXT: call void @use32(i32 [[SHL]])
1432+ ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[SHL]], [[NEG]]
1433+ ; CHECK-NEXT: ret i32 [[MUL2]]
1434+ ;
1435+ %neg = sub i32 0 , %x
1436+ %shl = shl i32 %neg , %y
1437+ call void @use32 (i32 %shl )
1438+ %mul2 = mul i32 %shl , %neg
1439+ ret i32 %mul2
1440+ }
1441+
12691442@X = global i32 5
12701443
12711444define i64 @test_mul_canonicalize_neg_is_not_undone (i64 %L1 ) {
0 commit comments