brintos

brintos / llvm-project-archived public Read only

0
0
Text · 64.9 KiB · 0f3137c Raw
2205 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3; RUN: opt < %s -passes=instcombine -use-constant-int-for-fixed-length-splat -S | FileCheck %s4 5declare i32 @llvm.abs.i32(i32, i1)6 7define i32 @pow2_multiplier(i32 %A) {8; CHECK-LABEL: @pow2_multiplier(9; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 110; CHECK-NEXT:    ret i32 [[B]]11;12  %B = mul i32 %A, 213  ret i32 %B14}15 16define <2 x i32> @pow2_multiplier_vec(<2 x i32> %A) {17; CHECK-LABEL: @pow2_multiplier_vec(18; CHECK-NEXT:    [[B:%.*]] = shl <2 x i32> [[A:%.*]], splat (i32 3)19; CHECK-NEXT:    ret <2 x i32> [[B]]20;21  %B = mul <2 x i32> %A, <i32 8, i32 8>22  ret <2 x i32> %B23}24 25define i8 @combine_shl(i8 %A) {26; CHECK-LABEL: @combine_shl(27; CHECK-NEXT:    [[C:%.*]] = shl i8 [[A:%.*]], 628; CHECK-NEXT:    ret i8 [[C]]29;30  %B = mul i8 %A, 831  %C = mul i8 %B, 832  ret i8 %C33}34 35define i32 @neg(i32 %i) {36; CHECK-LABEL: @neg(37; CHECK-NEXT:    [[T:%.*]] = sub i32 0, [[I:%.*]]38; CHECK-NEXT:    ret i32 [[T]]39;40  %t = mul i32 %i, -141  ret i32 %t42}43 44; Use the sign-bit as a mask:45; (zext (A < 0)) * B --> (A >> 31) & B46 47define i32 @test10(i32 %a, i32 %b) {48; CHECK-LABEL: @test10(49; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 050; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 051; CHECK-NEXT:    ret i32 [[E]]52;53  %c = icmp slt i32 %a, 054  %d = zext i1 %c to i3255  %e = mul i32 %d, %b56  ret i32 %e57}58 59define i32 @test11(i32 %a, i32 %b) {60; CHECK-LABEL: @test11(61; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 062; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 063; CHECK-NEXT:    ret i32 [[E]]64;65  %c = icmp sle i32 %a, -166  %d = zext i1 %c to i3267  %e = mul i32 %d, %b68  ret i32 %e69}70 71declare void @use32(i32)72 73define i32 @test12(i32 %a, i32 %b) {74; CHECK-LABEL: @test12(75; CHECK-NEXT:    [[A_LOBIT:%.*]] = lshr i32 [[A:%.*]], 3176; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A]], 077; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 078; CHECK-NEXT:    call void @use32(i32 [[A_LOBIT]])79; CHECK-NEXT:    ret i32 [[E]]80;81  %c = icmp ugt i32 %a, 214748364782  %d = zext i1 %c to i3283  %e = mul i32 %d, %b84  call void @use32(i32 %d)85  ret i32 %e86}87 88; rdar://729352789define i32 @shl1(i32 %a, i32 %b) {90; CHECK-LABEL: @shl1(91; CHECK-NEXT:    [[M1:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]92; CHECK-NEXT:    ret i32 [[M1]]93;94  %shl = shl i32 1, %b95  %m = mul i32 %shl, %a96  ret i32 %m97}98 99define i32 @shl1_nsw_nsw(i32 %A, i32 %B) {100; CHECK-LABEL: @shl1_nsw_nsw(101; CHECK-NEXT:    [[D1:%.*]] = shl nsw i32 [[A:%.*]], [[B:%.*]]102; CHECK-NEXT:    ret i32 [[D1]]103;104  %shl = shl nsw i32 1, %B105  %D = mul nsw i32 %A, %shl106  ret i32 %D107}108 109define <2 x i32> @shl1_nsw_nsw_commute(<2 x i32> %A, <2 x i32> %B) {110; CHECK-LABEL: @shl1_nsw_nsw_commute(111; CHECK-NEXT:    [[D1:%.*]] = shl nsw <2 x i32> [[A:%.*]], [[B:%.*]]112; CHECK-NEXT:    ret <2 x i32> [[D1]]113;114  %shl = shl nsw <2 x i32> <i32 1, i32 poison>, %B115  %D = mul nsw <2 x i32> %shl, %A116  ret <2 x i32> %D117}118 119define i32 @shl1_nuw(i32 %A, i32 %B) {120; CHECK-LABEL: @shl1_nuw(121; CHECK-NEXT:    [[D1:%.*]] = shl nuw i32 [[A:%.*]], [[B:%.*]]122; CHECK-NEXT:    ret i32 [[D1]]123;124  %shl = shl i32 1, %B125  %D = mul nuw i32 %A, %shl126  ret i32 %D127}128 129define i32 @shl1_nuw_commute(i32 %A, i32 %B) {130; CHECK-LABEL: @shl1_nuw_commute(131; CHECK-NEXT:    [[D1:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]132; CHECK-NEXT:    ret i32 [[D1]]133;134  %shl = shl nuw i32 1, %B135  %D = mul i32 %shl, %A136  ret i32 %D137}138 139define i32 @shl1_nsw(i32 %A) {140; CHECK-LABEL: @shl1_nsw(141; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 1, [[A:%.*]]142; CHECK-NEXT:    [[C1:%.*]] = shl i32 [[SHL]], [[A]]143; CHECK-NEXT:    ret i32 [[C1]]144;145  %shl = shl i32 1, %A146  %C = mul nsw i32 %shl, %shl147  ret i32 %C148}149 150define i5 @shl1_increment(i5 %x, i5 %y) {151; CHECK-LABEL: @shl1_increment(152; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]153; CHECK-NEXT:    [[MULSHL:%.*]] = shl i5 [[Y_FR]], [[X:%.*]]154; CHECK-NEXT:    [[M1:%.*]] = add i5 [[MULSHL]], [[Y_FR]]155; CHECK-NEXT:    ret i5 [[M1]]156;157  %pow2x = shl i5 1, %x158  %x1 = add i5 %pow2x, 1159  %m = mul i5 %x1, %y160  ret i5 %m161}162 163define <3 x i5> @shl1_nuw_increment_commute(<3 x i5> %x, <3 x i5> noundef %p) {164; CHECK-LABEL: @shl1_nuw_increment_commute(165; CHECK-NEXT:    [[Y:%.*]] = ashr <3 x i5> [[P:%.*]], splat (i5 1)166; CHECK-NEXT:    [[MULSHL:%.*]] = shl nuw <3 x i5> [[Y]], [[X:%.*]]167; CHECK-NEXT:    [[M1:%.*]] = add nuw <3 x i5> [[MULSHL]], [[Y]]168; CHECK-NEXT:    ret <3 x i5> [[M1]]169;170  %y = ashr <3 x i5> %p, <i5 1, i5 1, i5 1> ; thwart complexity-based canonicalization171  %pow2x = shl <3 x i5> <i5 1, i5 poison, i5 1>, %x172  %x1 = add <3 x i5> %pow2x, <i5 1, i5 poison, i5 1>173  %m = mul nuw <3 x i5> %y, %x1174  ret <3 x i5> %m175}176 177define i5 @shl1_nsw_increment(i5 %x, i5 %y) {178; CHECK-LABEL: @shl1_nsw_increment(179; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]180; CHECK-NEXT:    [[MULSHL:%.*]] = shl i5 [[Y_FR]], [[X:%.*]]181; CHECK-NEXT:    [[M1:%.*]] = add i5 [[MULSHL]], [[Y_FR]]182; CHECK-NEXT:    ret i5 [[M1]]183;184  %pow2x = shl i5 1, %x185  %x1 = add i5 %pow2x, 1186  %m = mul nsw i5 %x1, %y187  ret i5 %m188}189 190define i5 @shl1_nsw_nsw_increment(i5 %x, i5 %y) {191; CHECK-LABEL: @shl1_nsw_nsw_increment(192; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]193; CHECK-NEXT:    [[MULSHL:%.*]] = shl nsw i5 [[Y_FR]], [[X:%.*]]194; CHECK-NEXT:    [[M1:%.*]] = add nsw i5 [[MULSHL]], [[Y_FR]]195; CHECK-NEXT:    ret i5 [[M1]]196;197  %pow2x = shl nsw i5 1, %x198  %x1 = add i5 %pow2x, 1199  %m = mul nsw i5 %y, %x1200  ret i5 %m201}202 203define i5 @shl1_nsw_nsw_increment_commute(i5 %x, i5 %y) {204; CHECK-LABEL: @shl1_nsw_nsw_increment_commute(205; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]206; CHECK-NEXT:    [[MULSHL:%.*]] = shl i5 [[Y_FR]], [[X:%.*]]207; CHECK-NEXT:    [[M1:%.*]] = add i5 [[MULSHL]], [[Y_FR]]208; CHECK-NEXT:    ret i5 [[M1]]209;210  %pow2x = shl nsw i5 1, %x211  %x1 = add nsw i5 %pow2x, 1212  %m = mul i5 %x1, %y213  ret i5 %m214}215 216define i32 @shl1_increment_use(i32 %x, i32 %y) {217; CHECK-LABEL: @shl1_increment_use(218; CHECK-NEXT:    [[POW2X:%.*]] = shl nuw i32 1, [[X:%.*]]219; CHECK-NEXT:    call void @use32(i32 [[POW2X]])220; CHECK-NEXT:    [[X1:%.*]] = add nuw i32 [[POW2X]], 1221; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X1]], [[Y:%.*]]222; CHECK-NEXT:    ret i32 [[M]]223;224  %pow2x = shl i32 1, %x225  call void @use32(i32 %pow2x)226  %x1 = add i32 %pow2x, 1227  %m = mul i32 %x1, %y228  ret i32 %m229}230 231; ((-1 << x) ^ -1) * y --> (y << x) - y232 233define i8 @shl1_decrement(i8 %x, i8 %y) {234; CHECK-LABEL: @shl1_decrement(235; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]236; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y_FR]], [[X:%.*]]237; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y_FR]]238; CHECK-NEXT:    ret i8 [[M1]]239;240  %pow2x = shl i8 -1, %x241  %x1 = xor i8 %pow2x, -1242  %m = mul i8 %x1, %y243  ret i8 %m244}245 246define i8 @shl1_decrement_commute(i8 %x, i8 noundef %p) {247; CHECK-LABEL: @shl1_decrement_commute(248; CHECK-NEXT:    [[Y:%.*]] = ashr i8 [[P:%.*]], 1249; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y]], [[X:%.*]]250; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y]]251; CHECK-NEXT:    ret i8 [[M1]]252;253  %y = ashr i8 %p, 1 ; thwart complexity-based canonicalization254  %pow2x = shl i8 1, %x255  %x1 = add i8 %pow2x, -1256  %m = mul i8 %y, %x1257  ret i8 %m258}259 260define i8 @shl1_nuw_decrement(i8 %x, i8 %y) {261; CHECK-LABEL: @shl1_nuw_decrement(262; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]263; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y_FR]], [[X:%.*]]264; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y_FR]]265; CHECK-NEXT:    ret i8 [[M1]]266;267  %pow2x = shl i8 -1, %x268  %x1 = xor i8 %pow2x, -1269  %m = mul nuw i8 %x1, %y270  ret i8 %m271}272 273define i8 @shl1_nsw_decrement(i8 %x, i8 %y) {274; CHECK-LABEL: @shl1_nsw_decrement(275; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]276; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y_FR]], [[X:%.*]]277; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y_FR]]278; CHECK-NEXT:    ret i8 [[M1]]279;280  %pow2x = shl nsw i8 -1, %x281  %x1 = xor i8 %pow2x, -1282  %m = mul nsw i8 %x1, %y283  ret i8 %m284}285 286; negative test - extra use would require more instructions287 288define i32 @shl1_decrement_use(i32 %x, i32 %y) {289; CHECK-LABEL: @shl1_decrement_use(290; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[X:%.*]]291; CHECK-NEXT:    [[X1:%.*]] = xor i32 [[NOTMASK]], -1292; CHECK-NEXT:    call void @use32(i32 [[X1]])293; CHECK-NEXT:    [[M:%.*]] = mul i32 [[Y:%.*]], [[X1]]294; CHECK-NEXT:    ret i32 [[M]]295;296  %pow2x = shl i32 1, %x297  %x1 = add i32 %pow2x, -1298  call void @use32(i32 %x1)299  %m = mul i32 %x1, %y300  ret i32 %m301}302 303; the fold works for vectors too and if 'y' is a constant, sub becomes add304 305define <2 x i8> @shl1_decrement_vec(<2 x i8> %x) {306; CHECK-LABEL: @shl1_decrement_vec(307; CHECK-NEXT:    [[MULSHL:%.*]] = shl <2 x i8> <i8 42, i8 -3>, [[X:%.*]]308; CHECK-NEXT:    [[M1:%.*]] = add <2 x i8> [[MULSHL]], <i8 -42, i8 3>309; CHECK-NEXT:    ret <2 x i8> [[M1]]310;311  %pow2x = shl <2 x i8> <i8 -1, i8 -1>, %x312  %x1 = xor <2 x i8> %pow2x, <i8 -1, i8 -1>313  %m = mul <2 x i8> %x1, <i8 42, i8 -3>314  ret <2 x i8> %m315}316 317; X * Y (when Y is a boolean) --> Y ? X : 0318 319define i32 @mul_bool(i32 %x, i1 %y) {320; CHECK-LABEL: @mul_bool(321; CHECK-NEXT:    [[M:%.*]] = select i1 [[Y:%.*]], i32 [[X:%.*]], i32 0322; CHECK-NEXT:    ret i32 [[M]]323;324  %z = zext i1 %y to i32325  %m = mul i32 %z, %x326  ret i32 %m327}328 329define <2 x i32> @mul_bool_vec(<2 x i32> %x, <2 x i1> %y) {330; CHECK-LABEL: @mul_bool_vec(331; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> [[X:%.*]], <2 x i32> zeroinitializer332; CHECK-NEXT:    ret <2 x i32> [[M]]333;334  %z = zext <2 x i1> %y to <2 x i32>335  %m = mul <2 x i32> %z, %x336  ret <2 x i32> %m337}338 339define <2 x i32> @mul_bool_vec_commute(<2 x i32> %px, <2 x i1> %y) {340; CHECK-LABEL: @mul_bool_vec_commute(341; CHECK-NEXT:    [[X:%.*]] = mul <2 x i32> [[PX:%.*]], [[PX]]342; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> [[X]], <2 x i32> zeroinitializer343; CHECK-NEXT:    ret <2 x i32> [[M]]344;345  %x = mul <2 x i32> %px, %px  ; thwart complexity-based canonicalization346  %z = zext <2 x i1> %y to <2 x i32>347  %m = mul <2 x i32> %x, %z348  ret <2 x i32> %m349}350 351; X * C (when X is a sext boolean) --> X ? -C : 0352 353define i32 @mul_sext_bool(i1 %x) {354; CHECK-LABEL: @mul_sext_bool(355; CHECK-NEXT:    [[M:%.*]] = select i1 [[X:%.*]], i32 -42, i32 0356; CHECK-NEXT:    ret i32 [[M]]357;358  %s = sext i1 %x to i32359  %m = mul i32 %s, 42360  ret i32 %m361}362 363define i32 @mul_sext_bool_use(i1 %x) {364; CHECK-LABEL: @mul_sext_bool_use(365; CHECK-NEXT:    [[S:%.*]] = sext i1 [[X:%.*]] to i32366; CHECK-NEXT:    call void @use32(i32 [[S]])367; CHECK-NEXT:    [[M:%.*]] = select i1 [[X]], i32 -42, i32 0368; CHECK-NEXT:    ret i32 [[M]]369;370  %s = sext i1 %x to i32371  call void @use32(i32 %s)372  %m = mul i32 %s, 42373  ret i32 %m374}375 376define <2 x i8> @mul_sext_bool_vec(<2 x i1> %x) {377; CHECK-LABEL: @mul_sext_bool_vec(378; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[X:%.*]], <2 x i8> <i8 -42, i8 -128>, <2 x i8> zeroinitializer379; CHECK-NEXT:    ret <2 x i8> [[M]]380;381  %s = sext <2 x i1> %x to <2 x i8>382  %m = mul <2 x i8> %s, <i8 42, i8 -128>383  ret <2 x i8> %m384}385 386define <3 x i7> @mul_bools(<3 x i1> %x, <3 x i1> %y) {387; CHECK-LABEL: @mul_bools(388; CHECK-NEXT:    [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]389; CHECK-NEXT:    [[R:%.*]] = zext <3 x i1> [[MULBOOL]] to <3 x i7>390; CHECK-NEXT:    ret <3 x i7> [[R]]391;392  %zx = zext <3 x i1> %x to <3 x i7>393  %zy = zext <3 x i1> %y to <3 x i7>394  %r = mul <3 x i7> %zx, %zy395  ret <3 x i7> %r396}397 398define i32 @mul_bools_use1(i1 %x, i1 %y) {399; CHECK-LABEL: @mul_bools_use1(400; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32401; CHECK-NEXT:    call void @use32(i32 [[ZY]])402; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]403; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32404; CHECK-NEXT:    ret i32 [[R]]405;406  %zx = zext i1 %x to i32407  %zy = zext i1 %y to i32408  call void @use32(i32 %zy)409  %r = mul i32 %zx, %zy410  ret i32 %r411}412 413define i32 @mul_bools_use2(i1 %x, i1 %y) {414; CHECK-LABEL: @mul_bools_use2(415; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32416; CHECK-NEXT:    call void @use32(i32 [[ZY]])417; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]418; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32419; CHECK-NEXT:    ret i32 [[R]]420;421  %zx = zext i1 %x to i32422  %zy = zext i1 %y to i32423  call void @use32(i32 %zy)424  %r = mul i32 %zy, %zx425  ret i32 %r426}427 428define i32 @mul_bools_use3(i1 %x, i1 %y) {429; CHECK-LABEL: @mul_bools_use3(430; CHECK-NEXT:    [[ZX:%.*]] = zext i1 [[X:%.*]] to i32431; CHECK-NEXT:    call void @use32(i32 [[ZX]])432; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32433; CHECK-NEXT:    call void @use32(i32 [[ZY]])434; CHECK-NEXT:    [[R:%.*]] = select i1 [[X]], i32 [[ZY]], i32 0435; CHECK-NEXT:    ret i32 [[R]]436;437  %zx = zext i1 %x to i32438  call void @use32(i32 %zx)439  %zy = zext i1 %y to i32440  call void @use32(i32 %zy)441  %r = mul i32 %zx, %zy442  ret i32 %r443}444 445define <3 x i32> @mul_bools_sext(<3 x i1> %x, <3 x i1> %y) {446; CHECK-LABEL: @mul_bools_sext(447; CHECK-NEXT:    [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]448; CHECK-NEXT:    [[R:%.*]] = zext <3 x i1> [[MULBOOL]] to <3 x i32>449; CHECK-NEXT:    ret <3 x i32> [[R]]450;451  %sx = sext <3 x i1> %x to <3 x i32>452  %sy = sext <3 x i1> %y to <3 x i32>453  %r = mul <3 x i32> %sx, %sy454  ret <3 x i32> %r455}456 457define i32 @mul_bools_sext_use1(i1 %x, i1 %y) {458; CHECK-LABEL: @mul_bools_sext_use1(459; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32460; CHECK-NEXT:    call void @use32(i32 [[SY]])461; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]462; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32463; CHECK-NEXT:    ret i32 [[R]]464;465  %sx = sext i1 %x to i32466  %sy = sext i1 %y to i32467  call void @use32(i32 %sy)468  %r = mul i32 %sx, %sy469  ret i32 %r470}471 472define i32 @mul_bools_sext_use2(i1 %x, i1 %y) {473; CHECK-LABEL: @mul_bools_sext_use2(474; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32475; CHECK-NEXT:    call void @use32(i32 [[SY]])476; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]477; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32478; CHECK-NEXT:    ret i32 [[R]]479;480  %sx = sext i1 %x to i32481  %sy = sext i1 %y to i32482  call void @use32(i32 %sy)483  %r = mul i32 %sy, %sx484  ret i32 %r485}486 487define i32 @mul_bools_sext_use3(i1 %x, i1 %y) {488; CHECK-LABEL: @mul_bools_sext_use3(489; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32490; CHECK-NEXT:    call void @use32(i32 [[SX]])491; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32492; CHECK-NEXT:    call void @use32(i32 [[SY]])493; CHECK-NEXT:    [[R:%.*]] = mul nsw i32 [[SY]], [[SX]]494; CHECK-NEXT:    ret i32 [[R]]495;496  %sx = sext i1 %x to i32497  call void @use32(i32 %sx)498  %sy = sext i1 %y to i32499  call void @use32(i32 %sy)500  %r = mul i32 %sy, %sx501  ret i32 %r502}503 504define i32 @mul_bools_sext_one_use_per_op(i1 %x, i1 %y) {505; CHECK-LABEL: @mul_bools_sext_one_use_per_op(506; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]507; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32508; CHECK-NEXT:    ret i32 [[R]]509;510  %sx = sext i1 %x to i32511  %sy = sext i1 %y to i32512  %r = mul i32 %sx, %sy513  ret i32 %r514}515 516define i32 @mul_bool_sext_one_user(i1 %x) {517; CHECK-LABEL: @mul_bool_sext_one_user(518; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X:%.*]] to i32519; CHECK-NEXT:    ret i32 [[R]]520;521  %sx = sext i1 %x to i32522  %r = mul i32 %sx, %sx523  ret i32 %r524}525 526define i32 @mul_bools_zext_one_use_per_op(i1 %x, i1 %y) {527; CHECK-LABEL: @mul_bools_zext_one_use_per_op(528; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]529; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32530; CHECK-NEXT:    ret i32 [[R]]531;532  %zx = zext i1 %x to i32533  %zy = zext i1 %y to i32534  %r = mul i32 %zx, %zy535  ret i32 %r536}537 538define i32 @mul_bool_zext_one_user(i1 %x) {539; CHECK-LABEL: @mul_bool_zext_one_user(540; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X:%.*]] to i32541; CHECK-NEXT:    ret i32 [[R]]542;543  %sx = zext i1 %x to i32544  %r = mul i32 %sx, %sx545  ret i32 %r546}547 548define i32 @mul_bool_sext_one_extra_user(i1 %x) {549; CHECK-LABEL: @mul_bool_sext_one_extra_user(550; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32551; CHECK-NEXT:    call void @use32(i32 [[SX]])552; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X]] to i32553; CHECK-NEXT:    ret i32 [[R]]554;555  %sx = sext i1 %x to i32556  call void @use32(i32 %sx)557  %r = mul i32 %sx, %sx558  ret i32 %r559}560 561define i32 @mul_bool_zext_one_extra_user(i1 %x) {562; CHECK-LABEL: @mul_bool_zext_one_extra_user(563; CHECK-NEXT:    [[SX:%.*]] = zext i1 [[X:%.*]] to i32564; CHECK-NEXT:    call void @use32(i32 [[SX]])565; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X]] to i32566; CHECK-NEXT:    ret i32 [[R]]567;568  %sx = zext i1 %x to i32569  call void @use32(i32 %sx)570  %r = mul i32 %sx, %sx571  ret i32 %r572}573 574define <3 x i32> @mul_bools_mixed_ext(<3 x i1> %x, <3 x i1> %y) {575; CHECK-LABEL: @mul_bools_mixed_ext(576; CHECK-NEXT:    [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]577; CHECK-NEXT:    [[R:%.*]] = sext <3 x i1> [[MULBOOL]] to <3 x i32>578; CHECK-NEXT:    ret <3 x i32> [[R]]579;580  %zx = zext <3 x i1> %x to <3 x i32>581  %sy = sext <3 x i1> %y to <3 x i32>582  %r = mul <3 x i32> %zx, %sy583  ret <3 x i32> %r584}585 586define i32 @mul_bools_mixed_ext_use1(i1 %x, i1 %y) {587; CHECK-LABEL: @mul_bools_mixed_ext_use1(588; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32589; CHECK-NEXT:    call void @use32(i32 [[ZY]])590; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]591; CHECK-NEXT:    [[R:%.*]] = sext i1 [[MULBOOL]] to i32592; CHECK-NEXT:    ret i32 [[R]]593;594  %sx = sext i1 %x to i32595  %zy = zext i1 %y to i32596  call void @use32(i32 %zy)597  %r = mul i32 %sx, %zy598  ret i32 %r599}600 601define i32 @mul_bools_mixed_ext_use2(i1 %x, i1 %y) {602; CHECK-LABEL: @mul_bools_mixed_ext_use2(603; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32604; CHECK-NEXT:    call void @use32(i32 [[SY]])605; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]606; CHECK-NEXT:    [[R:%.*]] = sext i1 [[MULBOOL]] to i32607; CHECK-NEXT:    ret i32 [[R]]608;609  %zx = zext i1 %x to i32610  %sy = sext i1 %y to i32611  call void @use32(i32 %sy)612  %r = mul i32 %sy, %zx613  ret i32 %r614}615 616define i32 @mul_bools_mixed_ext_use3(i1 %x, i1 %y) {617; CHECK-LABEL: @mul_bools_mixed_ext_use3(618; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32619; CHECK-NEXT:    call void @use32(i32 [[SX]])620; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32621; CHECK-NEXT:    call void @use32(i32 [[ZY]])622; CHECK-NEXT:    [[R:%.*]] = select i1 [[Y]], i32 [[SX]], i32 0623; CHECK-NEXT:    ret i32 [[R]]624;625  %sx = sext i1 %x to i32626  call void @use32(i32 %sx)627  %zy = zext i1 %y to i32628  call void @use32(i32 %zy)629  %r = mul i32 %zy, %sx630  ret i32 %r631}632 633; (A >>u 31) * B --> (A >>s 31) & B --> A < 0 ? B : 0634 635define i32 @signbit_mul(i32 %a, i32 %b) {636; CHECK-LABEL: @signbit_mul(637; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0638; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0639; CHECK-NEXT:    ret i32 [[E]]640;641  %d = lshr i32 %a, 31642  %e = mul i32 %d, %b643  ret i32 %e644}645 646define i32 @signbit_mul_commute_extra_use(i32 %a, i32 %b) {647; CHECK-LABEL: @signbit_mul_commute_extra_use(648; CHECK-NEXT:    [[D:%.*]] = lshr i32 [[A:%.*]], 31649; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A]], 0650; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0651; CHECK-NEXT:    call void @use32(i32 [[D]])652; CHECK-NEXT:    ret i32 [[E]]653;654  %d = lshr i32 %a, 31655  %e = mul i32 %b, %d656  call void @use32(i32 %d)657  ret i32 %e658}659 660; (A >>u 31)) * B --> (A >>s 31) & B --> A < 0 ? B : 0661 662define <2 x i32> @signbit_mul_vec(<2 x i32> %a, <2 x i32> %b) {663; CHECK-LABEL: @signbit_mul_vec(664; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer665; CHECK-NEXT:    [[E:%.*]] = select <2 x i1> [[ISNEG]], <2 x i32> [[B:%.*]], <2 x i32> zeroinitializer666; CHECK-NEXT:    ret <2 x i32> [[E]]667;668  %d = lshr <2 x i32> %a, <i32 31, i32 31>669  %e = mul <2 x i32> %d, %b670  ret <2 x i32> %e671}672 673define <2 x i32> @signbit_mul_vec_commute(<2 x i32> %a, <2 x i32> %b) {674; CHECK-LABEL: @signbit_mul_vec_commute(675; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer676; CHECK-NEXT:    [[E:%.*]] = select <2 x i1> [[ISNEG]], <2 x i32> [[B:%.*]], <2 x i32> zeroinitializer677; CHECK-NEXT:    ret <2 x i32> [[E]]678;679  %d = lshr <2 x i32> %a, <i32 31, i32 31>680  %e = mul <2 x i32> %b, %d681  ret <2 x i32> %e682}683 684; (A & 1) * B --> (lowbit A) ? B : 0685 686define i32 @lowbit_mul(i32 %a, i32 %b) {687; CHECK-LABEL: @lowbit_mul(688; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[A:%.*]] to i1689; CHECK-NEXT:    [[E:%.*]] = select i1 [[TMP1]], i32 [[B:%.*]], i32 0690; CHECK-NEXT:    ret i32 [[E]]691;692  %d = and i32 %a, 1693  %e = mul i32 %d, %b694  ret i32 %e695}696 697; (A & 1) * B --> (lowbit A) ? B : 0698 699define <2 x i17> @lowbit_mul_commute(<2 x i17> %a, <2 x i17> %p) {700; CHECK-LABEL: @lowbit_mul_commute(701; CHECK-NEXT:    [[B:%.*]] = xor <2 x i17> [[P:%.*]], <i17 42, i17 43>702; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i17> [[A:%.*]] to <2 x i1>703; CHECK-NEXT:    [[E:%.*]] = select <2 x i1> [[TMP1]], <2 x i17> [[B]], <2 x i17> zeroinitializer704; CHECK-NEXT:    ret <2 x i17> [[E]]705;706  %b = xor <2 x i17> %p, <i17 42, i17 43> ; thwart complexity-based canonicalization707  %d = and <2 x i17> %a, <i17 1, i17 1>708  %e = mul <2 x i17> %b, %d709  ret <2 x i17> %e710}711 712; negative test - extra use713 714define i32 @lowbit_mul_use(i32 %a, i32 %b) {715; CHECK-LABEL: @lowbit_mul_use(716; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 1717; CHECK-NEXT:    call void @use32(i32 [[D]])718; CHECK-NEXT:    [[E:%.*]] = mul nuw i32 [[D]], [[B:%.*]]719; CHECK-NEXT:    ret i32 [[E]]720;721  %d = and i32 %a, 1722  call void @use32(i32 %d)723  %e = mul i32 %d, %b724  ret i32 %e725}726 727; negative test - wrong mask728 729define i32 @not_lowbit_mul(i32 %a, i32 %b) {730; CHECK-LABEL: @not_lowbit_mul(731; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 2732; CHECK-NEXT:    [[E:%.*]] = mul i32 [[D]], [[B:%.*]]733; CHECK-NEXT:    ret i32 [[E]]734;735  %d = and i32 %a, 2736  %e = mul i32 %d, %b737  ret i32 %e738}739 740define i32 @signsplat_mul(i32 %x) {741; CHECK-LABEL: @signsplat_mul(742; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[X:%.*]], 0743; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[ISNEG]], i32 -42, i32 0744; CHECK-NEXT:    ret i32 [[MUL]]745;746  %ash = ashr i32 %x, 31747  %mul = mul i32 %ash, 42748  ret i32 %mul749}750 751define <2 x i32> @signsplat_mul_vec(<2 x i32> %x) {752; CHECK-LABEL: @signsplat_mul_vec(753; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer754; CHECK-NEXT:    [[MUL:%.*]] = select <2 x i1> [[ISNEG]], <2 x i32> <i32 -42, i32 3>, <2 x i32> zeroinitializer755; CHECK-NEXT:    ret <2 x i32> [[MUL]]756;757  %ash = ashr <2 x i32> %x, <i32 31, i32 31>758  %mul = mul <2 x i32> %ash, <i32 42, i32 -3>759  ret <2 x i32> %mul760}761 762; negative test - wrong shift amount763 764define i32 @not_signsplat_mul(i32 %x) {765; CHECK-LABEL: @not_signsplat_mul(766; CHECK-NEXT:    [[ASH:%.*]] = ashr i32 [[X:%.*]], 30767; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ASH]], 42768; CHECK-NEXT:    ret i32 [[MUL]]769;770  %ash = ashr i32 %x, 30771  %mul = mul i32 %ash, 42772  ret i32 %mul773}774 775; negative test - extra use776 777define i32 @signsplat_mul_use(i32 %x) {778; CHECK-LABEL: @signsplat_mul_use(779; CHECK-NEXT:    [[ASH:%.*]] = ashr i32 [[X:%.*]], 31780; CHECK-NEXT:    call void @use32(i32 [[ASH]])781; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ASH]], -42782; CHECK-NEXT:    ret i32 [[MUL]]783;784  %ash = ashr i32 %x, 31785  call void @use32(i32 %ash)786  %mul = mul i32 %ash, -42787  ret i32 %mul788}789 790define i32 @test18(i32 %A, i32 %B) {791; CHECK-LABEL: @test18(792; CHECK-NEXT:    ret i32 0793;794  %C = and i32 %A, 1795  %D = and i32 %B, 1796  %E = mul i32 %C, %D797  %F = and i32 %E, 16798  ret i32 %F799}800 801declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)802declare void @use(i1)803 804define i32 @test19(i32 %A, i32 %B) {805; CHECK-LABEL: @test19(806; CHECK-NEXT:    call void @use(i1 false)807; CHECK-NEXT:    ret i32 0808;809  %C = and i32 %A, 1810  %D = and i32 %B, 1811 812; It would be nice if we also started proving that this doesn't overflow.813  %E = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %C, i32 %D)814  %F = extractvalue {i32, i1} %E, 0815  %G = extractvalue {i32, i1} %E, 1816  call void @use(i1 %G)817  %H = and i32 %F, 16818  ret i32 %H819}820 821define <2 x i64> @test20(<2 x i64> %A) {822; CHECK-LABEL: @test20(823; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i64> [[A:%.*]], <i64 3, i64 2>824; CHECK-NEXT:    [[C:%.*]] = add <2 x i64> [[TMP1]], <i64 36, i64 28>825; CHECK-NEXT:    ret <2 x i64> [[C]]826;827  %B = add <2 x i64> %A, <i64 12, i64 14>828  %C = mul <2 x i64> %B, <i64 3, i64 2>829  ret <2 x i64> %C830}831 832@g = internal global i32 0, align 4833 834define i32 @PR20079(i32 %a) {835; CHECK-LABEL: @PR20079(836; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A:%.*]], -1837; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ADD]], ptrtoint (ptr @g to i32)838; CHECK-NEXT:    ret i32 [[MUL]]839;840  %add = add i32 %a, -1841  %mul = mul nsw i32 %add, ptrtoint (ptr @g to i32)842  ret i32 %mul843}844 845; Keep nuw flag in this change, https://alive2.llvm.org/ce/z/-Wowpk846define i32 @add_mul_nuw(i32 %a) {847; CHECK-LABEL: @add_mul_nuw(848; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i32 [[A:%.*]], 3849; CHECK-NEXT:    [[MUL:%.*]] = add nuw i32 [[TMP1]], 9850; CHECK-NEXT:    ret i32 [[MUL]]851;852  %add = add nuw i32 %a, 3853  %mul = mul nuw i32 %add, 3854  ret i32 %mul855}856 857; Don't propagate nsw flag in this change858define i32 @add_mul_nsw(i32 %a) {859; CHECK-LABEL: @add_mul_nsw(860; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3861; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9862; CHECK-NEXT:    ret i32 [[MUL]]863;864  %add = add nsw i32 %a, 3865  %mul = mul nsw i32 %add, 3866  ret i32 %mul867}868 869; Only the add or only the mul has nuw, https://alive2.llvm.org/ce/z/vPwbEa870define i32 @only_add_nuw(i32 %a) {871; CHECK-LABEL: @only_add_nuw(872; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3873; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9874; CHECK-NEXT:    ret i32 [[MUL]]875;876  %add = add nuw i32 %a, 3877  %mul = mul i32 %add, 3878  ret i32 %mul879}880 881define i32 @only_mul_nuw(i32 %a) {882; CHECK-LABEL: @only_mul_nuw(883; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3884; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9885; CHECK-NEXT:    ret i32 [[MUL]]886;887  %add = add i32 %a, 3888  %mul = mul nuw i32 %add, 3889  ret i32 %mul890}891 892; Don't propagate nsw flag in this change, https://alive2.llvm.org/ce/z/jJ8rZd893define i32 @PR57278_shl(i32 %a) {894; CHECK-LABEL: @PR57278_shl(895; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 12896; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9897; CHECK-NEXT:    ret i32 [[MUL]]898;899  %shl = shl nsw i32 %a, 2900  %add = or i32 %shl, 3901  %mul = mul nsw i32 %add, 3902  ret i32 %mul903}904 905; Negative test: Have common bits set906define i32 @PR57278_shl_1(i32 %a) {907; CHECK-LABEL: @PR57278_shl_1(908; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i32 [[A:%.*]], 2909; CHECK-NEXT:    [[ADD:%.*]] = or i32 [[SHL]], 4910; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ADD]], 3911; CHECK-NEXT:    ret i32 [[MUL]]912;913  %shl = shl nsw i32 %a, 2914  %add = or i32 %shl, 4915  %mul = mul nsw i32 %add, 3916  ret i32 %mul917}918 919; Keep nuw flag in this change, https://alive2.llvm.org/ce/z/awsQrx920define i32 @PR57278_mul(i32 %a) {921; CHECK-LABEL: @PR57278_mul(922; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i32 [[A:%.*]], 36923; CHECK-NEXT:    [[MUL:%.*]] = add nuw i32 [[TMP1]], 9924; CHECK-NEXT:    ret i32 [[MUL]]925;926  %mul0 = mul nuw i32 %a, 12927  %add = or i32 %mul0, 3928  %mul = mul nuw i32 %add, 3929  ret i32 %mul930}931 932; Negative test: Have common bits set, https://alive2.llvm.org/ce/z/bHZRh5933define i32 @PR57278_mul_1(i32 %a) {934; CHECK-LABEL: @PR57278_mul_1(935; CHECK-NEXT:    [[MUL0:%.*]] = mul nuw i32 [[A:%.*]], 12936; CHECK-NEXT:    [[ADD:%.*]] = or i32 [[MUL0]], 4937; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[ADD]], 3938; CHECK-NEXT:    ret i32 [[MUL]]939;940  %mul0 = mul nuw i32 %a, 12941  %add = or i32 %mul0, 4942  %mul = mul nuw i32 %add, 3943  ret i32 %mul944}945 946; Test the haveNoCommonBitsSet with assume, https://alive2.llvm.org/ce/z/AXKBjK947define i32 @PR57278_mul_assume(i32 %a) {948; CHECK-LABEL: @PR57278_mul_assume(949; CHECK-NEXT:    [[COMBITS:%.*]] = and i32 [[A:%.*]], 3950; CHECK-NEXT:    [[NOCOMBITS:%.*]] = icmp eq i32 [[COMBITS]], 0951; CHECK-NEXT:    call void @llvm.assume(i1 [[NOCOMBITS]])952; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A]], 5953; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 15954; CHECK-NEXT:    ret i32 [[MUL]]955;956  %combits = and i32 %a , 3957  %nocombits = icmp eq i32 %combits, 0958  call void @llvm.assume(i1 %nocombits)959 960  %add = or i32 %a, 3961  %mul = mul i32 %add, 5962  ret i32 %mul963}964 965declare void @llvm.assume(i1)966 967define i32 @PR57278_or_disjoint_nuw(i32 %a) {968; CHECK-LABEL: @PR57278_or_disjoint_nuw(969; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i32 [[A:%.*]], 3970; CHECK-NEXT:    [[MUL:%.*]] = add nuw i32 [[TMP1]], 9971; CHECK-NEXT:    ret i32 [[MUL]]972;973  %add = or disjoint i32 %a, 3974  %mul = mul nuw i32 %add, 3975  ret i32 %mul976}977 978define i32 @PR57278_or_disjoint_nsw(i32 %a) {979; CHECK-LABEL: @PR57278_or_disjoint_nsw(980; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3981; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9982; CHECK-NEXT:    ret i32 [[MUL]]983;984  %add = or disjoint i32 %a, 3985  %mul = mul nsw i32 %add, 3986  ret i32 %mul987}988 989; https://alive2.llvm.org/ce/z/XYpv9q990define <2 x i32> @PR57278_shl_vec(<2 x i32> %v1) {991; CHECK-LABEL: @PR57278_shl_vec(992; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw <2 x i32> [[V1:%.*]], <i32 12, i32 24>993; CHECK-NEXT:    [[MUL:%.*]] = add nuw <2 x i32> [[TMP1]], splat (i32 9)994; CHECK-NEXT:    ret <2 x i32> [[MUL]]995;996  %shl = shl nuw <2 x i32> %v1, <i32 2, i32 3>997  %add = or <2 x i32> %shl, <i32 3, i32 3>998  %mul = mul nuw <2 x i32> %add, <i32 3, i32 3>999  ret <2 x i32> %mul1000}1001 1002; TODO: vector with poison should also be supported, https://alive2.llvm.org/ce/z/XYpv9q1003define <2 x i32> @PR57278_shl_vec_poison(<2 x i32> %v1) {1004; CHECK-LABEL: @PR57278_shl_vec_poison(1005; CHECK-NEXT:    [[SHL:%.*]] = shl nuw <2 x i32> [[V1:%.*]], <i32 2, i32 poison>1006; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw <2 x i32> [[SHL]], <i32 3, i32 poison>1007; CHECK-NEXT:    [[MUL:%.*]] = add nuw <2 x i32> [[TMP1]], <i32 9, i32 poison>1008; CHECK-NEXT:    ret <2 x i32> [[MUL]]1009;1010  %shl = shl nuw <2 x i32> %v1, <i32 2, i32 poison>1011  %add = or <2 x i32> %shl, <i32 3, i32 poison>1012  %mul = mul nuw <2 x i32> %add, <i32 3, i32 poison>1013  ret <2 x i32> %mul1014}1015 1016define <2 x i1> @test21(<2 x i1> %A, <2 x i1> %B) {1017; CHECK-LABEL: @test21(1018; CHECK-NEXT:    [[C:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]1019; CHECK-NEXT:    ret <2 x i1> [[C]]1020;1021  %C = mul <2 x i1> %A, %B1022  ret <2 x i1> %C1023}1024 1025define i32 @test22(i32 %A) {1026; CHECK-LABEL: @test22(1027; CHECK-NEXT:    [[B:%.*]] = sub nsw i32 0, [[A:%.*]]1028; CHECK-NEXT:    ret i32 [[B]]1029;1030  %B = mul nsw i32 %A, -11031  ret i32 %B1032}1033 1034define i32 @test23(i32 %A) {1035; CHECK-LABEL: @test23(1036; CHECK-NEXT:    [[C:%.*]] = mul nuw i32 [[A:%.*]], 61037; CHECK-NEXT:    ret i32 [[C]]1038;1039  %B = shl nuw i32 %A, 11040  %C = mul nuw i32 %B, 31041  ret i32 %C1042}1043 1044define i32 @test24(i32 %A) {1045; CHECK-LABEL: @test24(1046; CHECK-NEXT:    [[C:%.*]] = mul nsw i32 [[A:%.*]], 61047; CHECK-NEXT:    ret i32 [[C]]1048;1049  %B = shl nsw i32 %A, 11050  %C = mul nsw i32 %B, 31051  ret i32 %C1052}1053 1054define i32 @neg_neg_mul(i32 %A, i32 %B) {1055; CHECK-LABEL: @neg_neg_mul(1056; CHECK-NEXT:    [[E:%.*]] = mul i32 [[A:%.*]], [[B:%.*]]1057; CHECK-NEXT:    ret i32 [[E]]1058;1059  %C = sub i32 0, %A1060  %D = sub i32 0, %B1061  %E = mul i32 %C, %D1062  ret i32 %E1063}1064 1065define i32 @neg_neg_mul_nsw(i32 %A, i32 %B) {1066; CHECK-LABEL: @neg_neg_mul_nsw(1067; CHECK-NEXT:    [[E:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]1068; CHECK-NEXT:    ret i32 [[E]]1069;1070  %C = sub nsw i32 0, %A1071  %D = sub nsw i32 0, %B1072  %E = mul nsw i32 %C, %D1073  ret i32 %E1074}1075 1076define i124 @neg_neg_mul_apint(i124 %A, i124 %B) {1077; CHECK-LABEL: @neg_neg_mul_apint(1078; CHECK-NEXT:    [[E:%.*]] = mul i124 [[A:%.*]], [[B:%.*]]1079; CHECK-NEXT:    ret i124 [[E]]1080;1081  %C = sub i124 0, %A1082  %D = sub i124 0, %B1083  %E = mul i124 %C, %D1084  ret i124 %E1085}1086 1087define i32 @neg_mul_constant(i32 %A) {1088; CHECK-LABEL: @neg_mul_constant(1089; CHECK-NEXT:    [[E:%.*]] = mul i32 [[A:%.*]], -71090; CHECK-NEXT:    ret i32 [[E]]1091;1092  %C = sub i32 0, %A1093  %E = mul i32 %C, 71094  ret i32 %E1095}1096 1097define i55 @neg_mul_constant_apint(i55 %A) {1098; CHECK-LABEL: @neg_mul_constant_apint(1099; CHECK-NEXT:    [[E:%.*]] = mul i55 [[A:%.*]], -71100; CHECK-NEXT:    ret i55 [[E]]1101;1102  %C = sub i55 0, %A1103  %E = mul i55 %C, 71104  ret i55 %E1105}1106 1107define <3 x i8> @neg_mul_constant_vec(<3 x i8> %a) {1108; CHECK-LABEL: @neg_mul_constant_vec(1109; CHECK-NEXT:    [[B:%.*]] = mul <3 x i8> [[A:%.*]], splat (i8 -5)1110; CHECK-NEXT:    ret <3 x i8> [[B]]1111;1112  %A = sub <3 x i8> zeroinitializer, %a1113  %B = mul <3 x i8> %A, <i8 5, i8 5, i8 5>1114  ret <3 x i8> %B1115}1116 1117define <3 x i4> @neg_mul_constant_vec_weird(<3 x i4> %a) {1118; CHECK-LABEL: @neg_mul_constant_vec_weird(1119; CHECK-NEXT:    [[B:%.*]] = mul <3 x i4> [[A:%.*]], splat (i4 -5)1120; CHECK-NEXT:    ret <3 x i4> [[B]]1121;1122  %A = sub <3 x i4> zeroinitializer, %a1123  %B = mul <3 x i4> %A, <i4 5, i4 5, i4 5>1124  ret <3 x i4> %B1125}1126 1127define i64 @test29(i31 %A, i31 %B) {1128; CHECK-LABEL: @test29(1129; CHECK-NEXT:    [[C:%.*]] = sext i31 [[A:%.*]] to i641130; CHECK-NEXT:    [[D:%.*]] = sext i31 [[B:%.*]] to i641131; CHECK-NEXT:    [[E:%.*]] = mul nsw i64 [[C]], [[D]]1132; CHECK-NEXT:    ret i64 [[E]]1133;1134  %C = sext i31 %A to i641135  %D = sext i31 %B to i641136  %E = mul i64 %C, %D1137  ret i64 %E1138}1139 1140define i64 @test30(i32 %A, i32 %B) {1141; CHECK-LABEL: @test30(1142; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i641143; CHECK-NEXT:    [[D:%.*]] = zext i32 [[B:%.*]] to i641144; CHECK-NEXT:    [[E:%.*]] = mul nuw i64 [[C]], [[D]]1145; CHECK-NEXT:    ret i64 [[E]]1146;1147  %C = zext i32 %A to i641148  %D = zext i32 %B to i641149  %E = mul i64 %C, %D1150  ret i64 %E1151}1152 1153@PR22087 = external global i321154define i32 @test31(i32 %V) {1155; CHECK-LABEL: @test31(1156; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr inttoptr (i64 4 to ptr), @PR220871157; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[CMP]] to i321158; CHECK-NEXT:    [[MUL1:%.*]] = shl i32 [[V:%.*]], [[EXT]]1159; CHECK-NEXT:    ret i32 [[MUL1]]1160;1161  %cmp = icmp ne ptr inttoptr (i64 4 to ptr), @PR220871162  %ext = zext i1 %cmp to i321163  %shl = shl i32 1, %ext1164  %mul = mul i32 %V, %shl1165  ret i32 %mul1166}1167 1168define i32 @test32(i32 %X) {1169; CHECK-LABEL: @test32(1170; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 311171; CHECK-NEXT:    ret i32 [[MUL]]1172;1173  %mul = mul nsw i32 %X, -21474836481174  ret i32 %mul1175}1176 1177define <2 x i32> @test32vec(<2 x i32> %X) {1178; CHECK-LABEL: @test32vec(1179; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 31)1180; CHECK-NEXT:    ret <2 x i32> [[MUL]]1181;1182  %mul = mul nsw <2 x i32> %X, <i32 -2147483648, i32 -2147483648>1183  ret <2 x i32> %mul1184}1185 1186define i32 @test33(i32 %X) {1187; CHECK-LABEL: @test33(1188; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i32 [[X:%.*]], 301189; CHECK-NEXT:    ret i32 [[MUL]]1190;1191  %mul = mul nsw i32 %X, 10737418241192  ret i32 %mul1193}1194 1195define <2 x i32> @test33vec(<2 x i32> %X) {1196; CHECK-LABEL: @test33vec(1197; CHECK-NEXT:    [[MUL:%.*]] = shl nsw <2 x i32> [[X:%.*]], splat (i32 30)1198; CHECK-NEXT:    ret <2 x i32> [[MUL]]1199;1200  %mul = mul nsw <2 x i32> %X, <i32 1073741824, i32 1073741824>1201  ret <2 x i32> %mul1202}1203 1204define i128 @test34(i128 %X) {1205; CHECK-LABEL: @test34(1206; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i128 [[X:%.*]], 11207; CHECK-NEXT:    ret i128 [[MUL]]1208;1209  %mul = mul nsw i128 %X, 21210  ret i128 %mul1211}1212 1213define i32 @test_mul_canonicalize_op0(i32 %x, i32 %y) {1214; CHECK-LABEL: @test_mul_canonicalize_op0(1215; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]1216; CHECK-NEXT:    [[MUL:%.*]] = sub i32 0, [[TMP1]]1217; CHECK-NEXT:    ret i32 [[MUL]]1218;1219  %neg = sub i32 0, %x1220  %mul = mul i32 %neg, %y1221  ret i32 %mul1222}1223 1224define i32 @test_mul_canonicalize_op1(i32 %x, i32 %z) {1225; CHECK-LABEL: @test_mul_canonicalize_op1(1226; CHECK-NEXT:    [[Y_NEG:%.*]] = mul i32 [[Z:%.*]], -31227; CHECK-NEXT:    [[DOTNEG:%.*]] = mul i32 [[Y_NEG]], [[X:%.*]]1228; CHECK-NEXT:    ret i32 [[DOTNEG]]1229;1230  %y = mul i32 %z, 31231  %neg = sub i32 0, %x1232  %mul = mul i32 %y, %neg1233  ret i32 %mul1234}1235 1236define i32 @test_mul_canonicalize_nsw(i32 %x, i32 %y) {1237; CHECK-LABEL: @test_mul_canonicalize_nsw(1238; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]1239; CHECK-NEXT:    [[MUL:%.*]] = sub i32 0, [[TMP1]]1240; CHECK-NEXT:    ret i32 [[MUL]]1241;1242  %neg = sub nsw i32 0, %x1243  %mul = mul nsw i32 %neg, %y1244  ret i32 %mul1245}1246 1247define <2 x i32> @test_mul_canonicalize_vec(<2 x i32> %x, <2 x i32> %y) {1248; CHECK-LABEL: @test_mul_canonicalize_vec(1249; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i32> [[X:%.*]], [[Y:%.*]]1250; CHECK-NEXT:    [[MUL:%.*]] = sub <2 x i32> zeroinitializer, [[TMP1]]1251; CHECK-NEXT:    ret <2 x i32> [[MUL]]1252;1253  %neg = sub <2 x i32> <i32 0, i32 0>, %x1254  %mul = mul <2 x i32> %neg, %y1255  ret <2 x i32> %mul1256}1257 1258define i32 @test_mul_canonicalize_multiple_uses(i32 %x, i32 %y) {1259; CHECK-LABEL: @test_mul_canonicalize_multiple_uses(1260; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]1261; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]1262; CHECK-NEXT:    ret i32 [[MUL2]]1263;1264  %neg = sub i32 0, %x1265  %mul = mul i32 %neg, %y1266  %mul2 = mul i32 %mul, %neg1267  ret i32 %mul21268}1269 1270define i32 @mul_nsw_mul_nsw_neg(i32 %x, i32 %y) {1271; CHECK-LABEL: @mul_nsw_mul_nsw_neg(1272; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]1273; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]1274; CHECK-NEXT:    ret i32 [[MUL2]]1275;1276  %neg = sub i32 0, %x1277  %mul = mul nsw i32 %neg, %y1278  %mul2 = mul nsw i32 %mul, %neg1279  ret i32 %mul21280}1281 1282define i32 @mul_mul_nsw_neg(i32 %x,i32 %y) {1283; CHECK-LABEL: @mul_mul_nsw_neg(1284; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]1285; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]1286; CHECK-NEXT:    ret i32 [[MUL2]]1287;1288  %neg = sub i32 0, %x1289  %mul = mul nsw i32 %neg, %y1290  %mul2 = mul i32 %mul, %neg1291  ret i32 %mul21292}1293 1294define i32 @mul_nsw_mul_neg(i32 %x,i32 %y) {1295; CHECK-LABEL: @mul_nsw_mul_neg(1296; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]1297; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]1298; CHECK-NEXT:    ret i32 [[MUL2]]1299;1300  %neg = sub i32 0, %x1301  %mul = mul i32 %neg, %y1302  %mul2 = mul nsw i32 %mul, %neg1303  ret i32 %mul21304}1305 1306define i32 @mul_nsw_mul_neg_onearg(i32 %x) {1307; CHECK-LABEL: @mul_nsw_mul_neg_onearg(1308; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]1309; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]1310; CHECK-NEXT:    ret i32 [[MUL2]]1311;1312  %neg = sub i32 0, %x1313  %mul = mul i32 %neg, %x1314  %mul2 = mul nsw i32 %mul, %neg1315  ret i32 %mul21316}1317 1318define i8 @mul_mul_nsw_neg_onearg(i8 %x) {1319; CHECK-LABEL: @mul_mul_nsw_neg_onearg(1320; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i8 [[X:%.*]], [[X]]1321; CHECK-NEXT:    [[MUL2:%.*]] = mul i8 [[MUL_NEG]], [[X]]1322; CHECK-NEXT:    ret i8 [[MUL2]]1323;1324  %neg = sub i8 0, %x1325  %mul = mul nsw i8 %neg, %x1326  %mul2 = mul i8 %mul, %neg1327  ret i8 %mul21328}1329 1330define i32 @mul_nsw_mul_nsw_neg_onearg(i32 %x) {1331; CHECK-LABEL: @mul_nsw_mul_nsw_neg_onearg(1332; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]1333; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]1334; CHECK-NEXT:    ret i32 [[MUL2]]1335;1336  %neg = sub i32 0, %x1337  %mul = mul nsw i32 %neg, %x1338  %mul2 = mul nsw i32 %mul, %neg1339  ret i32 %mul21340}1341 1342define i32 @mul_nsw_shl_nsw_neg(i32 %x, i32 %y) {1343; CHECK-LABEL: @mul_nsw_shl_nsw_neg(1344; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]1345; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]1346; CHECK-NEXT:    ret i32 [[MUL]]1347;1348  %neg = sub i32 0, %x1349  %shl = shl nsw i32 %neg, %y1350  %mul = mul nsw i32 %shl, %neg1351  ret i32 %mul1352}1353 1354define i32 @mul_shl_nsw_neg(i32 %x,i32 %y) {1355; CHECK-LABEL: @mul_shl_nsw_neg(1356; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]1357; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]1358; CHECK-NEXT:    ret i32 [[MUL]]1359;1360  %neg = sub i32 0, %x1361  %shl = shl nsw i32 %neg, %y1362  %mul = mul i32 %shl, %neg1363  ret i32 %mul1364}1365 1366define i32 @mul_nsw_shl_neg(i32 %x,i32 %y) {1367; CHECK-LABEL: @mul_nsw_shl_neg(1368; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]1369; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]1370; CHECK-NEXT:    ret i32 [[MUL]]1371;1372  %neg = sub i32 0, %x1373  %shl = shl i32 %neg, %y1374  %mul = mul nsw i32 %shl, %neg1375  ret i32 %mul1376}1377 1378define i32 @mul_nsw_shl_neg_onearg(i32 %x) {1379; CHECK-LABEL: @mul_nsw_shl_neg_onearg(1380; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[X]]1381; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]1382; CHECK-NEXT:    ret i32 [[MUL]]1383;1384  %neg = sub i32 0, %x1385  %shl = shl i32 %neg, %x1386  %mul = mul nsw i32 %shl, %neg1387  ret i32 %mul1388}1389 1390define i8 @mul_shl_nsw_neg_onearg(i8 %x) {1391; CHECK-LABEL: @mul_shl_nsw_neg_onearg(1392; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i8 [[X:%.*]], [[X]]1393; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[SHL_NEG]], [[X]]1394; CHECK-NEXT:    ret i8 [[MUL]]1395;1396  %neg = sub i8 0, %x1397  %shl = shl nsw i8 %neg, %x1398  %mul = mul i8 %shl, %neg1399  ret i8 %mul1400}1401 1402define i32 @mul_nsw_shl_nsw_neg_onearg(i32 %x) {1403; CHECK-LABEL: @mul_nsw_shl_nsw_neg_onearg(1404; CHECK-NEXT:    [[SHL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]1405; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]1406; CHECK-NEXT:    ret i32 [[MUL]]1407;1408  %neg = sub i32 0, %x1409  %shl = mul nsw i32 %neg, %x1410  %mul = mul nsw i32 %shl, %neg1411  ret i32 %mul1412}1413 1414define i32 @mul_use_mul_neg(i32 %x,i32 %y) {1415; CHECK-LABEL: @mul_use_mul_neg(1416; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]1417; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[Y:%.*]], [[NEG]]1418; CHECK-NEXT:    call void @use32(i32 [[MUL]])1419; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL]], [[NEG]]1420; CHECK-NEXT:    ret i32 [[MUL2]]1421;1422  %neg = sub i32 0, %x1423  %mul = mul i32 %neg, %y1424  call void @use32(i32 %mul)1425  %mul2 = mul i32 %mul, %neg1426  ret i32 %mul21427}1428 1429define i32 @mul_shl_use_mul_neg(i32 %x,i32 %y) {1430; CHECK-LABEL: @mul_shl_use_mul_neg(1431; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]1432; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[NEG]], [[Y:%.*]]1433; CHECK-NEXT:    call void @use32(i32 [[SHL]])1434; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[SHL]], [[NEG]]1435; CHECK-NEXT:    ret i32 [[MUL2]]1436;1437  %neg = sub i32 0, %x1438  %shl = shl i32 %neg, %y1439  call void @use32(i32 %shl)1440  %mul2 = mul i32 %shl, %neg1441  ret i32 %mul21442}1443 1444@X = global i32 51445 1446define i64 @test_mul_canonicalize_neg_is_not_undone(i64 %L1) {1447; Check we do not undo the canonicalization of 0 - (X * Y), if Y is a constant1448; expr.1449; CHECK-LABEL: @test_mul_canonicalize_neg_is_not_undone(1450; CHECK-NEXT:    [[B4:%.*]] = mul i64 [[L1:%.*]], sub (i64 0, i64 ptrtoint (ptr @X to i64))1451; CHECK-NEXT:    ret i64 [[B4]]1452;1453  %v1 = ptrtoint ptr @X to i641454  %B8 = sub i64 0, %v11455  %B4 = mul i64 %B8, %L11456  ret i64 %B41457}1458 1459define i32 @negate_if_true(i32 %x, i1 %cond) {1460; CHECK-LABEL: @negate_if_true(1461; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]1462; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[X]]1463; CHECK-NEXT:    ret i32 [[R]]1464;1465  %sel = select i1 %cond, i32 -1, i32 11466  %r = mul i32 %sel, %x1467  ret i32 %r1468}1469 1470define i32 @negate_if_false(i32 %x, i1 %cond) {1471; CHECK-LABEL: @negate_if_false(1472; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]1473; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], i32 [[X]], i32 [[TMP1]]1474; CHECK-NEXT:    ret i32 [[R]]1475;1476  %sel = select i1 %cond, i32 1, i32 -11477  %r = mul i32 %sel, %x1478  ret i32 %r1479}1480 1481define <2 x i8> @negate_if_true_commute(<2 x i8> %px, i1 %cond) {1482; CHECK-LABEL: @negate_if_true_commute(1483; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> splat (i8 42), [[PX:%.*]]1484; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw <2 x i8> zeroinitializer, [[X]]1485; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], <2 x i8> [[TMP1]], <2 x i8> [[X]]1486; CHECK-NEXT:    ret <2 x i8> [[R]]1487;1488  %x = sdiv <2 x i8> <i8 42, i8 42>, %px  ; thwart complexity-based canonicalization1489  %sel = select i1 %cond, <2 x i8> <i8 -1, i8 -1>, <2 x i8> <i8 1, i8 1>1490  %r = mul <2 x i8> %x, %sel1491  ret <2 x i8> %r1492}1493 1494define <2 x i8> @negate_if_false_commute(<2 x i8> %px, <2 x i1> %cond) {1495; CHECK-LABEL: @negate_if_false_commute(1496; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 5>, [[PX:%.*]]1497; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> zeroinitializer, [[X]]1498; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i8> [[X]], <2 x i8> [[TMP1]]1499; CHECK-NEXT:    ret <2 x i8> [[R]]1500;1501  %x = sdiv <2 x i8> <i8 42, i8 5>, %px  ; thwart complexity-based canonicalization1502  %sel = select <2 x i1> %cond, <2 x i8> <i8 1, i8 poison>, <2 x i8> <i8 -1, i8 -1>1503  %r = mul <2 x i8> %x, %sel1504  ret <2 x i8> %r1505}1506 1507; Negative test1508 1509define i32 @negate_if_true_extra_use(i32 %x, i1 %cond) {1510; CHECK-LABEL: @negate_if_true_extra_use(1511; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 -1, i32 11512; CHECK-NEXT:    call void @use32(i32 [[SEL]])1513; CHECK-NEXT:    [[R:%.*]] = mul i32 [[SEL]], [[X:%.*]]1514; CHECK-NEXT:    ret i32 [[R]]1515;1516  %sel = select i1 %cond, i32 -1, i32 11517  call void @use32(i32 %sel)1518  %r = mul i32 %sel, %x1519  ret i32 %r1520}1521 1522; Negative test1523 1524define <2 x i8> @negate_if_true_wrong_constant(<2 x i8> %px, i1 %cond) {1525; CHECK-LABEL: @negate_if_true_wrong_constant(1526; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> splat (i8 42), [[PX:%.*]]1527; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x i8> <i8 -1, i8 0>, <2 x i8> splat (i8 1)1528; CHECK-NEXT:    [[R:%.*]] = mul <2 x i8> [[X]], [[SEL]]1529; CHECK-NEXT:    ret <2 x i8> [[R]]1530;1531  %x = sdiv <2 x i8> <i8 42, i8 42>, %px  ; thwart complexity-based canonicalization1532  %sel = select i1 %cond, <2 x i8> <i8 -1, i8 0>, <2 x i8> <i8 1, i8 1>1533  %r = mul <2 x i8> %x, %sel1534  ret <2 x i8> %r1535}1536 1537; (C ? (X /exact Y) : 1) * Y -> C ? X : Y1538define i32 @mul_div_select(i32 %x, i32 %y, i1 %c) {1539; CHECK-LABEL: @mul_div_select(1540; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]1541; CHECK-NEXT:    ret i32 [[MUL]]1542;1543  %div = udiv exact i32 %x, %y1544  %sel = select i1 %c, i32 %div, i32 11545  %mul = mul i32 %sel, %y1546  ret i32 %mul1547}1548 1549; fold mul(abs(x),abs(x)) -> mul(x,x)1550define i31 @combine_mul_abs_i31(i31 %0) {1551; CHECK-LABEL: @combine_mul_abs_i31(1552; CHECK-NEXT:    [[M:%.*]] = mul i31 [[TMP0:%.*]], [[TMP0]]1553; CHECK-NEXT:    ret i31 [[M]]1554;1555  %c = icmp slt i31 %0, 01556  %s = sub nsw i31 0, %01557  %r = select i1 %c, i31 %s, i31 %01558  %m = mul i31 %r, %r1559  ret i31 %m1560}1561 1562define i32 @combine_mul_abs_i32(i32 %0) {1563; CHECK-LABEL: @combine_mul_abs_i32(1564; CHECK-NEXT:    [[M:%.*]] = mul i32 [[TMP0:%.*]], [[TMP0]]1565; CHECK-NEXT:    ret i32 [[M]]1566;1567  %c = icmp slt i32 %0, 01568  %s = sub nsw i32 0, %01569  %r = select i1 %c, i32 %s, i32 %01570  %m = mul i32 %r, %r1571  ret i32 %m1572}1573 1574define <4 x i32> @combine_mul_abs_v4i32(<4 x i32> %0) {1575; CHECK-LABEL: @combine_mul_abs_v4i32(1576; CHECK-NEXT:    [[M:%.*]] = mul <4 x i32> [[TMP0:%.*]], [[TMP0]]1577; CHECK-NEXT:    ret <4 x i32> [[M]]1578;1579  %c = icmp slt <4 x i32> %0, zeroinitializer1580  %s = sub nsw <4 x i32> zeroinitializer, %01581  %r = select <4 x i1> %c, <4 x i32> %s, <4 x i32> %01582  %m = mul <4 x i32> %r, %r1583  ret <4 x i32> %m1584}1585 1586; fold mul(nabs(x),nabs(x)) -> mul(x,x)1587define i31 @combine_mul_nabs_i31(i31 %0) {1588; CHECK-LABEL: @combine_mul_nabs_i31(1589; CHECK-NEXT:    [[M:%.*]] = mul i31 [[TMP0:%.*]], [[TMP0]]1590; CHECK-NEXT:    ret i31 [[M]]1591;1592  %c = icmp slt i31 %0, 01593  %s = sub nsw i31 0, %01594  %r = select i1 %c, i31 %0, i31 %s1595  %m = mul i31 %r, %r1596  ret i31 %m1597}1598 1599define i32 @combine_mul_nabs_i32(i32 %0) {1600; CHECK-LABEL: @combine_mul_nabs_i32(1601; CHECK-NEXT:    [[M:%.*]] = mul i32 [[TMP0:%.*]], [[TMP0]]1602; CHECK-NEXT:    ret i32 [[M]]1603;1604  %c = icmp slt i32 %0, 01605  %s = sub nsw i32 0, %01606  %r = select i1 %c, i32 %0, i32 %s1607  %m = mul i32 %r, %r1608  ret i32 %m1609}1610 1611define <4 x i32> @combine_mul_nabs_v4i32(<4 x i32> %0) {1612; CHECK-LABEL: @combine_mul_nabs_v4i32(1613; CHECK-NEXT:    [[M:%.*]] = mul <4 x i32> [[TMP0:%.*]], [[TMP0]]1614; CHECK-NEXT:    ret <4 x i32> [[M]]1615;1616  %c = icmp slt <4 x i32> %0, zeroinitializer1617  %s = sub nsw <4 x i32> zeroinitializer, %01618  %r = select <4 x i1> %c, <4 x i32> %0, <4 x i32> %s1619  %m = mul <4 x i32> %r, %r1620  ret <4 x i32> %m1621}1622 1623define i32 @combine_mul_abs_intrin(i32 %x) {1624; CHECK-LABEL: @combine_mul_abs_intrin(1625; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], [[X]]1626; CHECK-NEXT:    ret i32 [[MUL]]1627;1628  %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)1629  %mul = mul i32 %abs, %abs1630  ret i32 %mul1631}1632 1633define i32 @combine_mul_nabs_intrin(i32 %x) {1634; CHECK-LABEL: @combine_mul_nabs_intrin(1635; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], [[X]]1636; CHECK-NEXT:    ret i32 [[MUL]]1637;1638  %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)1639  %neg = sub i32 0, %abs1640  %mul = mul i32 %neg, %neg1641  ret i32 %mul1642}1643 1644; z * splat(0) = splat(0), even for scalable vectors1645define <vscale x 2 x i64> @mul_scalable_splat_zero(<vscale x 2 x i64> %z) {1646; CHECK-LABEL: @mul_scalable_splat_zero(1647; CHECK-NEXT:    ret <vscale x 2 x i64> zeroinitializer1648;1649  %shuf = shufflevector <vscale x 2 x i64> insertelement (<vscale x 2 x i64> poison, i64 0, i32 0), <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer1650  %t3 = mul <vscale x 2 x i64> %shuf, %z1651  ret <vscale x 2 x i64> %t31652}1653 1654; fold mul(abs(x),abs(y)) -> abs(mul(x,y))1655define i32 @combine_mul_abs_x_abs_y(i32 %x, i32 %y) {1656; CHECK-LABEL: @combine_mul_abs_x_abs_y(1657; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw i32 [[X:%.*]], [[Y:%.*]]1658; CHECK-NEXT:    [[MUL:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)1659; CHECK-NEXT:    ret i32 [[MUL]]1660;1661  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)1662  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 true)1663  %mul = mul nsw i32 %abs_x, %abs_y1664  ret i32 %mul1665}1666 1667define i32 @combine_mul_abs_x_abs_y_no_nsw(i32 %x, i32 %y) {1668; CHECK-LABEL: @combine_mul_abs_x_abs_y_no_nsw(1669; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)1670; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 true)1671; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[ABS_X]], [[ABS_Y]]1672; CHECK-NEXT:    ret i32 [[MUL]]1673;1674  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)1675  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 true)1676  %mul = mul i32 %abs_x, %abs_y1677  ret i32 %mul1678}1679 1680define i32 @combine_mul_abs_x_abs_y_poison_1(i32 %x, i32 %y) {1681; CHECK-LABEL: @combine_mul_abs_x_abs_y_poison_1(1682; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)1683; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 false)1684; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ABS_X]], [[ABS_Y]]1685; CHECK-NEXT:    ret i32 [[MUL]]1686;1687  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)1688  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 false)1689  %mul = mul nsw i32 %abs_x, %abs_y1690  ret i32 %mul1691}1692 1693define i32 @combine_mul_abs_x_abs_y_poison_2(i32 %x, i32 %y) {1694; CHECK-LABEL: @combine_mul_abs_x_abs_y_poison_2(1695; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)1696; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 false)1697; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ABS_X]], [[ABS_Y]]1698; CHECK-NEXT:    ret i32 [[MUL]]1699;1700  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 false)1701  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 false)1702  %mul = mul nsw i32 %abs_x, %abs_y1703  ret i32 %mul1704}1705 1706define i32 @combine_mul_abs_x_abs_y_not_oneuse(i32 %x, i32 %y) {1707; CHECK-LABEL: @combine_mul_abs_x_abs_y_not_oneuse(1708; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)1709; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 true)1710; CHECK-NEXT:    [[ABS_X1:%.*]] = add nuw i32 [[ABS_Y]], 11711; CHECK-NEXT:    [[RET:%.*]] = mul i32 [[ABS_X]], [[ABS_X1]]1712; CHECK-NEXT:    ret i32 [[RET]]1713;1714  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)1715  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 true)1716  %mul = mul nsw i32 %abs_x, %abs_y1717  %ret = add i32 %mul, %abs_x1718  ret i32 %ret1719}1720 1721;1722; fold mul(sub(x,y),negpow2) -> shl(sub(y,x),log2(pow2))1723;1724 1725define i32 @mulsub1(i32 %a0, i32 %a1) {1726; CHECK-LABEL: @mulsub1(1727; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub i32 [[A0:%.*]], [[A1:%.*]]1728; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[SUB_NEG]], 21729; CHECK-NEXT:    ret i32 [[MUL]]1730;1731  %sub = sub i32 %a1, %a01732  %mul = mul i32 %sub, -41733  ret i32 %mul1734}1735 1736define <2 x i32> @mulsub1_vec(<2 x i32> %a0, <2 x i32> %a1) {1737; CHECK-LABEL: @mulsub1_vec(1738; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub <2 x i32> [[A0:%.*]], [[A1:%.*]]1739; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], splat (i32 2)1740; CHECK-NEXT:    ret <2 x i32> [[MUL]]1741;1742  %sub = sub <2 x i32> %a1, %a01743  %mul = mul <2 x i32> %sub, <i32 -4, i32 -4>1744  ret <2 x i32> %mul1745}1746 1747define <2 x i32> @mulsub1_vec_nonuniform(<2 x i32> %a0, <2 x i32> %a1) {1748; CHECK-LABEL: @mulsub1_vec_nonuniform(1749; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub <2 x i32> [[A0:%.*]], [[A1:%.*]]1750; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 3>1751; CHECK-NEXT:    ret <2 x i32> [[MUL]]1752;1753  %sub = sub <2 x i32> %a1, %a01754  %mul = mul <2 x i32> %sub, <i32 -4, i32 -8>1755  ret <2 x i32> %mul1756}1757 1758define <2 x i32> @mulsub1_vec_nonuniform_poison(<2 x i32> %a0, <2 x i32> %a1) {1759; CHECK-LABEL: @mulsub1_vec_nonuniform_poison(1760; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub <2 x i32> [[A0:%.*]], [[A1:%.*]]1761; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 0>1762; CHECK-NEXT:    ret <2 x i32> [[MUL]]1763;1764  %sub = sub <2 x i32> %a1, %a01765  %mul = mul <2 x i32> %sub, <i32 -4, i32 poison>1766  ret <2 x i32> %mul1767}1768 1769define i32 @mulsub2(i32 %a0) {1770; CHECK-LABEL: @mulsub2(1771; CHECK-NEXT:    [[SUB_NEG:%.*]] = shl i32 [[A0:%.*]], 21772; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[SUB_NEG]], -641773; CHECK-NEXT:    ret i32 [[MUL]]1774;1775  %sub = sub i32 16, %a01776  %mul = mul i32 %sub, -41777  ret i32 %mul1778}1779 1780define <2 x i32> @mulsub2_vec(<2 x i32> %a0) {1781; CHECK-LABEL: @mulsub2_vec(1782; CHECK-NEXT:    [[SUB_NEG:%.*]] = shl <2 x i32> [[A0:%.*]], splat (i32 2)1783; CHECK-NEXT:    [[MUL:%.*]] = add <2 x i32> [[SUB_NEG]], splat (i32 -64)1784; CHECK-NEXT:    ret <2 x i32> [[MUL]]1785;1786  %sub = sub <2 x i32> <i32 16, i32 16>, %a01787  %mul = mul <2 x i32> %sub, <i32 -4, i32 -4>1788  ret <2 x i32> %mul1789}1790 1791define <2 x i32> @mulsub2_vec_nonuniform(<2 x i32> %a0) {1792; CHECK-LABEL: @mulsub2_vec_nonuniform(1793; CHECK-NEXT:    [[SUB_NEG:%.*]] = add <2 x i32> [[A0:%.*]], <i32 -16, i32 -32>1794; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 3>1795; CHECK-NEXT:    ret <2 x i32> [[MUL]]1796;1797  %sub = sub <2 x i32> <i32 16, i32 32>, %a01798  %mul = mul <2 x i32> %sub, <i32 -4, i32 -8>1799  ret <2 x i32> %mul1800}1801 1802define <2 x i32> @mulsub2_vec_nonuniform_poison(<2 x i32> %a0) {1803; CHECK-LABEL: @mulsub2_vec_nonuniform_poison(1804; CHECK-NEXT:    [[SUB_NEG:%.*]] = add <2 x i32> [[A0:%.*]], <i32 -16, i32 -32>1805; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 0>1806; CHECK-NEXT:    ret <2 x i32> [[MUL]]1807;1808  %sub = sub <2 x i32> <i32 16, i32 32>, %a01809  %mul = mul <2 x i32> %sub, <i32 -4, i32 poison>1810  ret <2 x i32> %mul1811}1812 1813define i8 @mulsub_nsw(i8 %a1, i8 %a2) {1814; CHECK-LABEL: @mulsub_nsw(1815; CHECK-NEXT:    [[A_NEG:%.*]] = sub nsw i8 [[A2:%.*]], [[A1:%.*]]1816; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i8 [[A_NEG]], 11817; CHECK-NEXT:    ret i8 [[MUL]]1818;1819  %a = sub nsw i8 %a1, %a21820  %mul = mul nsw i8 %a, -21821  ret i8 %mul1822}1823 1824; It would be safe to keep the nsw on the shl here, but only because the mul1825; to shl transform happens to replace poison with 0.1826define <2 x i8> @mulsub_nsw_poison(<2 x i8> %a1, <2 x i8> %a2) {1827; CHECK-LABEL: @mulsub_nsw_poison(1828; CHECK-NEXT:    [[A_NEG:%.*]] = sub nsw <2 x i8> [[A2:%.*]], [[A1:%.*]]1829; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i8> [[A_NEG]], <i8 1, i8 0>1830; CHECK-NEXT:    ret <2 x i8> [[MUL]]1831;1832  %a = sub nsw <2 x i8> %a1, %a21833  %mul = mul nsw <2 x i8> %a, <i8 -2, i8 poison>1834  ret <2 x i8> %mul1835}1836 1837define i32 @muladd2(i32 %a0) {1838; CHECK-LABEL: @muladd2(1839; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[A0:%.*]], 21840; CHECK-NEXT:    [[MUL:%.*]] = sub i32 -64, [[TMP1]]1841; CHECK-NEXT:    ret i32 [[MUL]]1842;1843  %add = add i32 %a0, 161844  %mul = mul i32 %add, -41845  ret i32 %mul1846}1847 1848define <2 x i32> @muladd2_vec(<2 x i32> %a0) {1849; CHECK-LABEL: @muladd2_vec(1850; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> [[A0:%.*]], splat (i32 2)1851; CHECK-NEXT:    [[MUL:%.*]] = sub <2 x i32> splat (i32 -64), [[TMP1]]1852; CHECK-NEXT:    ret <2 x i32> [[MUL]]1853;1854  %add = add <2 x i32> %a0, <i32 16, i32 16>1855  %mul = mul <2 x i32> %add, <i32 -4, i32 -4>1856  ret <2 x i32> %mul1857}1858 1859define <2 x i32> @muladd2_vec_nonuniform(<2 x i32> %a0) {1860; CHECK-LABEL: @muladd2_vec_nonuniform(1861; CHECK-NEXT:    [[ADD_NEG:%.*]] = sub <2 x i32> <i32 -16, i32 -32>, [[A0:%.*]]1862; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[ADD_NEG]], <i32 2, i32 3>1863; CHECK-NEXT:    ret <2 x i32> [[MUL]]1864;1865  %add = add <2 x i32> %a0, <i32 16, i32 32>1866  %mul = mul <2 x i32> %add, <i32 -4, i32 -8>1867  ret <2 x i32> %mul1868}1869 1870define <2 x i32> @muladd2_vec_nonuniform_poison(<2 x i32> %a0) {1871; CHECK-LABEL: @muladd2_vec_nonuniform_poison(1872; CHECK-NEXT:    [[ADD_NEG:%.*]] = sub <2 x i32> <i32 -16, i32 -32>, [[A0:%.*]]1873; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[ADD_NEG]], <i32 2, i32 0>1874; CHECK-NEXT:    ret <2 x i32> [[MUL]]1875;1876  %add = add <2 x i32> %a0, <i32 16, i32 32>1877  %mul = mul <2 x i32> %add, <i32 -4, i32 poison>1878  ret <2 x i32> %mul1879}1880 1881define i32 @mulmuladd2(i32 %a0, i32 %a1) {1882; CHECK-LABEL: @mulmuladd2(1883; CHECK-NEXT:    [[ADD_NEG:%.*]] = sub i32 1073741808, [[A0:%.*]]1884; CHECK-NEXT:    [[MUL1_NEG:%.*]] = mul i32 [[ADD_NEG]], [[A1:%.*]]1885; CHECK-NEXT:    [[MUL2:%.*]] = shl i32 [[MUL1_NEG]], 21886; CHECK-NEXT:    ret i32 [[MUL2]]1887;1888  %add = add i32 %a0, 161889  %mul1 = mul i32 %add, %a11890  %mul2 = mul i32 %mul1, -41891  ret i32 %mul21892}1893define i32 @mulmuladd2_extrause0(i32 %a0, i32 %a1) {1894; CHECK-LABEL: @mulmuladd2_extrause0(1895; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A0:%.*]], 161896; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[ADD]], [[A1:%.*]]1897; CHECK-NEXT:    call void @use32(i32 [[MUL1]])1898; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], -41899; CHECK-NEXT:    ret i32 [[MUL2]]1900;1901  %add = add i32 %a0, 161902  %mul1 = mul i32 %add, %a11903  call void @use32(i32 %mul1)1904  %mul2 = mul i32 %mul1, -41905  ret i32 %mul21906}1907define i32 @mulmuladd2_extrause1(i32 %a0, i32 %a1) {1908; CHECK-LABEL: @mulmuladd2_extrause1(1909; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A0:%.*]], 161910; CHECK-NEXT:    call void @use32(i32 [[ADD]])1911; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[ADD]], [[A1:%.*]]1912; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], -41913; CHECK-NEXT:    ret i32 [[MUL2]]1914;1915  %add = add i32 %a0, 161916  call void @use32(i32 %add)1917  %mul1 = mul i32 %add, %a11918  %mul2 = mul i32 %mul1, -41919  ret i32 %mul21920}1921define i32 @mulmuladd2_extrause2(i32 %a0, i32 %a1) {1922; CHECK-LABEL: @mulmuladd2_extrause2(1923; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A0:%.*]], 161924; CHECK-NEXT:    call void @use32(i32 [[ADD]])1925; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[ADD]], [[A1:%.*]]1926; CHECK-NEXT:    call void @use32(i32 [[MUL1]])1927; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], -41928; CHECK-NEXT:    ret i32 [[MUL2]]1929;1930  %add = add i32 %a0, 161931  call void @use32(i32 %add)1932  %mul1 = mul i32 %add, %a11933  call void @use32(i32 %mul1)1934  %mul2 = mul i32 %mul1, -41935  ret i32 %mul21936}1937 1938define i32 @mulnot(i32 %a0) {1939; CHECK-LABEL: @mulnot(1940; CHECK-NEXT:    [[ADD_NEG:%.*]] = shl i32 [[A0:%.*]], 21941; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[ADD_NEG]], 41942; CHECK-NEXT:    ret i32 [[MUL]]1943;1944  %add = xor i32 %a0, -11945  %mul = mul i32 %add, -41946  ret i32 %mul1947}1948 1949define i32 @mulnot_extrause(i32 %a0) {1950; CHECK-LABEL: @mulnot_extrause(1951; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A0:%.*]], -11952; CHECK-NEXT:    call void @use32(i32 [[NOT]])1953; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[NOT]], -41954; CHECK-NEXT:    ret i32 [[MUL]]1955;1956  %not = xor i32 %a0, -11957  call void @use32(i32 %not)1958  %mul = mul i32 %not, -41959  ret i32 %mul1960}1961 1962define i32 @zext_negpow2(i8 %x) {1963; CHECK-LABEL: @zext_negpow2(1964; CHECK-NEXT:    [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]1965; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext i8 [[X_NEG]] to i321966; CHECK-NEXT:    [[R:%.*]] = shl nuw i32 [[X_NEG_Z]], 241967; CHECK-NEXT:    ret i32 [[R]]1968;1969  %zx = zext i8 %x to i321970  %r = mul i32 %zx, -16777216 ; -1 << 241971  ret i32 %r1972}1973 1974; splat constant1975 1976define <2 x i14> @zext_negpow2_vec(<2 x i5> %x) {1977; CHECK-LABEL: @zext_negpow2_vec(1978; CHECK-NEXT:    [[X_NEG:%.*]] = sub <2 x i5> zeroinitializer, [[X:%.*]]1979; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext <2 x i5> [[X_NEG]] to <2 x i14>1980; CHECK-NEXT:    [[R:%.*]] = shl <2 x i14> [[X_NEG_Z]], splat (i14 11)1981; CHECK-NEXT:    ret <2 x i14> [[R]]1982;1983  %zx = zext <2 x i5> %x to <2 x i14>1984  %r = mul <2 x i14> %zx, <i14 -2048, i14 -2048> ; -1 << 111985  ret <2 x i14> %r1986}1987 1988; negative test - mul must be big enough to cover bitwidth diff1989 1990define i32 @zext_negpow2_too_small(i8 %x) {1991; CHECK-LABEL: @zext_negpow2_too_small(1992; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X:%.*]] to i321993; CHECK-NEXT:    [[R:%.*]] = mul nsw i32 [[ZX]], -83886081994; CHECK-NEXT:    ret i32 [[R]]1995;1996  %zx = zext i8 %x to i321997  %r = mul i32 %zx, -8388608 ; -1 << 231998  ret i32 %r1999}2000 2001define i16 @sext_negpow2(i9 %x) {2002; CHECK-LABEL: @sext_negpow2(2003; CHECK-NEXT:    [[X_NEG:%.*]] = sub i9 0, [[X:%.*]]2004; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext i9 [[X_NEG]] to i162005; CHECK-NEXT:    [[R:%.*]] = shl i16 [[X_NEG_Z]], 102006; CHECK-NEXT:    ret i16 [[R]]2007;2008  %sx = sext i9 %x to i162009  %r = mul i16 %sx, -1024 ; -1 << 102010  ret i16 %r2011}2012 2013; splat constant with poison element(s)2014 2015define <2 x i16> @sext_negpow2_vec(<2 x i8> %x) {2016; CHECK-LABEL: @sext_negpow2_vec(2017; CHECK-NEXT:    [[X_NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]2018; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext <2 x i8> [[X_NEG]] to <2 x i16>2019; CHECK-NEXT:    [[R:%.*]] = shl nuw <2 x i16> [[X_NEG_Z]], splat (i16 8)2020; CHECK-NEXT:    ret <2 x i16> [[R]]2021;2022  %sx = sext <2 x i8> %x to <2 x i16>2023  %r = mul <2 x i16> %sx, <i16 -256, i16 poison> ; -1 << 82024  ret <2 x i16> %r2025}2026 2027; negative test - mul must be big enough to cover bitwidth diff2028 2029define <2 x i16> @sext_negpow2_too_small_vec(<2 x i8> %x) {2030; CHECK-LABEL: @sext_negpow2_too_small_vec(2031; CHECK-NEXT:    [[SX:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i16>2032; CHECK-NEXT:    [[R:%.*]] = mul nsw <2 x i16> [[SX]], <i16 -128, i16 poison>2033; CHECK-NEXT:    ret <2 x i16> [[R]]2034;2035  %sx = sext <2 x i8> %x to <2 x i16>2036  %r = mul <2 x i16> %sx, <i16 -128, i16 poison> ; -1 << 72037  ret <2 x i16> %r2038}2039 2040; negative test - too many uses2041 2042define i32 @zext_negpow2_use(i8 %x) {2043; CHECK-LABEL: @zext_negpow2_use(2044; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X:%.*]] to i322045; CHECK-NEXT:    call void @use32(i32 [[ZX]])2046; CHECK-NEXT:    [[R:%.*]] = mul i32 [[ZX]], -167772162047; CHECK-NEXT:    ret i32 [[R]]2048;2049  %zx = zext i8 %x to i322050  call void @use32(i32 %zx)2051  %r = mul i32 %zx, -16777216 ; -1 << 242052  ret i32 %r2053}2054 2055define i32 @mul_sext_icmp_with_zero(i32 %x) {2056; CHECK-LABEL: @mul_sext_icmp_with_zero(2057; CHECK-NEXT:    ret i32 02058;2059  %cmp = icmp eq i32 %x, 02060  %sext = sext i1 %cmp to i322061  %mul = mul i32 %sext, %x2062  ret i32 %mul2063}2064 2065define i32 @test_mul_sext_bool(i1 %x, i32 %y) {2066; CHECK-LABEL: @test_mul_sext_bool(2067; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]2068; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 02069; CHECK-NEXT:    ret i32 [[MUL]]2070;2071  %sext = sext i1 %x to i322072  %mul = mul i32 %sext, %y2073  ret i32 %mul2074}2075 2076define i32 @test_mul_sext_bool_nuw(i1 %x, i32 %y) {2077; CHECK-LABEL: @test_mul_sext_bool_nuw(2078; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]2079; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 02080; CHECK-NEXT:    ret i32 [[MUL]]2081;2082  %sext = sext i1 %x to i322083  %mul = mul nuw i32 %sext, %y2084  ret i32 %mul2085}2086 2087define i32 @test_mul_sext_bool_nsw(i1 %x, i32 %y) {2088; CHECK-LABEL: @test_mul_sext_bool_nsw(2089; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[Y:%.*]]2090; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 02091; CHECK-NEXT:    ret i32 [[MUL]]2092;2093  %sext = sext i1 %x to i322094  %mul = mul nsw i32 %sext, %y2095  ret i32 %mul2096}2097 2098define i32 @test_mul_sext_bool_nuw_nsw(i1 %x, i32 %y) {2099; CHECK-LABEL: @test_mul_sext_bool_nuw_nsw(2100; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[Y:%.*]]2101; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 02102; CHECK-NEXT:    ret i32 [[MUL]]2103;2104  %sext = sext i1 %x to i322105  %mul = mul nuw nsw i32 %sext, %y2106  ret i32 %mul2107}2108 2109define i32 @test_mul_sext_bool_commuted(i1 %x, i32 %y) {2110; CHECK-LABEL: @test_mul_sext_bool_commuted(2111; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -22112; CHECK-NEXT:    [[YY_NEG:%.*]] = add i32 [[TMP1]], 12113; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[YY_NEG]], i32 02114; CHECK-NEXT:    ret i32 [[MUL]]2115;2116  %yy = xor i32 %y, 12117  %sext = sext i1 %x to i322118  %mul = mul i32 %yy, %sext2119  ret i32 %mul2120}2121 2122define i32 @test_mul_sext_nonbool(i2 %x, i32 %y) {2123; CHECK-LABEL: @test_mul_sext_nonbool(2124; CHECK-NEXT:    [[SEXT:%.*]] = sext i2 [[X:%.*]] to i322125; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[Y:%.*]], [[SEXT]]2126; CHECK-NEXT:    ret i32 [[MUL]]2127;2128  %sext = sext i2 %x to i322129  %mul = mul i32 %sext, %y2130  ret i32 %mul2131}2132 2133define i32 @test_mul_sext_multiuse(i1 %x, i32 %y) {2134; CHECK-LABEL: @test_mul_sext_multiuse(2135; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[X:%.*]] to i322136; CHECK-NEXT:    tail call void @use(i32 [[SEXT]])2137; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[Y:%.*]], [[SEXT]]2138; CHECK-NEXT:    ret i32 [[MUL]]2139;2140  %sext = sext i1 %x to i322141  tail call void @use(i32 %sext)2142  %mul = mul i32 %sext, %y2143  ret i32 %mul2144}2145 2146define i8 @mul_nsw_nonneg(i8 %x, i8 %y) {2147; CHECK-LABEL: @mul_nsw_nonneg(2148; CHECK-NEXT:    [[X_NNEG:%.*]] = icmp sgt i8 [[X:%.*]], -12149; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NNEG]])2150; CHECK-NEXT:    [[Y_NNEG:%.*]] = icmp sgt i8 [[Y:%.*]], -12151; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NNEG]])2152; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i8 [[X]], [[Y]]2153; CHECK-NEXT:    ret i8 [[MUL]]2154;2155  %x.nneg = icmp sge i8 %x, 02156  call void @llvm.assume(i1 %x.nneg)2157  %y.nneg = icmp sge i8 %y, 02158  call void @llvm.assume(i1 %y.nneg)2159  %mul = mul nsw i8 %x, %y2160  ret i8 %mul2161}2162 2163define i8 @mul_nsw_not_nonneg1(i8 %x, i8 %y) {2164; CHECK-LABEL: @mul_nsw_not_nonneg1(2165; CHECK-NEXT:    [[Y_NNEG:%.*]] = icmp sgt i8 [[Y:%.*]], -12166; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NNEG]])2167; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X:%.*]], [[Y]]2168; CHECK-NEXT:    ret i8 [[MUL]]2169;2170  %y.nneg = icmp sge i8 %y, 02171  call void @llvm.assume(i1 %y.nneg)2172  %mul = mul nsw i8 %x, %y2173  ret i8 %mul2174}2175 2176define i8 @mul_nsw_not_nonneg2(i8 %x, i8 %y) {2177; CHECK-LABEL: @mul_nsw_not_nonneg2(2178; CHECK-NEXT:    [[X_NNEG:%.*]] = icmp sgt i8 [[X:%.*]], -12179; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NNEG]])2180; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X]], [[Y:%.*]]2181; CHECK-NEXT:    ret i8 [[MUL]]2182;2183  %x.nneg = icmp sge i8 %x, 02184  call void @llvm.assume(i1 %x.nneg)2185  %mul = mul nsw i8 %x, %y2186  ret i8 %mul2187}2188 2189define i8 @mul_not_nsw_nonneg(i8 %x, i8 %y) {2190; CHECK-LABEL: @mul_not_nsw_nonneg(2191; CHECK-NEXT:    [[X_NNEG:%.*]] = icmp sgt i8 [[X:%.*]], -12192; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NNEG]])2193; CHECK-NEXT:    [[Y_NNEG:%.*]] = icmp sgt i8 [[Y:%.*]], -12194; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NNEG]])2195; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X]], [[Y]]2196; CHECK-NEXT:    ret i8 [[MUL]]2197;2198  %x.nneg = icmp sge i8 %x, 02199  call void @llvm.assume(i1 %x.nneg)2200  %y.nneg = icmp sge i8 %y, 02201  call void @llvm.assume(i1 %y.nneg)2202  %mul = mul i8 %x, %y2203  ret i8 %mul2204}2205