brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.3 KiB · 81cbc2a Raw
807 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; This test makes sure that these instructions are properly eliminated.3;4; RUN: opt < %s -passes=instcombine -S | FileCheck %s5 6declare void @use(i8)7 8define i32 @shl_C1_add_A_C2_i32(i16 %A) {9; CHECK-LABEL: @shl_C1_add_A_C2_i32(10; CHECK-NEXT:    [[B:%.*]] = zext nneg i16 [[A:%.*]] to i3211; CHECK-NEXT:    [[D:%.*]] = shl i32 192, [[B]]12; CHECK-NEXT:    ret i32 [[D]]13;14  %B = zext i16 %A to i3215  %C = add i32 %B, 516  %D = shl i32 6, %C17  ret i32 %D18}19 20define i32 @ashr_C1_add_A_C2_i32(i32 %A) {21; CHECK-LABEL: @ashr_C1_add_A_C2_i32(22; CHECK-NEXT:    ret i32 023;24  %B = and i32 %A, 6553525  %C = add i32 %B, 526  %D = ashr i32 6, %C27  ret i32 %D28}29 30define i32 @lshr_C1_add_A_C2_i32(i32 %A) {31; CHECK-LABEL: @lshr_C1_add_A_C2_i32(32; CHECK-NEXT:    [[B:%.*]] = and i32 [[A:%.*]], 6553533; CHECK-NEXT:    [[D:%.*]] = shl i32 192, [[B]]34; CHECK-NEXT:    ret i32 [[D]]35;36  %B = and i32 %A, 6553537  %C = add i32 %B, 538  %D = shl i32 6, %C39  ret i32 %D40}41 42define <4 x i32> @shl_C1_add_A_C2_v4i32(<4 x i16> %A) {43; CHECK-LABEL: @shl_C1_add_A_C2_v4i32(44; CHECK-NEXT:    [[B:%.*]] = zext nneg <4 x i16> [[A:%.*]] to <4 x i32>45; CHECK-NEXT:    [[D:%.*]] = shl <4 x i32> <i32 6, i32 4, i32 poison, i32 -458752>, [[B]]46; CHECK-NEXT:    ret <4 x i32> [[D]]47;48  %B = zext <4 x i16> %A to <4 x i32>49  %C = add <4 x i32> %B, <i32 0, i32 1, i32 50, i32 16>50  %D = shl <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %C51  ret <4 x i32> %D52}53 54define <4 x i32> @ashr_C1_add_A_C2_v4i32(<4 x i32> %A) {55; CHECK-LABEL: @ashr_C1_add_A_C2_v4i32(56; CHECK-NEXT:    [[B:%.*]] = and <4 x i32> [[A:%.*]], <i32 0, i32 15, i32 255, i32 65535>57; CHECK-NEXT:    [[D:%.*]] = ashr <4 x i32> <i32 6, i32 1, i32 poison, i32 -1>, [[B]]58; CHECK-NEXT:    ret <4 x i32> [[D]]59;60  %B = and <4 x i32> %A, <i32 0, i32 15, i32 255, i32 65535>61  %C = add <4 x i32> %B, <i32 0, i32 1, i32 50, i32 16>62  %D = ashr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %C63  ret <4 x i32> %D64}65 66define <4 x i32> @lshr_C1_add_A_C2_v4i32(<4 x i32> %A) {67; CHECK-LABEL: @lshr_C1_add_A_C2_v4i32(68; CHECK-NEXT:    [[B:%.*]] = and <4 x i32> [[A:%.*]], <i32 0, i32 15, i32 255, i32 65535>69; CHECK-NEXT:    [[D:%.*]] = lshr <4 x i32> <i32 6, i32 1, i32 poison, i32 65535>, [[B]]70; CHECK-NEXT:    ret <4 x i32> [[D]]71;72  %B = and <4 x i32> %A, <i32 0, i32 15, i32 255, i32 65535>73  %C = add <4 x i32> %B, <i32 0, i32 1, i32 50, i32 16>74  %D = lshr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %C75  ret <4 x i32> %D76}77 78define <4 x i32> @shl_C1_add_A_C2_v4i32_splat(i16 %I) {79; CHECK-LABEL: @shl_C1_add_A_C2_v4i32_splat(80; CHECK-NEXT:    [[A:%.*]] = zext i16 [[I:%.*]] to i3281; CHECK-NEXT:    [[B:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 082; CHECK-NEXT:    [[C:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> poison, <4 x i32> zeroinitializer83; CHECK-NEXT:    [[E:%.*]] = shl <4 x i32> <i32 6, i32 4, i32 poison, i32 -458752>, [[C]]84; CHECK-NEXT:    ret <4 x i32> [[E]]85;86  %A = zext i16 %I to i3287  %B = insertelement <4 x i32> undef, i32 %A, i32 088  %C = shufflevector <4 x i32> %B, <4 x i32> undef, <4 x i32> zeroinitializer89  %D = add <4 x i32> %C, <i32 0, i32 1, i32 50, i32 16>90  %E = shl <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %D91  ret <4 x i32> %E92}93 94define <4 x i32> @ashr_C1_add_A_C2_v4i32_splat(i16 %I) {95; CHECK-LABEL: @ashr_C1_add_A_C2_v4i32_splat(96; CHECK-NEXT:    [[A:%.*]] = zext i16 [[I:%.*]] to i3297; CHECK-NEXT:    [[B:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 098; CHECK-NEXT:    [[C:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> poison, <4 x i32> zeroinitializer99; CHECK-NEXT:    [[E:%.*]] = ashr <4 x i32> <i32 6, i32 1, i32 poison, i32 -1>, [[C]]100; CHECK-NEXT:    ret <4 x i32> [[E]]101;102  %A = zext i16 %I to i32103  %B = insertelement <4 x i32> undef, i32 %A, i32 0104  %C = shufflevector <4 x i32> %B, <4 x i32> undef, <4 x i32> zeroinitializer105  %D = add <4 x i32> %C, <i32 0, i32 1, i32 50, i32 16>106  %E = ashr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %D107  ret <4 x i32> %E108}109 110define <4 x i32> @lshr_C1_add_A_C2_v4i32_splat(i16 %I) {111; CHECK-LABEL: @lshr_C1_add_A_C2_v4i32_splat(112; CHECK-NEXT:    [[A:%.*]] = zext i16 [[I:%.*]] to i32113; CHECK-NEXT:    [[B:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 0114; CHECK-NEXT:    [[C:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> poison, <4 x i32> zeroinitializer115; CHECK-NEXT:    [[E:%.*]] = lshr <4 x i32> <i32 6, i32 1, i32 poison, i32 65535>, [[C]]116; CHECK-NEXT:    ret <4 x i32> [[E]]117;118  %A = zext i16 %I to i32119  %B = insertelement <4 x i32> undef, i32 %A, i32 0120  %C = shufflevector <4 x i32> %B, <4 x i32> undef, <4 x i32> zeroinitializer121  %D = add <4 x i32> %C, <i32 0, i32 1, i32 50, i32 16>122  %E = lshr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %D123  ret <4 x i32> %E124}125 126define i32 @shl_add_nuw(i32 %x) {127; CHECK-LABEL: @shl_add_nuw(128; CHECK-NEXT:    [[R:%.*]] = shl i32 192, [[X:%.*]]129; CHECK-NEXT:    ret i32 [[R]]130;131  %a = add nuw i32 %x, 5132  %r = shl i32 6, %a133  ret i32 %r134}135 136; vectors with arbitrary constants work too137 138define <2 x i12> @lshr_add_nuw(<2 x i12> %x) {139; CHECK-LABEL: @lshr_add_nuw(140; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i12> <i12 0, i12 21>, [[X:%.*]]141; CHECK-NEXT:    ret <2 x i12> [[R]]142;143  %a = add nuw <2 x i12> %x, <i12 5, i12 1>144  %r = lshr <2 x i12> <i12 6, i12 42>, %a145  ret <2 x i12> %r146}147 148; extra use is ok and in this case the result can be simplified to a constant149 150define i32 @ashr_add_nuw(i32 %x, ptr %p) {151; CHECK-LABEL: @ashr_add_nuw(152; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 5153; CHECK-NEXT:    store i32 [[A]], ptr [[P:%.*]], align 4154; CHECK-NEXT:    ret i32 -1155;156  %a = add nuw i32 %x, 5157  store i32 %a, ptr %p158  %r = ashr i32 -6, %a159  ret i32 %r160}161 162; Preserve nuw and exact flags.163 164define i32 @shl_nuw_add_nuw(i32 %x) {165; CHECK-LABEL: @shl_nuw_add_nuw(166; CHECK-NEXT:    [[R:%.*]] = shl nuw i32 2, [[X:%.*]]167; CHECK-NEXT:    ret i32 [[R]]168;169  %a = add nuw i32 %x, 1170  %r = shl nuw i32 1, %a171  ret i32 %r172}173 174define i32 @shl_nsw_add_nuw(i32 %x) {175; CHECK-LABEL: @shl_nsw_add_nuw(176; CHECK-NEXT:    [[R:%.*]] = shl nsw i32 -2, [[X:%.*]]177; CHECK-NEXT:    ret i32 [[R]]178;179  %a = add nuw i32 %x, 1180  %r = shl nsw i32 -1, %a181  ret i32 %r182}183 184define i32 @lshr_exact_add_nuw(i32 %x) {185; CHECK-LABEL: @lshr_exact_add_nuw(186; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 2, [[X:%.*]]187; CHECK-NEXT:    ret i32 [[R]]188;189  %a = add nuw i32 %x, 1190  %r = lshr exact i32 4, %a191  ret i32 %r192}193 194define i32 @ashr_exact_add_nuw(i32 %x) {195; CHECK-LABEL: @ashr_exact_add_nuw(196; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 -2, [[X:%.*]]197; CHECK-NEXT:    ret i32 [[R]]198;199  %a = add nuw i32 %x, 1200  %r = ashr exact i32 -4, %a201  ret i32 %r202}203 204; negative test - must have 'nuw'205 206define i32 @shl_add_nsw(i32 %x) {207; CHECK-LABEL: @shl_add_nsw(208; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 5209; CHECK-NEXT:    [[R:%.*]] = shl i32 6, [[A]]210; CHECK-NEXT:    ret i32 [[R]]211;212  %a = add nsw i32 %x, 5213  %r = shl i32 6, %a214  ret i32 %r215}216 217; offset precondition check (must be negative constant) for lshr_exact_add_negative_shift_positive218 219define i32 @lshr_exact_add_positive_shift_positive(i32 %x) {220; CHECK-LABEL: @lshr_exact_add_positive_shift_positive(221; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 1222; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 2, [[A]]223; CHECK-NEXT:    ret i32 [[R]]224;225  %a = add i32 %x, 1226  %r = lshr exact i32 2, %a227  ret i32 %r228}229 230define i32 @lshr_exact_add_big_negative_offset(i32 %x) {231; CHECK-LABEL: @lshr_exact_add_big_negative_offset(232; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -33233; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 2, [[A]]234; CHECK-NEXT:    ret i32 [[R]]235;236  %a = add i32 %x, -33237  %r = lshr exact i32 2, %a238  ret i32 %r239}240 241; leading zeros for shifted constant precondition check for lshr_exact_add_negative_shift_positive242 243define i32 @lshr_exact_add_negative_shift_negative(i32 %x) {244; CHECK-LABEL: @lshr_exact_add_negative_shift_negative(245; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -1246; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 -2, [[A]]247; CHECK-NEXT:    ret i32 [[R]]248;249  %a = add i32 %x, -1250  %r = lshr exact i32 -2, %a251  ret i32 %r252}253 254; exact precondition check for lshr_exact_add_negative_shift_positive255 256define i32 @lshr_add_negative_shift_no_exact(i32 %x) {257; CHECK-LABEL: @lshr_add_negative_shift_no_exact(258; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -1259; CHECK-NEXT:    [[R:%.*]] = lshr i32 2, [[A]]260; CHECK-NEXT:    ret i32 [[R]]261;262  %a = add i32 %x, -1263  %r = lshr i32 2, %a264  ret i32 %r265}266 267define i32 @lshr_exact_add_negative_shift_positive(i32 %x) {268; CHECK-LABEL: @lshr_exact_add_negative_shift_positive(269; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 4, [[X:%.*]]270; CHECK-NEXT:    ret i32 [[R]]271;272  %a = add i32 %x, -1273  %r = lshr exact i32 2, %a274  ret i32 %r275}276 277define i8 @lshr_exact_add_negative_shift_positive_extra_use(i8 %x) {278; CHECK-LABEL: @lshr_exact_add_negative_shift_positive_extra_use(279; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -1280; CHECK-NEXT:    call void @use(i8 [[A]])281; CHECK-NEXT:    [[R:%.*]] = lshr exact i8 -128, [[X]]282; CHECK-NEXT:    ret i8 [[R]]283;284  %a = add i8 %x, -1285  call void @use(i8 %a)286  %r = lshr exact i8 64, %a287  ret i8 %r288}289 290define <2 x i9> @lshr_exact_add_negative_shift_positive_vec(<2 x i9> %x) {291; CHECK-LABEL: @lshr_exact_add_negative_shift_positive_vec(292; CHECK-NEXT:    [[R:%.*]] = lshr exact <2 x i9> splat (i9 -256), [[X:%.*]]293; CHECK-NEXT:    ret <2 x i9> [[R]]294;295  %a = add <2 x i9> %x, <i9 -7, i9 -7>296  %r = lshr exact <2 x i9> <i9 2, i9 2>, %a297  ret <2 x i9> %r298}299 300; not enough leading zeros in shift constant301 302define <2 x i9> @lshr_exact_add_negative_shift_lzcnt(<2 x i9> %x) {303; CHECK-LABEL: @lshr_exact_add_negative_shift_lzcnt(304; CHECK-NEXT:    [[A:%.*]] = add <2 x i9> [[X:%.*]], splat (i9 -7)305; CHECK-NEXT:    [[R:%.*]] = lshr exact <2 x i9> splat (i9 4), [[A]]306; CHECK-NEXT:    ret <2 x i9> [[R]]307;308  %a = add <2 x i9> %x, <i9 -7, i9 -7>309  %r = lshr exact <2 x i9> <i9 4, i9 4>, %a310  ret <2 x i9> %r311}312 313; leading ones precondition check for ashr_exact_add_negative_shift_[positive,negative]314 315define i8 @ashr_exact_add_negative_shift_no_trailing_zeros(i8 %x) {316; CHECK-LABEL: @ashr_exact_add_negative_shift_no_trailing_zeros(317; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -4318; CHECK-NEXT:    [[R:%.*]] = ashr exact i8 -112, [[A]]319; CHECK-NEXT:    ret i8 [[R]]320;321  %a = add i8 %x, -4322  %r = ashr exact i8 -112, %a ; 0b1001_0000323  ret i8 %r324}325 326define i32 @ashr_exact_add_big_negative_offset(i32 %x) {327; CHECK-LABEL: @ashr_exact_add_big_negative_offset(328; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -33329; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 -2, [[A]]330; CHECK-NEXT:    ret i32 [[R]]331;332  %a = add i32 %x, -33333  %r = ashr exact i32 -2, %a334  ret i32 %r335}336 337; exact precondition check for ashr_exact_add_negative_shift_[positive,negative]338 339define i32 @ashr_add_negative_shift_no_exact(i32 %x) {340; CHECK-LABEL: @ashr_add_negative_shift_no_exact(341; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -1342; CHECK-NEXT:    [[R:%.*]] = ashr i32 -2, [[A]]343; CHECK-NEXT:    ret i32 [[R]]344;345  %a = add i32 %x, -1346  %r = ashr i32 -2, %a347  ret i32 %r348}349 350define i32 @ashr_exact_add_negative_shift_negative(i32 %x) {351; CHECK-LABEL: @ashr_exact_add_negative_shift_negative(352; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 -4, [[X:%.*]]353; CHECK-NEXT:    ret i32 [[R]]354;355  %a = add i32 %x, -1356  %r = ashr exact i32 -2, %a357  ret i32 %r358}359 360define i8 @ashr_exact_add_negative_shift_negative_extra_use(i8 %x) {361; CHECK-LABEL: @ashr_exact_add_negative_shift_negative_extra_use(362; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -2363; CHECK-NEXT:    call void @use(i8 [[A]])364; CHECK-NEXT:    [[R:%.*]] = ashr exact i8 -128, [[X]]365; CHECK-NEXT:    ret i8 [[R]]366;367  %a = add i8 %x, -2368  call void @use(i8 %a)369  %r = ashr exact i8 -32, %a370  ret i8 %r371}372 373define <2 x i7> @ashr_exact_add_negative_shift_negative_vec(<2 x i7> %x) {374; CHECK-LABEL: @ashr_exact_add_negative_shift_negative_vec(375; CHECK-NEXT:    [[R:%.*]] = ashr exact <2 x i7> splat (i7 -64), [[X:%.*]]376; CHECK-NEXT:    ret <2 x i7> [[R]]377;378  %a = add <2 x i7> %x, <i7 -5, i7 -5>379  %r = ashr exact <2 x i7> <i7 -2, i7 -2>, %a380  ret <2 x i7> %r381}382 383; not enough leading ones in shift constant384 385define <2 x i7> @ashr_exact_add_negative_leading_ones_vec(<2 x i7> %x) {386; CHECK-LABEL: @ashr_exact_add_negative_leading_ones_vec(387; CHECK-NEXT:    [[A:%.*]] = add <2 x i7> [[X:%.*]], splat (i7 -5)388; CHECK-NEXT:    [[R:%.*]] = ashr exact <2 x i7> splat (i7 -4), [[A]]389; CHECK-NEXT:    ret <2 x i7> [[R]]390;391  %a = add <2 x i7> %x, <i7 -5, i7 -5>392  %r = ashr exact <2 x i7> <i7 -4, i7 -4>, %a393  ret <2 x i7> %r394}395 396; PR54890397 398define i32 @shl_nsw_add_negative(i32 %x) {399; CHECK-LABEL: @shl_nsw_add_negative(400; CHECK-NEXT:    [[R:%.*]] = shl nuw i32 1, [[X:%.*]]401; CHECK-NEXT:    ret i32 [[R]]402;403  %a = add i32 %x, -1404  %r = shl nsw i32 2, %a405  ret i32 %r406}407 408; vectors and extra uses are allowed409; nuw propagates to the new shift410 411define <2 x i8> @shl_nuw_add_negative_splat_uses(<2 x i8> %x, ptr %p) {412; CHECK-LABEL: @shl_nuw_add_negative_splat_uses(413; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], splat (i8 -2)414; CHECK-NEXT:    store <2 x i8> [[A]], ptr [[P:%.*]], align 2415; CHECK-NEXT:    [[R:%.*]] = shl nuw <2 x i8> splat (i8 3), [[X]]416; CHECK-NEXT:    ret <2 x i8> [[R]]417;418  %a = add <2 x i8> %x, <i8 -2, i8 -2>419  store <2 x i8> %a, ptr %p420  %r = shl nuw <2 x i8> <i8 12, i8 12>, %a421  ret <2 x i8> %r422}423 424; negative test - shift constant must have enough trailing zeros to allow the pre-shift425 426define i32 @shl_nsw_add_negative_invalid_constant(i32 %x) {427; CHECK-LABEL: @shl_nsw_add_negative_invalid_constant(428; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -2429; CHECK-NEXT:    [[R:%.*]] = shl nsw i32 2, [[A]]430; CHECK-NEXT:    ret i32 [[R]]431;432  %a = add i32 %x, -2433  %r = shl nsw i32 2, %a434  ret i32 %r435}436 437; negative test - the offset constant must be negative438 439define i32 @shl_nsw_add_positive_invalid_constant(i32 %x) {440; CHECK-LABEL: @shl_nsw_add_positive_invalid_constant(441; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 2442; CHECK-NEXT:    [[R:%.*]] = shl nsw i32 4, [[A]]443; CHECK-NEXT:    ret i32 [[R]]444;445  %a = add i32 %x, 2446  %r = shl nsw i32 4, %a447  ret i32 %r448}449 450; negative test - a large shift must be detected without crashing451 452define i32 @shl_nsw_add_negative_invalid_constant2(i32 %x) {453; CHECK-LABEL: @shl_nsw_add_negative_invalid_constant2(454; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -33455; CHECK-NEXT:    [[R:%.*]] = shl nsw i32 2, [[A]]456; CHECK-NEXT:    ret i32 [[R]]457;458  %a = add i32 %x, -33459  %r = shl nsw i32 2, %a460  ret i32 %r461}462 463; negative test - currently transformed to 'xor' before we see it,464; but INT_MIN should be handled too465 466define i4 @shl_nsw_add_negative_invalid_constant3(i4 %x) {467; CHECK-LABEL: @shl_nsw_add_negative_invalid_constant3(468; CHECK-NEXT:    [[A:%.*]] = xor i4 [[X:%.*]], -8469; CHECK-NEXT:    [[R:%.*]] = shl nsw i4 2, [[A]]470; CHECK-NEXT:    ret i4 [[R]]471;472  %a = add i4 %x, 8473  %r = shl nsw i4 2, %a474  ret i4 %r475}476 477define i2 @lshr_2_add_zext_basic(i1 %a, i1 %b) {478; CHECK-LABEL: @lshr_2_add_zext_basic(479; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]480; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[TMP1]] to i2481; CHECK-NEXT:    ret i2 [[LSHR]]482;483  %zext.a = zext i1 %a to i2484  %zext.b = zext i1 %b to i2485  %add = add i2 %zext.a, %zext.b486  %lshr = lshr i2 %add, 1487  ret i2 %lshr488}489 490define i2 @ashr_2_add_zext_basic(i1 %a, i1 %b) {491; CHECK-LABEL: @ashr_2_add_zext_basic(492; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i2493; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i1 [[B:%.*]] to i2494; CHECK-NEXT:    [[ADD:%.*]] = add nuw i2 [[ZEXT_A]], [[ZEXT_B]]495; CHECK-NEXT:    [[LSHR:%.*]] = ashr i2 [[ADD]], 1496; CHECK-NEXT:    ret i2 [[LSHR]]497;498  %zext.a = zext i1 %a to i2499  %zext.b = zext i1 %b to i2500  %add = add i2 %zext.a, %zext.b501  %lshr = ashr i2 %add, 1502  ret i2 %lshr503}504 505define i32 @lshr_16_add_zext_basic(i16 %a, i16 %b) {506; CHECK-LABEL: @lshr_16_add_zext_basic(507; CHECK-NEXT:    [[TMP1:%.*]] = xor i16 [[A:%.*]], -1508; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ugt i16 [[B:%.*]], [[TMP1]]509; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i32510; CHECK-NEXT:    ret i32 [[LSHR]]511;512  %zext.a = zext i16 %a to i32513  %zext.b = zext i16 %b to i32514  %add = add i32 %zext.a, %zext.b515  %lshr = lshr i32 %add, 16516  ret i32 %lshr517}518 519define i32 @lshr_16_add_zext_basic_multiuse(i16 %a, i16 %b) {520; CHECK-LABEL: @lshr_16_add_zext_basic_multiuse(521; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i16 [[A:%.*]] to i32522; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i16 [[B:%.*]] to i32523; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]524; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[ADD]], 16525; CHECK-NEXT:    [[OTHERUSE:%.*]] = or i32 [[LSHR]], [[ZEXT_A]]526; CHECK-NEXT:    ret i32 [[OTHERUSE]]527;528  %zext.a = zext i16 %a to i32529  %zext.b = zext i16 %b to i32530  %add = add i32 %zext.a, %zext.b531  %lshr = lshr i32 %add, 16532  %otheruse = or i32 %lshr, %zext.a533  ret i32 %otheruse534}535 536define i32 @lshr_16_add_known_16_leading_zeroes(i32 %a, i32 %b) {537; CHECK-LABEL: @lshr_16_add_known_16_leading_zeroes(538; CHECK-NEXT:    [[A16:%.*]] = and i32 [[A:%.*]], 65535539; CHECK-NEXT:    [[B16:%.*]] = and i32 [[B:%.*]], 65535540; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A16]], [[B16]]541; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[ADD]], 16542; CHECK-NEXT:    ret i32 [[LSHR]]543;544  %a16 = and i32 %a, 65535 ; 0x65535545  %b16 = and i32 %b, 65535 ; 0x65535546  %add = add i32 %a16, %b16547  %lshr = lshr i32 %add, 16548  ret i32 %lshr549}550 551define i32 @lshr_16_add_not_known_16_leading_zeroes(i32 %a, i32 %b) {552; CHECK-LABEL: @lshr_16_add_not_known_16_leading_zeroes(553; CHECK-NEXT:    [[A16:%.*]] = and i32 [[A:%.*]], 131071554; CHECK-NEXT:    [[B16:%.*]] = and i32 [[B:%.*]], 65535555; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A16]], [[B16]]556; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[ADD]], 16557; CHECK-NEXT:    ret i32 [[LSHR]]558;559  %a16 = and i32 %a, 131071 ; 0x1FFFF560  %b16 = and i32 %b, 65535 ; 0x65535561  %add = add i32 %a16, %b16562  %lshr = lshr i32 %add, 16563  ret i32 %lshr564}565 566define i64 @lshr_32_add_zext_basic(i32 %a, i32 %b) {567; CHECK-LABEL: @lshr_32_add_zext_basic(568; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1569; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ugt i32 [[B:%.*]], [[TMP1]]570; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i64571; CHECK-NEXT:    ret i64 [[LSHR]]572;573  %zext.a = zext i32 %a to i64574  %zext.b = zext i32 %b to i64575  %add = add i64 %zext.a, %zext.b576  %lshr = lshr i64 %add, 32577  ret i64 %lshr578}579 580define i64 @lshr_32_add_zext_basic_multiuse(i32 %a, i32 %b) {581; CHECK-LABEL: @lshr_32_add_zext_basic_multiuse(582; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i32 [[A:%.*]] to i64583; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i32 [[B:%.*]] to i64584; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[ZEXT_A]], [[ZEXT_B]]585; CHECK-NEXT:    [[LSHR:%.*]] = lshr i64 [[ADD]], 32586; CHECK-NEXT:    [[OTHERUSE:%.*]] = or i64 [[LSHR]], [[ZEXT_B]]587; CHECK-NEXT:    ret i64 [[OTHERUSE]]588;589  %zext.a = zext i32 %a to i64590  %zext.b = zext i32 %b to i64591  %add = add i64 %zext.a, %zext.b592  %lshr = lshr i64 %add, 32593  %otheruse = or i64 %lshr, %zext.b594  ret i64 %otheruse595}596 597define i64 @lshr_31_i32_add_zext_basic(i32 %a, i32 %b) {598; CHECK-LABEL: @lshr_31_i32_add_zext_basic(599; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i32 [[A:%.*]] to i64600; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i32 [[B:%.*]] to i64601; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[ZEXT_A]], [[ZEXT_B]]602; CHECK-NEXT:    [[LSHR:%.*]] = lshr i64 [[ADD]], 31603; CHECK-NEXT:    ret i64 [[LSHR]]604;605  %zext.a = zext i32 %a to i64606  %zext.b = zext i32 %b to i64607  %add = add i64 %zext.a, %zext.b608  %lshr = lshr i64 %add, 31609  ret i64 %lshr610}611 612define i64 @lshr_33_i32_add_zext_basic(i32 %a, i32 %b) {613; CHECK-LABEL: @lshr_33_i32_add_zext_basic(614; CHECK-NEXT:    ret i64 0615;616  %zext.a = zext i32 %a to i64617  %zext.b = zext i32 %b to i64618  %add = add i64 %zext.a, %zext.b619  %lshr = lshr i64 %add, 33620  ret i64 %lshr621}622 623define i64 @lshr_16_to_64_add_zext_basic(i16 %a, i16 %b) {624; CHECK-LABEL: @lshr_16_to_64_add_zext_basic(625; CHECK-NEXT:    [[TMP1:%.*]] = xor i16 [[A:%.*]], -1626; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ugt i16 [[B:%.*]], [[TMP1]]627; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i64628; CHECK-NEXT:    ret i64 [[LSHR]]629;630  %zext.a = zext i16 %a to i64631  %zext.b = zext i16 %b to i64632  %add = add i64 %zext.a, %zext.b633  %lshr = lshr i64 %add, 16634  ret i64 %lshr635}636 637define i64 @lshr_32_add_known_32_leading_zeroes(i64 %a, i64 %b) {638; CHECK-LABEL: @lshr_32_add_known_32_leading_zeroes(639; CHECK-NEXT:    [[A32:%.*]] = and i64 [[A:%.*]], 4294967295640; CHECK-NEXT:    [[B32:%.*]] = and i64 [[B:%.*]], 4294967295641; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[A32]], [[B32]]642; CHECK-NEXT:    [[LSHR:%.*]] = lshr i64 [[ADD]], 32643; CHECK-NEXT:    ret i64 [[LSHR]]644;645  %a32 = and i64 %a, 4294967295 ; 0xFFFFFFFF646  %b32 = and i64 %b, 4294967295 ; 0xFFFFFFFF647  %add = add i64 %a32, %b32648  %lshr = lshr i64 %add, 32649  ret i64 %lshr650}651 652define i64 @lshr_32_add_not_known_32_leading_zeroes(i64 %a, i64 %b) {653;654; CHECK-LABEL: @lshr_32_add_not_known_32_leading_zeroes(655; CHECK-NEXT:    [[A32:%.*]] = and i64 [[A:%.*]], 8589934591656; CHECK-NEXT:    [[B32:%.*]] = and i64 [[B:%.*]], 4294967295657; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[A32]], [[B32]]658; CHECK-NEXT:    [[LSHR:%.*]] = lshr i64 [[ADD]], 32659; CHECK-NEXT:    ret i64 [[LSHR]]660;661  %a32 = and i64 %a, 8589934591 ; 0x1FFFFFFFF662  %b32 = and i64 %b, 4294967295 ; 0xFFFFFFFF663  %add = add i64 %a32, %b32664  %lshr = lshr i64 %add, 32665  ret i64 %lshr666}667 668define i32 @ashr_16_add_zext_basic(i16 %a, i16 %b) {669; CHECK-LABEL: @ashr_16_add_zext_basic(670; CHECK-NEXT:    [[TMP1:%.*]] = xor i16 [[A:%.*]], -1671; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ugt i16 [[B:%.*]], [[TMP1]]672; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i32673; CHECK-NEXT:    ret i32 [[LSHR]]674;675  %zext.a = zext i16 %a to i32676  %zext.b = zext i16 %b to i32677  %add = add i32 %zext.a, %zext.b678  %lshr = lshr i32 %add, 16679  ret i32 %lshr680}681 682define i64 @ashr_32_add_zext_basic(i32 %a, i32 %b) {683; CHECK-LABEL: @ashr_32_add_zext_basic(684; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1685; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ugt i32 [[B:%.*]], [[TMP1]]686; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i64687; CHECK-NEXT:    ret i64 [[LSHR]]688;689  %zext.a = zext i32 %a to i64690  %zext.b = zext i32 %b to i64691  %add = add i64 %zext.a, %zext.b692  %lshr = ashr i64 %add, 32693  ret i64 %lshr694}695 696define i64 @ashr_16_to_64_add_zext_basic(i16 %a, i16 %b) {697; CHECK-LABEL: @ashr_16_to_64_add_zext_basic(698; CHECK-NEXT:    [[TMP1:%.*]] = xor i16 [[A:%.*]], -1699; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ugt i16 [[B:%.*]], [[TMP1]]700; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i64701; CHECK-NEXT:    ret i64 [[LSHR]]702;703  %zext.a = zext i16 %a to i64704  %zext.b = zext i16 %b to i64705  %add = add i64 %zext.a, %zext.b706  %lshr = ashr i64 %add, 16707  ret i64 %lshr708}709 710define i32 @lshr_32_add_zext_trunc(i32 %a, i32 %b) {711; CHECK-LABEL: @lshr_32_add_zext_trunc(712; CHECK-NEXT:    [[ADD_NARROWED:%.*]] = add i32 [[A:%.*]], [[B:%.*]]713; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ult i32 [[ADD_NARROWED]], [[A]]714; CHECK-NEXT:    [[TRUNC_SHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i32715; CHECK-NEXT:    [[RET:%.*]] = add i32 [[ADD_NARROWED]], [[TRUNC_SHR]]716; CHECK-NEXT:    ret i32 [[RET]]717;718  %zext.a = zext i32 %a to i64719  %zext.b = zext i32 %b to i64720  %add = add i64 %zext.a, %zext.b721  %trunc.add = trunc i64 %add to i32722  %shr = lshr i64 %add, 32723  %trunc.shr = trunc i64 %shr to i32724  %ret = add i32 %trunc.add, %trunc.shr725  ret i32 %ret726}727 728define <3 x i32> @add3_i96(<3 x i32> %0, <3 x i32> %1) {729; CHECK-LABEL: @add3_i96(730; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <3 x i32> [[TMP0:%.*]], i64 0731; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <3 x i32> [[TMP1:%.*]], i64 0732; CHECK-NEXT:    [[ADD_NARROWED:%.*]] = add i32 [[TMP4]], [[TMP3]]733; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ult i32 [[ADD_NARROWED]], [[TMP4]]734; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <3 x i32> [[TMP0]], i64 1735; CHECK-NEXT:    [[TMP6:%.*]] = zext i32 [[TMP5]] to i64736; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <3 x i32> [[TMP1]], i64 1737; CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64738; CHECK-NEXT:    [[TMP9:%.*]] = add nuw nsw i64 [[TMP8]], [[TMP6]]739; CHECK-NEXT:    [[TMP10:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i64740; CHECK-NEXT:    [[TMP11:%.*]] = add nuw nsw i64 [[TMP9]], [[TMP10]]741; CHECK-NEXT:    [[TMP12:%.*]] = extractelement <3 x i32> [[TMP0]], i64 2742; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <3 x i32> [[TMP1]], i64 2743; CHECK-NEXT:    [[TMP14:%.*]] = add i32 [[TMP13]], [[TMP12]]744; CHECK-NEXT:    [[TMP15:%.*]] = lshr i64 [[TMP11]], 32745; CHECK-NEXT:    [[TMP16:%.*]] = trunc nuw nsw i64 [[TMP15]] to i32746; CHECK-NEXT:    [[TMP17:%.*]] = add i32 [[TMP14]], [[TMP16]]747; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <3 x i32> poison, i32 [[ADD_NARROWED]], i64 0748; CHECK-NEXT:    [[TMP19:%.*]] = trunc i64 [[TMP11]] to i32749; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <3 x i32> [[TMP18]], i32 [[TMP19]], i64 1750; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <3 x i32> [[TMP20]], i32 [[TMP17]], i64 2751; CHECK-NEXT:    ret <3 x i32> [[TMP21]]752;753  %3 = extractelement <3 x i32> %0, i64 0754  %4 = zext i32 %3 to i64755  %5 = extractelement <3 x i32> %1, i64 0756  %6 = zext i32 %5 to i64757  %7 = add nuw nsw i64 %6, %4758  %8 = extractelement <3 x i32> %0, i64 1759  %9 = zext i32 %8 to i64760  %10 = extractelement <3 x i32> %1, i64 1761  %11 = zext i32 %10 to i64762  %12 = add nuw nsw i64 %11, %9763  %13 = lshr i64 %7, 32764  %14 = add nuw nsw i64 %12, %13765  %15 = extractelement <3 x i32> %0, i64 2766  %16 = extractelement <3 x i32> %1, i64 2767  %17 = add i32 %16, %15768  %18 = lshr i64 %14, 32769  %19 = trunc i64 %18 to i32770  %20 = add i32 %17, %19771  %21 = trunc i64 %7 to i32772  %22 = insertelement <3 x i32> undef, i32 %21, i32 0773  %23 = trunc i64 %14 to i32774  %24 = insertelement <3 x i32> %22, i32 %23, i32 1775  %25 = insertelement <3 x i32> %24, i32 %20, i32 2776  ret <3 x i32> %25777}778 779define i8 @shl_fold_or_disjoint_cnt(i8 %x) {780; CHECK-LABEL: @shl_fold_or_disjoint_cnt(781; CHECK-NEXT:    [[R:%.*]] = shl i8 16, [[X:%.*]]782; CHECK-NEXT:    ret i8 [[R]]783;784  %a = or disjoint i8 %x, 3785  %r = shl i8 2, %a786  ret i8 %r787}788 789define <2 x i8> @ashr_fold_or_disjoint_cnt(<2 x i8> %x) {790; CHECK-LABEL: @ashr_fold_or_disjoint_cnt(791; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i8> <i8 0, i8 1>, [[X:%.*]]792; CHECK-NEXT:    ret <2 x i8> [[R]]793;794  %a = or disjoint <2 x i8> %x, <i8 3, i8 1>795  %r = ashr <2 x i8> <i8 2, i8 3>, %a796  ret <2 x i8> %r797}798 799define <2 x i8> @lshr_fold_or_disjoint_cnt_out_of_bounds(<2 x i8> %x) {800; CHECK-LABEL: @lshr_fold_or_disjoint_cnt_out_of_bounds(801; CHECK-NEXT:    ret <2 x i8> zeroinitializer802;803  %a = or disjoint <2 x i8> %x, <i8 3, i8 8>804  %r = lshr <2 x i8> <i8 2, i8 3>, %a805  ret <2 x i8> %r806}807