brintos

brintos / llvm-project-archived public Read only

0
0
Text · 46.8 KiB · ff358c6 Raw
1588 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4target datalayout = "e-m:e-i64:64-n8:16:32:64"5 6declare i32 @llvm.bswap.i32(i32)7declare i128 @llvm.bswap.i128(i128)8declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)9declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone10declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone11declare i32 @llvm.ctpop.i32(i32) nounwind readnone12declare <2 x i8> @llvm.cttz.v2i8(<2 x i8>, i1) nounwind readnone13declare <2 x i8> @llvm.ctlz.v2i8(<2 x i8>, i1) nounwind readnone14declare <2 x i8> @llvm.ctpop.v2i8(<2 x i8>) nounwind readnone15 16declare void @use(i32)17declare void @usevec(<3 x i14>)18 19define i32 @lshr_ctlz_zero_is_not_undef(i32 %x) {20; CHECK-LABEL: @lshr_ctlz_zero_is_not_undef(21; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 022; CHECK-NEXT:    [[SH:%.*]] = zext i1 [[TMP1]] to i3223; CHECK-NEXT:    ret i32 [[SH]]24;25  %ct = call i32 @llvm.ctlz.i32(i32 %x, i1 false)26  %sh = lshr i32 %ct, 527  ret i32 %sh28}29 30define i32 @lshr_cttz_zero_is_not_undef(i32 %x) {31; CHECK-LABEL: @lshr_cttz_zero_is_not_undef(32; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 033; CHECK-NEXT:    [[SH:%.*]] = zext i1 [[TMP1]] to i3234; CHECK-NEXT:    ret i32 [[SH]]35;36  %ct = call i32 @llvm.cttz.i32(i32 %x, i1 false)37  %sh = lshr i32 %ct, 538  ret i32 %sh39}40 41define i32 @lshr_ctpop(i32 %x) {42; CHECK-LABEL: @lshr_ctpop(43; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], -144; CHECK-NEXT:    [[SH:%.*]] = zext i1 [[TMP1]] to i3245; CHECK-NEXT:    ret i32 [[SH]]46;47  %ct = call i32 @llvm.ctpop.i32(i32 %x)48  %sh = lshr i32 %ct, 549  ret i32 %sh50}51 52define <2 x i8> @lshr_ctlz_zero_is_not_undef_splat_vec(<2 x i8> %x) {53; CHECK-LABEL: @lshr_ctlz_zero_is_not_undef_splat_vec(54; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer55; CHECK-NEXT:    [[SH:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>56; CHECK-NEXT:    ret <2 x i8> [[SH]]57;58  %ct = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %x, i1 false)59  %sh = lshr <2 x i8> %ct, <i8 3, i8 3>60  ret <2 x i8> %sh61}62 63define <2 x i8> @lshr_cttz_zero_is_not_undef_splat_vec(<2 x i8> %x) {64; CHECK-LABEL: @lshr_cttz_zero_is_not_undef_splat_vec(65; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer66; CHECK-NEXT:    [[SH:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>67; CHECK-NEXT:    ret <2 x i8> [[SH]]68;69  %ct = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 false)70  %sh = lshr <2 x i8> %ct, <i8 3, i8 3>71  ret <2 x i8> %sh72}73 74define <2 x i8> @lshr_ctpop_splat_vec(<2 x i8> %x) {75; CHECK-LABEL: @lshr_ctpop_splat_vec(76; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -1)77; CHECK-NEXT:    [[SH:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>78; CHECK-NEXT:    ret <2 x i8> [[SH]]79;80  %ct = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)81  %sh = lshr <2 x i8> %ct, <i8 3, i8 3>82  ret <2 x i8> %sh83}84 85define i32 @lshr_ctlz_zero_is_undef(i32 %x) {86; CHECK-LABEL: @lshr_ctlz_zero_is_undef(87; CHECK-NEXT:    ret i32 088;89  %ct = call i32 @llvm.ctlz.i32(i32 %x, i1 true)90  %sh = lshr i32 %ct, 591  ret i32 %sh92}93 94define i32 @lshr_cttz_zero_is_undef(i32 %x) {95; CHECK-LABEL: @lshr_cttz_zero_is_undef(96; CHECK-NEXT:    ret i32 097;98  %ct = call i32 @llvm.cttz.i32(i32 %x, i1 true)99  %sh = lshr i32 %ct, 5100  ret i32 %sh101}102 103define <2 x i8> @lshr_ctlz_zero_is_undef_splat_vec(<2 x i8> %x) {104; CHECK-LABEL: @lshr_ctlz_zero_is_undef_splat_vec(105; CHECK-NEXT:    ret <2 x i8> zeroinitializer106;107  %ct = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %x, i1 true)108  %sh = lshr <2 x i8> %ct, <i8 3, i8 3>109  ret <2 x i8> %sh110}111 112define i8 @lshr_ctlz_zero_is_undef_vec(<2 x i8> %x) {113; CHECK-LABEL: @lshr_ctlz_zero_is_undef_vec(114; CHECK-NEXT:    ret i8 0115;116  %ct = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %x, i1 true)117  %sh = lshr <2 x i8> %ct, <i8 3, i8 0>118  %ex = extractelement <2 x i8> %sh, i32 0119  ret i8 %ex120}121 122define <2 x i8> @lshr_cttz_zero_is_undef_splat_vec(<2 x i8> %x) {123; CHECK-LABEL: @lshr_cttz_zero_is_undef_splat_vec(124; CHECK-NEXT:    ret <2 x i8> zeroinitializer125;126  %ct = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 true)127  %sh = lshr <2 x i8> %ct, <i8 3, i8 3>128  ret <2 x i8> %sh129}130 131define i8 @lshr_cttz_zero_is_undef_vec(<2 x i8> %x) {132; CHECK-LABEL: @lshr_cttz_zero_is_undef_vec(133; CHECK-NEXT:    ret i8 0134;135  %ct = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %x, i1 true)136  %sh = lshr <2 x i8> %ct, <i8 3, i8 0>137  %ex = extractelement <2 x i8> %sh, i32 0138  ret i8 %ex139}140 141 142define i8 @lshr_exact(i8 %x) {143; CHECK-LABEL: @lshr_exact(144; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], 1145; CHECK-NEXT:    [[LSHR:%.*]] = and i8 [[TMP1]], 63146; CHECK-NEXT:    ret i8 [[LSHR]]147;148  %shl = shl i8 %x, 2149  %add = add i8 %shl, 4150  %lshr = lshr i8 %add, 2151  ret i8 %lshr152}153 154define <2 x i8> @lshr_exact_splat_vec(<2 x i8> %x) {155; CHECK-LABEL: @lshr_exact_splat_vec(156; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], splat (i8 1)157; CHECK-NEXT:    [[LSHR:%.*]] = and <2 x i8> [[TMP1]], splat (i8 63)158; CHECK-NEXT:    ret <2 x i8> [[LSHR]]159;160  %shl = shl <2 x i8> %x, <i8 2, i8 2>161  %add = add <2 x i8> %shl, <i8 4, i8 4>162  %lshr = lshr <2 x i8> %add, <i8 2, i8 2>163  ret <2 x i8> %lshr164}165 166define <2 x i8> @lshr_exact_splat_vec_nuw(<2 x i8> %x) {167; CHECK-LABEL: @lshr_exact_splat_vec_nuw(168; CHECK-NEXT:    [[LSHR:%.*]] = add nuw <2 x i8> [[X:%.*]], splat (i8 1)169; CHECK-NEXT:    ret <2 x i8> [[LSHR]]170;171  %shl = shl nuw <2 x i8> %x, <i8 2, i8 2>172  %add = add nuw <2 x i8> %shl, <i8 4, i8 4>173  %lshr = lshr <2 x i8> %add, <i8 2, i8 2>174  ret <2 x i8> %lshr175}176 177define i8 @shl_add(i8 %x, i8 %y) {178; CHECK-LABEL: @shl_add(179; CHECK-NEXT:    [[TMP1:%.*]] = lshr i8 [[Y:%.*]], 2180; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], [[X:%.*]]181; CHECK-NEXT:    [[R:%.*]] = and i8 [[TMP2]], 63182; CHECK-NEXT:    ret i8 [[R]]183;184  %l = shl i8 %x, 2185  %a = add i8 %l, %y186  %r = lshr i8 %a, 2187  ret i8 %r188}189 190define <2 x i8> @shl_add_commute_vec(<2 x i8> %x, <2 x i8> %py) {191; CHECK-LABEL: @shl_add_commute_vec(192; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], [[PY]]193; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i8> [[Y]], splat (i8 3)194; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i8> [[TMP1]], [[X:%.*]]195; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[TMP2]], splat (i8 31)196; CHECK-NEXT:    ret <2 x i8> [[R]]197;198  %y = mul <2 x i8> %py, %py ; thwart complexity-based canonicalization199  %l = shl <2 x i8> %x, <i8 3, i8 3>200  %a = add <2 x i8> %y, %l201  %r = lshr <2 x i8> %a, <i8 3, i8 3>202  ret <2 x i8> %r203}204 205define i32 @shl_add_use1(i32 %x, i32 %y) {206; CHECK-LABEL: @shl_add_use1(207; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 2208; CHECK-NEXT:    call void @use(i32 [[L]])209; CHECK-NEXT:    [[A:%.*]] = add i32 [[L]], [[Y:%.*]]210; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[A]], 2211; CHECK-NEXT:    ret i32 [[R]]212;213  %l = shl i32 %x, 2214  call void @use(i32 %l)215  %a = add i32 %l, %y216  %r = lshr i32 %a, 2217  ret i32 %r218}219 220define i32 @shl_add_use2(i32 %x, i32 %y) {221; CHECK-LABEL: @shl_add_use2(222; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 2223; CHECK-NEXT:    [[A:%.*]] = add i32 [[L]], [[Y:%.*]]224; CHECK-NEXT:    call void @use(i32 [[A]])225; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[A]], 2226; CHECK-NEXT:    ret i32 [[R]]227;228  %l = shl i32 %x, 2229  %a = add i32 %l, %y230  call void @use(i32 %a)231  %r = lshr i32 %a, 2232  ret i32 %r233}234 235define i16 @bool_zext(i1 %x) {236; CHECK-LABEL: @bool_zext(237; CHECK-NEXT:    [[HIBIT:%.*]] = zext i1 [[X:%.*]] to i16238; CHECK-NEXT:    ret i16 [[HIBIT]]239;240  %sext = sext i1 %x to i16241  %hibit = lshr i16 %sext, 15242  ret i16 %hibit243}244 245define i32 @bool_zext_use(i1 %x) {246; CHECK-LABEL: @bool_zext_use(247; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[X:%.*]] to i32248; CHECK-NEXT:    call void @use(i32 [[SEXT]])249; CHECK-NEXT:    [[HIBIT:%.*]] = zext i1 [[X]] to i32250; CHECK-NEXT:    ret i32 [[HIBIT]]251;252  %sext = sext i1 %x to i32253  call void @use(i32 %sext)254  %hibit = lshr i32 %sext, 31255  ret i32 %hibit256}257 258define <2 x i8> @bool_zext_splat(<2 x i1> %x) {259; CHECK-LABEL: @bool_zext_splat(260; CHECK-NEXT:    [[HIBIT:%.*]] = zext <2 x i1> [[X:%.*]] to <2 x i8>261; CHECK-NEXT:    ret <2 x i8> [[HIBIT]]262;263  %sext = sext <2 x i1> %x to <2 x i8>264  %hibit = lshr <2 x i8> %sext, <i8 7, i8 7>265  ret <2 x i8> %hibit266}267 268define i32 @smear_sign_and_widen(i8 %x) {269; CHECK-LABEL: @smear_sign_and_widen(270; CHECK-NEXT:    [[TMP1:%.*]] = ashr i8 [[X:%.*]], 7271; CHECK-NEXT:    [[HIBIT:%.*]] = zext i8 [[TMP1]] to i32272; CHECK-NEXT:    ret i32 [[HIBIT]]273;274  %sext = sext i8 %x to i32275  %hibit = lshr i32 %sext, 24276  ret i32 %hibit277}278 279define i16 @smear_sign_and_widen_should_not_change_type(i4 %x) {280; CHECK-LABEL: @smear_sign_and_widen_should_not_change_type(281; CHECK-NEXT:    [[SEXT:%.*]] = sext i4 [[X:%.*]] to i16282; CHECK-NEXT:    [[HIBIT:%.*]] = lshr i16 [[SEXT]], 12283; CHECK-NEXT:    ret i16 [[HIBIT]]284;285  %sext = sext i4 %x to i16286  %hibit = lshr i16 %sext, 12287  ret i16 %hibit288}289 290define <2 x i8> @smear_sign_and_widen_splat(<2 x i6> %x) {291; CHECK-LABEL: @smear_sign_and_widen_splat(292; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i6> [[X:%.*]], splat (i6 2)293; CHECK-NEXT:    [[HIBIT:%.*]] = zext <2 x i6> [[TMP1]] to <2 x i8>294; CHECK-NEXT:    ret <2 x i8> [[HIBIT]]295;296  %sext = sext <2 x i6> %x to <2 x i8>297  %hibit = lshr <2 x i8> %sext, <i8 2, i8 2>298  ret <2 x i8> %hibit299}300 301define i18 @fake_sext(i3 %x) {302; CHECK-LABEL: @fake_sext(303; CHECK-NEXT:    [[TMP1:%.*]] = lshr i3 [[X:%.*]], 2304; CHECK-NEXT:    [[SH:%.*]] = zext nneg i3 [[TMP1]] to i18305; CHECK-NEXT:    ret i18 [[SH]]306;307  %sext = sext i3 %x to i18308  %sh = lshr i18 %sext, 17309  ret i18 %sh310}311 312; Avoid the transform if it would change the shift from a legal to illegal type.313 314define i32 @fake_sext_but_should_not_change_type(i3 %x) {315; CHECK-LABEL: @fake_sext_but_should_not_change_type(316; CHECK-NEXT:    [[SEXT:%.*]] = sext i3 [[X:%.*]] to i32317; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[SEXT]], 31318; CHECK-NEXT:    ret i32 [[SH]]319;320  %sext = sext i3 %x to i32321  %sh = lshr i32 %sext, 31322  ret i32 %sh323}324 325define <2 x i8> @fake_sext_splat(<2 x i3> %x) {326; CHECK-LABEL: @fake_sext_splat(327; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i3> [[X:%.*]], splat (i3 2)328; CHECK-NEXT:    [[SH:%.*]] = zext nneg <2 x i3> [[TMP1]] to <2 x i8>329; CHECK-NEXT:    ret <2 x i8> [[SH]]330;331  %sext = sext <2 x i3> %x to <2 x i8>332  %sh = lshr <2 x i8> %sext, <i8 7, i8 7>333  ret <2 x i8> %sh334}335 336; Use a narrow shift: lshr (zext iM X to iN), C --> zext (lshr X, C) to iN337 338define <2 x i32> @narrow_lshr_constant(<2 x i8> %x, <2 x i8> %y) {339; CHECK-LABEL: @narrow_lshr_constant(340; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], splat (i8 3)341; CHECK-NEXT:    [[SH:%.*]] = zext nneg <2 x i8> [[TMP1]] to <2 x i32>342; CHECK-NEXT:    ret <2 x i32> [[SH]]343;344  %zx = zext <2 x i8> %x to <2 x i32>345  %sh = lshr <2 x i32> %zx, <i32 3, i32 3>346  ret <2 x i32> %sh347}348 349define i32 @mul_splat_fold(i32 %x) {350; CHECK-LABEL: @mul_splat_fold(351; CHECK-NEXT:    ret i32 [[X:%.*]]352;353  %m = mul nuw i32 %x, 65537354  %t = lshr i32 %m, 16355  ret i32 %t356}357 358; Vector type, extra use, weird types are all ok.359 360define <3 x i14> @mul_splat_fold_vec(<3 x i14> %x) {361; CHECK-LABEL: @mul_splat_fold_vec(362; CHECK-NEXT:    [[M:%.*]] = mul nuw <3 x i14> [[X:%.*]], splat (i14 129)363; CHECK-NEXT:    call void @usevec(<3 x i14> [[M]])364; CHECK-NEXT:    ret <3 x i14> [[X]]365;366  %m = mul nuw <3 x i14> %x, <i14 129, i14 129, i14 129>367  call void @usevec(<3 x i14> %m)368  %t = lshr <3 x i14> %m, <i14 7, i14 7, i14 7>369  ret <3 x i14> %t370}371 372define i32 @shl_add_lshr_flag_preservation(i32 %x, i32 %c, i32 %y) {373; CHECK-LABEL: @shl_add_lshr_flag_preservation(374; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]]375; CHECK-NEXT:    [[LSHR:%.*]] = add nuw nsw i32 [[TMP1]], [[X:%.*]]376; CHECK-NEXT:    ret i32 [[LSHR]]377;378  %shl = shl nuw i32 %x, %c379  %add = add nuw nsw i32 %shl, %y380  %lshr = lshr exact i32 %add, %c381  ret i32 %lshr382}383 384define i32 @shl_add_lshr(i32 %x, i32 %c, i32 %y) {385; CHECK-LABEL: @shl_add_lshr(386; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]387; CHECK-NEXT:    [[LSHR:%.*]] = add nuw i32 [[TMP1]], [[X:%.*]]388; CHECK-NEXT:    ret i32 [[LSHR]]389;390  %shl = shl nuw i32 %x, %c391  %add = add nuw i32 %shl, %y392  %lshr = lshr i32 %add, %c393  ret i32 %lshr394}395 396define i32 @shl_add_lshr_comm(i32 %x, i32 %c, i32 %y) {397; CHECK-LABEL: @shl_add_lshr_comm(398; CHECK-NEXT:    [[Y2:%.*]] = mul i32 [[Y:%.*]], [[Y]]399; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y2]], [[C:%.*]]400; CHECK-NEXT:    [[LSHR:%.*]] = add nuw i32 [[TMP1]], [[X:%.*]]401; CHECK-NEXT:    ret i32 [[LSHR]]402;403  %shl = shl nuw i32 %x, %c404  %y2 = mul i32 %y, %y ; thwart complexity-based canonicalization405  %add = add nuw i32 %y2, %shl406  %lshr = lshr i32 %add, %c407  ret i32 %lshr408}409 410; Negative test411 412define i32 @shl_add_lshr_no_nuw(i32 %x, i32 %c, i32 %y) {413; CHECK-LABEL: @shl_add_lshr_no_nuw(414; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]]415; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SHL]], [[Y:%.*]]416; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[ADD]], [[C]]417; CHECK-NEXT:    ret i32 [[LSHR]]418;419  %shl = shl nuw i32 %x, %c420  %add = add i32 %shl, %y421  %lshr = lshr i32 %add, %c422  ret i32 %lshr423}424 425; Negative test426 427define i32 @shl_sub_lshr_not_exact(i32 %x, i32 %c, i32 %y) {428; CHECK-LABEL: @shl_sub_lshr_not_exact(429; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]]430; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 [[SHL]], [[Y:%.*]]431; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[SUB]], [[C]]432; CHECK-NEXT:    ret i32 [[LSHR]]433;434  %shl = shl nuw i32 %x, %c435  %sub = sub nuw i32 %shl, %y436  %lshr = lshr i32 %sub, %c437  ret i32 %lshr438}439 440; Negative test441 442define i32 @shl_sub_lshr_no_nuw(i32 %x, i32 %c, i32 %y) {443; CHECK-LABEL: @shl_sub_lshr_no_nuw(444; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i32 [[X:%.*]], [[C:%.*]]445; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[SHL]], [[Y:%.*]]446; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 [[SUB]], [[C]]447; CHECK-NEXT:    ret i32 [[LSHR]]448;449  %shl = shl nsw i32 %x, %c450  %sub = sub nsw i32 %shl, %y451  %lshr = lshr exact i32 %sub, %c452  ret i32 %lshr453}454 455define i32 @shl_sub_lshr(i32 %x, i32 %c, i32 %y) {456; CHECK-LABEL: @shl_sub_lshr(457; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]]458; CHECK-NEXT:    [[LSHR:%.*]] = sub nuw nsw i32 [[X:%.*]], [[TMP1]]459; CHECK-NEXT:    ret i32 [[LSHR]]460;461  %shl = shl nuw i32 %x, %c462  %sub = sub nuw nsw i32 %shl, %y463  %lshr = lshr exact i32 %sub, %c464  ret i32 %lshr465}466 467define i32 @shl_sub_lshr_reverse(i32 %x, i32 %c, i32 %y) {468; CHECK-LABEL: @shl_sub_lshr_reverse(469; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]]470; CHECK-NEXT:    [[LSHR:%.*]] = sub nuw nsw i32 [[TMP1]], [[X:%.*]]471; CHECK-NEXT:    ret i32 [[LSHR]]472;473  %shl = shl nuw i32 %x, %c474  %sub = sub nuw nsw i32 %y, %shl475  %lshr = lshr exact i32 %sub, %c476  ret i32 %lshr477}478 479define i32 @shl_sub_lshr_reverse_no_nsw(i32 %x, i32 %c, i32 %y) {480; CHECK-LABEL: @shl_sub_lshr_reverse_no_nsw(481; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]]482; CHECK-NEXT:    [[LSHR:%.*]] = sub nuw i32 [[TMP1]], [[X:%.*]]483; CHECK-NEXT:    ret i32 [[LSHR]]484;485  %shl = shl nuw i32 %x, %c486  %sub = sub nuw i32 %y, %shl487  %lshr = lshr exact i32 %sub, %c488  ret i32 %lshr489}490 491define i32 @shl_sub_lshr_reverse_nsw_on_op1(i32 %x, i32 %c, i32 %y) {492; CHECK-LABEL: @shl_sub_lshr_reverse_nsw_on_op1(493; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C:%.*]]494; CHECK-NEXT:    [[LSHR:%.*]] = sub nuw i32 [[TMP1]], [[X:%.*]]495; CHECK-NEXT:    ret i32 [[LSHR]]496;497  %shl = shl nuw nsw i32 %x, %c498  %sub = sub nuw i32 %y, %shl499  %lshr = lshr exact i32 %sub, %c500  ret i32 %lshr501}502 503; Negative test504 505define i32 @shl_sub_lshr_reverse_no_exact(i32 %x, i32 %c, i32 %y) {506; CHECK-LABEL: @shl_sub_lshr_reverse_no_exact(507; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]]508; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 [[Y:%.*]], [[SHL]]509; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[SUB]], [[C]]510; CHECK-NEXT:    ret i32 [[LSHR]]511;512  %shl = shl nuw i32 %x, %c513  %sub = sub nuw nsw i32 %y, %shl514  %lshr = lshr i32 %sub, %c515  ret i32 %lshr516}517 518; Negative test519 520define i32 @shl_sub_lshr_reverse_multiuse(i32 %x, i32 %c, i32 %y) {521; CHECK-LABEL: @shl_sub_lshr_reverse_multiuse(522; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]]523; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 [[Y:%.*]], [[SHL]]524; CHECK-NEXT:    call void @use(i32 [[SUB]])525; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 [[SUB]], [[C]]526; CHECK-NEXT:    ret i32 [[LSHR]]527;528  %shl = shl nuw i32 %x, %c529  %sub = sub nuw i32 %y, %shl530  call void @use(i32 %sub)531  %lshr = lshr exact i32 %sub, %c532  ret i32 %lshr533}534 535define i32 @shl_sub_lshr_reverse_multiuse2(i32 %x, i32 %c, i32 %y) {536; CHECK-LABEL: @shl_sub_lshr_reverse_multiuse2(537; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[C:%.*]]538; CHECK-NEXT:    call void @use(i32 [[SHL]])539; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[Y:%.*]], [[C]]540; CHECK-NEXT:    [[LSHR:%.*]] = sub nuw i32 [[TMP1]], [[X]]541; CHECK-NEXT:    ret i32 [[LSHR]]542;543  %shl = shl nuw i32 %x, %c544  call void @use(i32 %shl)545  %sub = sub nuw i32 %y, %shl546  %lshr = lshr exact i32 %sub, %c547  ret i32 %lshr548}549 550; Negative test551 552define i32 @shl_sub_lshr_reverse_no_nuw(i32 %x, i32 %c, i32 %y) {553; CHECK-LABEL: @shl_sub_lshr_reverse_no_nuw(554; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], [[C:%.*]]555; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 [[Y:%.*]], [[SHL]]556; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 [[SUB]], [[C]]557; CHECK-NEXT:    ret i32 [[LSHR]]558;559  %shl = shl i32 %x, %c560  %sub = sub nuw i32 %y, %shl561  %lshr = lshr exact i32 %sub, %c562  ret i32 %lshr563}564 565; Negative test566 567define i32 @shl_sub_lshr_reverse_no_nsw_2(i32 %x, i32 %c, i32 %y) {568; CHECK-LABEL: @shl_sub_lshr_reverse_no_nsw_2(569; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i32 [[X:%.*]], [[C:%.*]]570; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[Y:%.*]], [[SHL]]571; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 [[SUB]], [[C]]572; CHECK-NEXT:    ret i32 [[LSHR]]573;574  %shl = shl nuw nsw i32 %x, %c575  %sub = sub i32 %y, %shl576  %lshr = lshr exact i32 %sub, %c577  ret i32 %lshr578}579 580define i32 @shl_or_lshr(i32 %x, i32 %c, i32 %y) {581; CHECK-LABEL: @shl_or_lshr(582; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]583; CHECK-NEXT:    [[LSHR:%.*]] = or i32 [[TMP1]], [[X:%.*]]584; CHECK-NEXT:    ret i32 [[LSHR]]585;586  %shl = shl nuw i32 %x, %c587  %or = or i32 %shl, %y588  %lshr = lshr i32 %or, %c589  ret i32 %lshr590}591 592define i32 @shl_or_disjoint_lshr(i32 %x, i32 %c, i32 %y) {593; CHECK-LABEL: @shl_or_disjoint_lshr(594; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]595; CHECK-NEXT:    [[LSHR:%.*]] = or disjoint i32 [[TMP1]], [[X:%.*]]596; CHECK-NEXT:    ret i32 [[LSHR]]597;598  %shl = shl nuw i32 %x, %c599  %or = or disjoint i32 %shl, %y600  %lshr = lshr i32 %or, %c601  ret i32 %lshr602}603 604define i32 @shl_or_lshr_comm(i32 %x, i32 %c, i32 %y) {605; CHECK-LABEL: @shl_or_lshr_comm(606; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]607; CHECK-NEXT:    [[LSHR:%.*]] = or i32 [[TMP1]], [[X:%.*]]608; CHECK-NEXT:    ret i32 [[LSHR]]609;610  %shl = shl nuw i32 %x, %c611  %or = or i32 %y, %shl612  %lshr = lshr i32 %or, %c613  ret i32 %lshr614}615 616define i32 @shl_or_disjoint_lshr_comm(i32 %x, i32 %c, i32 %y) {617; CHECK-LABEL: @shl_or_disjoint_lshr_comm(618; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]619; CHECK-NEXT:    [[LSHR:%.*]] = or disjoint i32 [[TMP1]], [[X:%.*]]620; CHECK-NEXT:    ret i32 [[LSHR]]621;622  %shl = shl nuw i32 %x, %c623  %or = or disjoint i32 %y, %shl624  %lshr = lshr i32 %or, %c625  ret i32 %lshr626}627 628define i32 @shl_xor_lshr(i32 %x, i32 %c, i32 %y) {629; CHECK-LABEL: @shl_xor_lshr(630; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]631; CHECK-NEXT:    [[LSHR:%.*]] = xor i32 [[TMP1]], [[X:%.*]]632; CHECK-NEXT:    ret i32 [[LSHR]]633;634  %shl = shl nuw i32 %x, %c635  %xor = xor i32 %shl, %y636  %lshr = lshr i32 %xor, %c637  ret i32 %lshr638}639 640define i32 @shl_xor_lshr_comm(i32 %x, i32 %c, i32 %y) {641; CHECK-LABEL: @shl_xor_lshr_comm(642; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]643; CHECK-NEXT:    [[LSHR:%.*]] = xor i32 [[TMP1]], [[X:%.*]]644; CHECK-NEXT:    ret i32 [[LSHR]]645;646  %shl = shl nuw i32 %x, %c647  %xor = xor i32 %y, %shl648  %lshr = lshr i32 %xor, %c649  ret i32 %lshr650}651 652define i32 @shl_and_lshr(i32 %x, i32 %c, i32 %y) {653; CHECK-LABEL: @shl_and_lshr(654; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]655; CHECK-NEXT:    [[LSHR:%.*]] = and i32 [[TMP1]], [[X:%.*]]656; CHECK-NEXT:    ret i32 [[LSHR]]657;658  %shl = shl nuw i32 %x, %c659  %and = and i32 %shl, %y660  %lshr = lshr i32 %and, %c661  ret i32 %lshr662}663 664define i32 @shl_and_lshr_comm(i32 %x, i32 %c, i32 %y) {665; CHECK-LABEL: @shl_and_lshr_comm(666; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]667; CHECK-NEXT:    [[LSHR:%.*]] = and i32 [[TMP1]], [[X:%.*]]668; CHECK-NEXT:    ret i32 [[LSHR]]669;670  %shl = shl nuw i32 %x, %c671  %and = and i32 %y, %shl672  %lshr = lshr i32 %and, %c673  ret i32 %lshr674}675 676define i32 @shl_lshr_and_exact(i32 %x, i32 %c, i32 %y) {677; CHECK-LABEL: @shl_lshr_and_exact(678; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], [[C:%.*]]679; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]680; CHECK-NEXT:    ret i32 [[TMP2]]681;682  %2 = shl nuw i32 %x, %c683  %3 = and i32 %2, %y684  %4 = lshr exact i32 %3, %c685  ret i32 %4686}687 688; Negative test689 690define i32 @shl_add_lshr_neg(i32 %x, i32 %y, i32 %z) {691; CHECK-LABEL: @shl_add_lshr_neg(692; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[Y:%.*]]693; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[SHL]], [[Z:%.*]]694; CHECK-NEXT:    [[RES:%.*]] = lshr exact i32 [[ADD]], [[Z]]695; CHECK-NEXT:    ret i32 [[RES]]696;697  %shl = shl nuw i32 %x, %y698  %add = add nuw nsw i32 %shl, %z699  %res = lshr exact i32 %add, %z700  ret i32 %res701}702 703define i32 @mul_splat_fold_wrong_mul_const(i32 %x) {704; CHECK-LABEL: @mul_splat_fold_wrong_mul_const(705; CHECK-NEXT:    [[M:%.*]] = mul nuw i32 [[X:%.*]], 65538706; CHECK-NEXT:    [[T:%.*]] = lshr i32 [[M]], 16707; CHECK-NEXT:    ret i32 [[T]]708;709  %m = mul nuw i32 %x, 65538710  %t = lshr i32 %m, 16711  ret i32 %t712}713 714; Negative test715 716define i32 @shl_add_lshr_multiuse(i32 %x, i32 %y, i32 %z) {717; CHECK-LABEL: @shl_add_lshr_multiuse(718; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[Y:%.*]]719; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[SHL]], [[Z:%.*]]720; CHECK-NEXT:    call void @use(i32 [[ADD]])721; CHECK-NEXT:    [[RES:%.*]] = lshr exact i32 [[ADD]], [[Z]]722; CHECK-NEXT:    ret i32 [[RES]]723;724  %shl = shl nuw i32 %x, %y725  %add = add nuw nsw i32 %shl, %z726  call void @use (i32 %add)727  %res = lshr exact i32 %add, %z728  ret i32 %res729}730 731define i32 @mul_splat_fold_wrong_lshr_const(i32 %x) {732; CHECK-LABEL: @mul_splat_fold_wrong_lshr_const(733; CHECK-NEXT:    [[M:%.*]] = mul nuw i32 [[X:%.*]], 65537734; CHECK-NEXT:    [[T:%.*]] = lshr i32 [[M]], 15735; CHECK-NEXT:    ret i32 [[T]]736;737  %m = mul nuw i32 %x, 65537738  %t = lshr i32 %m, 15739  ret i32 %t740}741 742define i32 @mul_splat_fold_no_nuw(i32 %x) {743; CHECK-LABEL: @mul_splat_fold_no_nuw(744; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 16745; CHECK-NEXT:    [[T:%.*]] = add nsw i32 [[X]], [[TMP1]]746; CHECK-NEXT:    ret i32 [[T]]747;748  %m = mul nsw i32 %x, 65537749  %t = lshr i32 %m, 16750  ret i32 %t751}752 753; Negative test754 755define i32 @mul_splat_fold_no_flags(i32 %x) {756; CHECK-LABEL: @mul_splat_fold_no_flags(757; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X:%.*]], 65537758; CHECK-NEXT:    [[T:%.*]] = lshr i32 [[M]], 16759; CHECK-NEXT:    ret i32 [[T]]760;761  %m = mul i32 %x, 65537762  %t = lshr i32 %m, 16763  ret i32 %t764}765 766; Negative test (but simplifies before we reach the mul_splat transform)- need more than 2 bits767 768define i2 @mul_splat_fold_too_narrow(i2 %x) {769; CHECK-LABEL: @mul_splat_fold_too_narrow(770; CHECK-NEXT:    ret i2 [[X:%.*]]771;772  %m = mul nuw i2 %x, 2773  %t = lshr i2 %m, 1774  ret i2 %t775}776 777define i32 @negative_and_odd(i32 %x) {778; CHECK-LABEL: @negative_and_odd(779; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31780; CHECK-NEXT:    [[R:%.*]] = and i32 [[TMP1]], [[X]]781; CHECK-NEXT:    ret i32 [[R]]782;783  %s = srem i32 %x, 2784  %r = lshr i32 %s, 31785  ret i32 %r786}787 788define <2 x i7> @negative_and_odd_vec(<2 x i7> %x) {789; CHECK-LABEL: @negative_and_odd_vec(790; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i7> [[X:%.*]], splat (i7 6)791; CHECK-NEXT:    [[R:%.*]] = and <2 x i7> [[TMP1]], [[X]]792; CHECK-NEXT:    ret <2 x i7> [[R]]793;794  %s = srem <2 x i7> %x, <i7 2, i7 2>795  %r = lshr <2 x i7> %s, <i7 6, i7 6>796  ret <2 x i7> %r797}798 799; Negative test - this is still worth trying to avoid srem?800 801define i32 @negative_and_odd_uses(i32 %x, ptr %p) {802; CHECK-LABEL: @negative_and_odd_uses(803; CHECK-NEXT:    [[S:%.*]] = srem i32 [[X:%.*]], 2804; CHECK-NEXT:    store i32 [[S]], ptr [[P:%.*]], align 4805; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[S]], 31806; CHECK-NEXT:    ret i32 [[R]]807;808  %s = srem i32 %x, 2809  store i32 %s, ptr %p810  %r = lshr i32 %s, 31811  ret i32 %r812}813 814; Negative test - wrong divisor815 816define i32 @srem3(i32 %x) {817; CHECK-LABEL: @srem3(818; CHECK-NEXT:    [[S:%.*]] = srem i32 [[X:%.*]], 3819; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[S]], 31820; CHECK-NEXT:    ret i32 [[R]]821;822  %s = srem i32 %x, 3823  %r = lshr i32 %s, 31824  ret i32 %r825}826 827; Negative test - wrong shift amount828 829define i32 @srem2_lshr30(i32 %x) {830; CHECK-LABEL: @srem2_lshr30(831; CHECK-NEXT:    [[S:%.*]] = srem i32 [[X:%.*]], 2832; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[S]], 30833; CHECK-NEXT:    ret i32 [[R]]834;835  %s = srem i32 %x, 2836  %r = lshr i32 %s, 30837  ret i32 %r838}839 840define i12 @trunc_sandwich(i32 %x) {841; CHECK-LABEL: @trunc_sandwich(842; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X:%.*]], 30843; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i12844; CHECK-NEXT:    ret i12 [[R1]]845;846  %sh = lshr i32 %x, 28847  %tr = trunc i32 %sh to i12848  %r = lshr i12 %tr, 2849  ret i12 %r850}851 852define <2 x i12> @trunc_sandwich_splat_vec(<2 x i32> %x) {853; CHECK-LABEL: @trunc_sandwich_splat_vec(854; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 30)855; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw <2 x i32> [[SUM_SHIFT]] to <2 x i12>856; CHECK-NEXT:    ret <2 x i12> [[R1]]857;858  %sh = lshr <2 x i32> %x, <i32 22, i32 22>859  %tr = trunc <2 x i32> %sh to <2 x i12>860  %r = lshr <2 x i12> %tr, <i12 8, i12 8>861  ret <2 x i12> %r862}863 864define i12 @trunc_sandwich_min_shift1(i32 %x) {865; CHECK-LABEL: @trunc_sandwich_min_shift1(866; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X:%.*]], 21867; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i12868; CHECK-NEXT:    ret i12 [[R1]]869;870  %sh = lshr i32 %x, 20871  %tr = trunc i32 %sh to i12872  %r = lshr i12 %tr, 1873  ret i12 %r874}875 876define i12 @trunc_sandwich_small_shift1(i32 %x) {877; CHECK-LABEL: @trunc_sandwich_small_shift1(878; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X:%.*]], 20879; CHECK-NEXT:    [[R1:%.*]] = trunc nuw i32 [[SUM_SHIFT]] to i12880; CHECK-NEXT:    [[R:%.*]] = and i12 [[R1]], 2047881; CHECK-NEXT:    ret i12 [[R]]882;883  %sh = lshr i32 %x, 19884  %tr = trunc i32 %sh to i12885  %r = lshr i12 %tr, 1886  ret i12 %r887}888 889define i12 @trunc_sandwich_max_sum_shift(i32 %x) {890; CHECK-LABEL: @trunc_sandwich_max_sum_shift(891; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X:%.*]], 31892; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i12893; CHECK-NEXT:    ret i12 [[R1]]894;895  %sh = lshr i32 %x, 20896  %tr = trunc i32 %sh to i12897  %r = lshr i12 %tr, 11898  ret i12 %r899}900 901define i12 @trunc_sandwich_max_sum_shift2(i32 %x) {902; CHECK-LABEL: @trunc_sandwich_max_sum_shift2(903; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X:%.*]], 31904; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i12905; CHECK-NEXT:    ret i12 [[R1]]906;907  %sh = lshr i32 %x, 30908  %tr = trunc i32 %sh to i12909  %r = lshr i12 %tr, 1910  ret i12 %r911}912 913define i12 @trunc_sandwich_big_sum_shift1(i32 %x) {914; CHECK-LABEL: @trunc_sandwich_big_sum_shift1(915; CHECK-NEXT:    ret i12 0916;917  %sh = lshr i32 %x, 21918  %tr = trunc i32 %sh to i12919  %r = lshr i12 %tr, 11920  ret i12 %r921}922 923define i12 @trunc_sandwich_big_sum_shift2(i32 %x) {924; CHECK-LABEL: @trunc_sandwich_big_sum_shift2(925; CHECK-NEXT:    ret i12 0926;927  %sh = lshr i32 %x, 31928  %tr = trunc i32 %sh to i12929  %r = lshr i12 %tr, 1930  ret i12 %r931}932 933define i12 @trunc_sandwich_use1(i32 %x) {934; CHECK-LABEL: @trunc_sandwich_use1(935; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 28936; CHECK-NEXT:    call void @use(i32 [[SH]])937; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X]], 30938; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i12939; CHECK-NEXT:    ret i12 [[R1]]940;941  %sh = lshr i32 %x, 28942  call void @use(i32 %sh)943  %tr = trunc i32 %sh to i12944  %r = lshr i12 %tr, 2945  ret i12 %r946}947 948define <3 x i9> @trunc_sandwich_splat_vec_use1(<3 x i14> %x) {949; CHECK-LABEL: @trunc_sandwich_splat_vec_use1(950; CHECK-NEXT:    [[SH:%.*]] = lshr <3 x i14> [[X:%.*]], splat (i14 6)951; CHECK-NEXT:    call void @usevec(<3 x i14> [[SH]])952; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr <3 x i14> [[X]], splat (i14 11)953; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw <3 x i14> [[SUM_SHIFT]] to <3 x i9>954; CHECK-NEXT:    ret <3 x i9> [[R1]]955;956  %sh = lshr <3 x i14> %x, <i14 6, i14 6, i14 6>957  call void @usevec(<3 x i14> %sh)958  %tr = trunc <3 x i14> %sh to <3 x i9>959  %r = lshr <3 x i9> %tr, <i9 5, i9 5, i9 5>960  ret <3 x i9> %r961}962 963define i12 @trunc_sandwich_min_shift1_use1(i32 %x) {964; CHECK-LABEL: @trunc_sandwich_min_shift1_use1(965; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 20966; CHECK-NEXT:    call void @use(i32 [[SH]])967; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X]], 21968; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i12969; CHECK-NEXT:    ret i12 [[R1]]970;971  %sh = lshr i32 %x, 20972  call void @use(i32 %sh)973  %tr = trunc i32 %sh to i12974  %r = lshr i12 %tr, 1975  ret i12 %r976}977 978; negative test - trunc is bigger than first shift979 980define i12 @trunc_sandwich_small_shift1_use1(i32 %x) {981; CHECK-LABEL: @trunc_sandwich_small_shift1_use1(982; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 19983; CHECK-NEXT:    call void @use(i32 [[SH]])984; CHECK-NEXT:    [[TR:%.*]] = trunc i32 [[SH]] to i12985; CHECK-NEXT:    [[R:%.*]] = lshr i12 [[TR]], 1986; CHECK-NEXT:    ret i12 [[R]]987;988  %sh = lshr i32 %x, 19989  call void @use(i32 %sh)990  %tr = trunc i32 %sh to i12991  %r = lshr i12 %tr, 1992  ret i12 %r993}994 995define i12 @trunc_sandwich_max_sum_shift_use1(i32 %x) {996; CHECK-LABEL: @trunc_sandwich_max_sum_shift_use1(997; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 20998; CHECK-NEXT:    call void @use(i32 [[SH]])999; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X]], 311000; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i121001; CHECK-NEXT:    ret i12 [[R1]]1002;1003  %sh = lshr i32 %x, 201004  call void @use(i32 %sh)1005  %tr = trunc i32 %sh to i121006  %r = lshr i12 %tr, 111007  ret i12 %r1008}1009 1010define i12 @trunc_sandwich_max_sum_shift2_use1(i32 %x) {1011; CHECK-LABEL: @trunc_sandwich_max_sum_shift2_use1(1012; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 301013; CHECK-NEXT:    call void @use(i32 [[SH]])1014; CHECK-NEXT:    [[SUM_SHIFT:%.*]] = lshr i32 [[X]], 311015; CHECK-NEXT:    [[R1:%.*]] = trunc nuw nsw i32 [[SUM_SHIFT]] to i121016; CHECK-NEXT:    ret i12 [[R1]]1017;1018  %sh = lshr i32 %x, 301019  call void @use(i32 %sh)1020  %tr = trunc i32 %sh to i121021  %r = lshr i12 %tr, 11022  ret i12 %r1023}1024 1025; negative test - but overshift is simplified to zero by another fold1026 1027define i12 @trunc_sandwich_big_sum_shift1_use1(i32 %x) {1028; CHECK-LABEL: @trunc_sandwich_big_sum_shift1_use1(1029; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 211030; CHECK-NEXT:    call void @use(i32 [[SH]])1031; CHECK-NEXT:    ret i12 01032;1033  %sh = lshr i32 %x, 211034  call void @use(i32 %sh)1035  %tr = trunc i32 %sh to i121036  %r = lshr i12 %tr, 111037  ret i12 %r1038}1039 1040; negative test - but overshift is simplified to zero by another fold1041 1042define i12 @trunc_sandwich_big_sum_shift2_use1(i32 %x) {1043; CHECK-LABEL: @trunc_sandwich_big_sum_shift2_use1(1044; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 311045; CHECK-NEXT:    call void @use(i32 [[SH]])1046; CHECK-NEXT:    ret i12 01047;1048  %sh = lshr i32 %x, 311049  call void @use(i32 %sh)1050  %tr = trunc i32 %sh to i121051  %r = lshr i12 %tr, 11052  ret i12 %r1053}1054 1055define i16 @lshr_sext_i1_to_i16(i1 %a) {1056; CHECK-LABEL: @lshr_sext_i1_to_i16(1057; CHECK-NEXT:    [[LSHR:%.*]] = select i1 [[A:%.*]], i16 4095, i16 01058; CHECK-NEXT:    ret i16 [[LSHR]]1059;1060  %sext = sext i1 %a to i161061  %lshr = lshr i16 %sext, 41062  ret i16 %lshr1063}1064 1065define i128 @lshr_sext_i1_to_i128(i1 %a) {1066; CHECK-LABEL: @lshr_sext_i1_to_i128(1067; CHECK-NEXT:    [[LSHR:%.*]] = select i1 [[A:%.*]], i128 77371252455336267181195263, i128 01068; CHECK-NEXT:    ret i128 [[LSHR]]1069;1070  %sext = sext i1 %a to i1281071  %lshr = lshr i128 %sext, 421072  ret i128 %lshr1073}1074 1075define i32 @lshr_sext_i1_to_i32_use(i1 %a) {1076; CHECK-LABEL: @lshr_sext_i1_to_i32_use(1077; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[A:%.*]] to i321078; CHECK-NEXT:    call void @use(i32 [[SEXT]])1079; CHECK-NEXT:    [[LSHR:%.*]] = select i1 [[A]], i32 262143, i32 01080; CHECK-NEXT:    ret i32 [[LSHR]]1081;1082  %sext = sext i1 %a to i321083  call void @use(i32 %sext)1084  %lshr = lshr i32 %sext, 141085  ret i32 %lshr1086}1087 1088define <3 x i14> @lshr_sext_i1_to_i14_splat_vec_use1(<3 x i1> %a) {1089; CHECK-LABEL: @lshr_sext_i1_to_i14_splat_vec_use1(1090; CHECK-NEXT:    [[SEXT:%.*]] = sext <3 x i1> [[A:%.*]] to <3 x i14>1091; CHECK-NEXT:    call void @usevec(<3 x i14> [[SEXT]])1092; CHECK-NEXT:    [[LSHR:%.*]] = select <3 x i1> [[A]], <3 x i14> splat (i14 1023), <3 x i14> zeroinitializer1093; CHECK-NEXT:    ret <3 x i14> [[LSHR]]1094;1095  %sext = sext <3 x i1> %a to <3 x i14>1096  call void @usevec(<3 x i14> %sext)1097  %lshr = lshr <3 x i14> %sext, <i14 4, i14 4, i14 4>1098  ret <3 x i14> %lshr1099}1100 1101define i1 @icmp_ule(i32 %x, i32 %y) {1102; CHECK-LABEL: @icmp_ule(1103; CHECK-NEXT:    ret i1 true1104;1105  %x.shifted = lshr i32 %x, %y1106  %cmp = icmp ule i32 %x.shifted, %x1107  ret i1 %cmp1108}1109 1110define i1 @icmp_ult(i32 %x, i32 %y) {1111; CHECK-LABEL: @icmp_ult(1112; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1113; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X_SHIFTED]], [[X]]1114; CHECK-NEXT:    ret i1 [[CMP]]1115;1116  %x.shifted = lshr i32 %x, %y1117  %cmp = icmp ult i32 %x.shifted, %x1118  ret i1 %cmp1119}1120 1121define i1 @icmp_eq(i32 %x, i32 %y) {1122; CHECK-LABEL: @icmp_eq(1123; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1124; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X_SHIFTED]], [[X]]1125; CHECK-NEXT:    ret i1 [[CMP]]1126;1127  %x.shifted = lshr i32 %x, %y1128  %cmp = icmp eq i32 %x.shifted, %x1129  ret i1 %cmp1130}1131 1132define i1 @icmp_ne(i32 %x, i32 %y) {1133; CHECK-LABEL: @icmp_ne(1134; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1135; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X_SHIFTED]], [[X]]1136; CHECK-NEXT:    ret i1 [[CMP]]1137;1138  %x.shifted = lshr i32 %x, %y1139  %cmp = icmp ne i32 %x.shifted, %x1140  ret i1 %cmp1141}1142 1143define i1 @icmp_ugt(i32 %x, i32 %y) {1144; CHECK-LABEL: @icmp_ugt(1145; CHECK-NEXT:    ret i1 false1146;1147  %x.shifted = lshr i32 %x, %y1148  %cmp = icmp ugt i32 %x.shifted, %x1149  ret i1 %cmp1150}1151 1152define i1 @icmp_uge(i32 %x, i32 %y) {1153; CHECK-LABEL: @icmp_uge(1154; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1155; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X_SHIFTED]], [[X]]1156; CHECK-NEXT:    ret i1 [[CMP]]1157;1158  %x.shifted = lshr i32 %x, %y1159  %cmp = icmp uge i32 %x.shifted, %x1160  ret i1 %cmp1161}1162 1163define i1 @icmp_sle(i32 %x, i32 %y) {1164; CHECK-LABEL: @icmp_sle(1165; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1166; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X_SHIFTED]], [[X]]1167; CHECK-NEXT:    ret i1 [[CMP]]1168;1169  %x.shifted = lshr i32 %x, %y1170  %cmp = icmp sle i32 %x.shifted, %x1171  ret i1 %cmp1172}1173 1174define i1 @icmp_slt(i32 %x, i32 %y) {1175; CHECK-LABEL: @icmp_slt(1176; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1177; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X_SHIFTED]], [[X]]1178; CHECK-NEXT:    ret i1 [[CMP]]1179;1180  %x.shifted = lshr i32 %x, %y1181  %cmp = icmp slt i32 %x.shifted, %x1182  ret i1 %cmp1183}1184 1185define i1 @icmp_sgt(i32 %x, i32 %y) {1186; CHECK-LABEL: @icmp_sgt(1187; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1188; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X_SHIFTED]], [[X]]1189; CHECK-NEXT:    ret i1 [[CMP]]1190;1191  %x.shifted = lshr i32 %x, %y1192  %cmp = icmp sgt i32 %x.shifted, %x1193  ret i1 %cmp1194}1195 1196define i1 @icmp_sge(i32 %x, i32 %y) {1197; CHECK-LABEL: @icmp_sge(1198; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]1199; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[X_SHIFTED]], [[X]]1200; CHECK-NEXT:    ret i1 [[CMP]]1201;1202  %x.shifted = lshr i32 %x, %y1203  %cmp = icmp sge i32 %x.shifted, %x1204  ret i1 %cmp1205}1206 1207define i32 @narrow_bswap(i16 %x) {1208; CHECK-LABEL: @narrow_bswap(1209; CHECK-NEXT:    [[TMP1:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])1210; CHECK-NEXT:    [[S:%.*]] = zext i16 [[TMP1]] to i321211; CHECK-NEXT:    ret i32 [[S]]1212;1213  %z = zext i16 %x to i321214  %b = call i32 @llvm.bswap.i32(i32 %z)1215  %s = lshr i32 %b, 161216  ret i32 %s1217}1218 1219define i128 @narrow_bswap_extra_wide(i16 %x) {1220; CHECK-LABEL: @narrow_bswap_extra_wide(1221; CHECK-NEXT:    [[TMP1:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])1222; CHECK-NEXT:    [[S:%.*]] = zext i16 [[TMP1]] to i1281223; CHECK-NEXT:    ret i128 [[S]]1224;1225  %z = zext i16 %x to i1281226  %b = call i128 @llvm.bswap.i128(i128 %z)1227  %s = lshr i128 %b, 1121228  ret i128 %s1229}1230 1231define i32 @narrow_bswap_undershift(i16 %x) {1232; CHECK-LABEL: @narrow_bswap_undershift(1233; CHECK-NEXT:    [[TMP1:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])1234; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[TMP1]] to i321235; CHECK-NEXT:    [[S:%.*]] = shl nuw nsw i32 [[TMP2]], 71236; CHECK-NEXT:    ret i32 [[S]]1237;1238  %z = zext i16 %x to i321239  %b = call i32 @llvm.bswap.i32(i32 %z)1240  %s = lshr i32 %b, 91241  ret i32 %s1242}1243 1244define <2 x i64> @narrow_bswap_splat(<2 x i16> %x) {1245; CHECK-LABEL: @narrow_bswap_splat(1246; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[X:%.*]])1247; CHECK-NEXT:    [[S:%.*]] = zext <2 x i16> [[TMP1]] to <2 x i64>1248; CHECK-NEXT:    ret <2 x i64> [[S]]1249;1250  %z = zext <2 x i16> %x to <2 x i64>1251  %b = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %z)1252  %s = lshr <2 x i64> %b, <i64 48, i64 48>1253  ret <2 x i64> %s1254}1255 1256define <2 x i64> @narrow_bswap_splat_poison_elt(<2 x i16> %x) {1257; CHECK-LABEL: @narrow_bswap_splat_poison_elt(1258; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i64>1259; CHECK-NEXT:    [[B:%.*]] = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> [[Z]])1260; CHECK-NEXT:    [[S:%.*]] = lshr exact <2 x i64> [[B]], <i64 48, i64 poison>1261; CHECK-NEXT:    ret <2 x i64> [[S]]1262;1263  %z = zext <2 x i16> %x to <2 x i64>1264  %b = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %z)1265  %s = lshr <2 x i64> %b, <i64 48, i64 poison>1266  ret <2 x i64> %s1267}1268 1269define <2 x i64> @narrow_bswap_overshift(<2 x i32> %x) {1270; CHECK-LABEL: @narrow_bswap_overshift(1271; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[X:%.*]])1272; CHECK-NEXT:    [[TMP2:%.*]] = lshr <2 x i32> [[TMP1]], splat (i32 16)1273; CHECK-NEXT:    [[S:%.*]] = zext nneg <2 x i32> [[TMP2]] to <2 x i64>1274; CHECK-NEXT:    ret <2 x i64> [[S]]1275;1276  %z = zext <2 x i32> %x to <2 x i64>1277  %b = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %z)1278  %s = lshr <2 x i64> %b, <i64 48, i64 48>1279  ret <2 x i64> %s1280}1281 1282define i128 @narrow_bswap_overshift2(i96 %x) {1283; CHECK-LABEL: @narrow_bswap_overshift2(1284; CHECK-NEXT:    [[TMP1:%.*]] = call i96 @llvm.bswap.i96(i96 [[X:%.*]])1285; CHECK-NEXT:    [[TMP2:%.*]] = lshr i96 [[TMP1]], 291286; CHECK-NEXT:    [[S:%.*]] = zext nneg i96 [[TMP2]] to i1281287; CHECK-NEXT:    ret i128 [[S]]1288;1289  %z = zext i96 %x to i1281290  %b = call i128 @llvm.bswap.i128(i128 %z)1291  %s = lshr i128 %b, 611292  ret i128 %s1293}1294 1295; negative test - can't make a bswap with an odd number of bytes1296 1297define i32 @not_narrow_bswap(i24 %x) {1298; CHECK-LABEL: @not_narrow_bswap(1299; CHECK-NEXT:    [[Z:%.*]] = zext i24 [[X:%.*]] to i321300; CHECK-NEXT:    [[B:%.*]] = call i32 @llvm.bswap.i32(i32 [[Z]])1301; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 [[B]], 81302; CHECK-NEXT:    ret i32 [[R]]1303;1304  %z = zext i24 %x to i321305  %b = call i32 @llvm.bswap.i32(i32 %z)1306  %r = lshr i32 %b, 81307  ret i32 %r1308}1309 1310define i8 @not_signbit(i8 %x) {1311; CHECK-LABEL: @not_signbit(1312; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -11313; CHECK-NEXT:    [[R:%.*]] = zext i1 [[ISNOTNEG]] to i81314; CHECK-NEXT:    ret i8 [[R]]1315;1316  %a = xor i8 %x, -11317  %r = lshr i8 %a, 71318  ret i8 %r1319}1320 1321define <2 x i6> @not_signbit_vec(<2 x i6> %x) {1322; CHECK-LABEL: @not_signbit_vec(1323; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], splat (i6 -1)1324; CHECK-NEXT:    [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>1325; CHECK-NEXT:    ret <2 x i6> [[R]]1326;1327  %a = xor <2 x i6> %x, <i6 -1, i6 poison>1328  %r = lshr <2 x i6> %a, <i6 5, i6 poison>1329  ret <2 x i6> %r1330}1331 1332define i8 @not_signbit_alt_xor(i8 %x) {1333; CHECK-LABEL: @not_signbit_alt_xor(1334; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -11335; CHECK-NEXT:    [[R:%.*]] = zext i1 [[ISNOTNEG]] to i81336; CHECK-NEXT:    ret i8 [[R]]1337;1338  %a = xor i8 %x, -21339  %r = lshr i8 %a, 71340  ret i8 %r1341}1342 1343define i8 @not_not_signbit(i8 %x) {1344; CHECK-LABEL: @not_not_signbit(1345; CHECK-NEXT:    [[A:%.*]] = xor i8 [[X:%.*]], -11346; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[A]], 61347; CHECK-NEXT:    ret i8 [[R]]1348;1349  %a = xor i8 %x, -11350  %r = lshr i8 %a, 61351  ret i8 %r1352}1353 1354define i32 @not_signbit_use(i32 %x) {1355; CHECK-LABEL: @not_signbit_use(1356; CHECK-NEXT:    [[A:%.*]] = xor i32 [[X:%.*]], -11357; CHECK-NEXT:    call void @use(i32 [[A]])1358; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[A]], 311359; CHECK-NEXT:    ret i32 [[R]]1360;1361  %a = xor i32 %x, -11362  call void @use(i32 %a)1363  %r = lshr i32 %a, 311364  ret i32 %r1365}1366 1367define i32 @not_signbit_zext(i16 %x) {1368; CHECK-LABEL: @not_signbit_zext(1369; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i16 [[X:%.*]], -11370; CHECK-NEXT:    [[R2:%.*]] = zext i1 [[ISNOTNEG]] to i321371; CHECK-NEXT:    ret i32 [[R2]]1372;1373  %a = xor i16 %x, -11374  %r = lshr i16 %a, 151375  %r2 = zext i16 %r to i321376  ret i32 %r21377}1378 1379define i8 @not_signbit_trunc(i16 %x) {1380; CHECK-LABEL: @not_signbit_trunc(1381; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i16 [[X:%.*]], -11382; CHECK-NEXT:    [[R2:%.*]] = zext i1 [[ISNOTNEG]] to i81383; CHECK-NEXT:    ret i8 [[R2]]1384;1385  %a = xor i16 %x, -11386  %r = lshr i16 %a, 151387  %r2 = trunc i16 %r to i81388  ret i8 %r21389}1390 1391define i2 @bool_add_lshr(i1 %a, i1 %b) {1392; CHECK-LABEL: @bool_add_lshr(1393; CHECK-NEXT:    [[LSHR1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]1394; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[LSHR1]] to i21395; CHECK-NEXT:    ret i2 [[LSHR]]1396;1397  %zext.a = zext i1 %a to i21398  %zext.b = zext i1 %b to i21399  %add = add i2 %zext.a, %zext.b1400  %lshr = lshr i2 %add, 11401  ret i2 %lshr1402}1403 1404; negative test - need bools1405 1406define i4 @not_bool_add_lshr(i2 %a, i2 %b) {1407; CHECK-LABEL: @not_bool_add_lshr(1408; CHECK-NEXT:    [[TMP1:%.*]] = xor i2 [[A:%.*]], -11409; CHECK-NEXT:    [[ADD_NARROWED_OVERFLOW:%.*]] = icmp ugt i2 [[B:%.*]], [[TMP1]]1410; CHECK-NEXT:    [[LSHR:%.*]] = zext i1 [[ADD_NARROWED_OVERFLOW]] to i41411; CHECK-NEXT:    ret i4 [[LSHR]]1412;1413  %zext.a = zext i2 %a to i41414  %zext.b = zext i2 %b to i41415  %add = add i4 %zext.a, %zext.b1416  %lshr = lshr i4 %add, 21417  ret i4 %lshr1418}1419 1420; TODO: This could be sext(and a, b).1421 1422define i2 @bool_add_ashr(i1 %a, i1 %b) {1423; CHECK-LABEL: @bool_add_ashr(1424; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i21425; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i1 [[B:%.*]] to i21426; CHECK-NEXT:    [[ADD:%.*]] = add nuw i2 [[ZEXT_A]], [[ZEXT_B]]1427; CHECK-NEXT:    [[ASHR:%.*]] = ashr i2 [[ADD]], 11428; CHECK-NEXT:    ret i2 [[ASHR]]1429;1430  %zext.a = zext i1 %a to i21431  %zext.b = zext i1 %b to i21432  %add = add i2 %zext.a, %zext.b1433  %ashr = ashr i2 %add, 11434  ret i2 %ashr1435}1436 1437define <2 x i8> @bool_add_lshr_vec(<2 x i1> %a, <2 x i1> %b) {1438; CHECK-LABEL: @bool_add_lshr_vec(1439; CHECK-NEXT:    [[LSHR1:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]1440; CHECK-NEXT:    [[LSHR:%.*]] = zext <2 x i1> [[LSHR1]] to <2 x i8>1441; CHECK-NEXT:    ret <2 x i8> [[LSHR]]1442;1443  %zext.a = zext <2 x i1> %a to <2 x i8>1444  %zext.b = zext <2 x i1> %b to <2 x i8>1445  %add = add <2 x i8> %zext.a, %zext.b1446  %lshr = lshr <2 x i8> %add, <i8 1, i8 1>1447  ret <2 x i8> %lshr1448}1449 1450define i32 @bool_add_lshr_uses(i1 %a, i1 %b) {1451; CHECK-LABEL: @bool_add_lshr_uses(1452; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i321453; CHECK-NEXT:    call void @use(i32 [[ZEXT_A]])1454; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i1 [[B:%.*]] to i321455; CHECK-NEXT:    call void @use(i32 [[ZEXT_B]])1456; CHECK-NEXT:    [[LSHR:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]1457; CHECK-NEXT:    ret i32 [[LSHR]]1458;1459  %zext.a = zext i1 %a to i321460  call void @use(i32 %zext.a)1461  %zext.b = zext i1 %b to i321462  call void @use(i32 %zext.b)1463  %add = add i32 %zext.a, %zext.b1464  %lshr = lshr i32 %add, 11465  ret i32 %lshr1466}1467 1468define i32 @bool_add_lshr_uses2(i1 %a, i1 %b) {1469; CHECK-LABEL: @bool_add_lshr_uses2(1470; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i321471; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i1 [[B:%.*]] to i321472; CHECK-NEXT:    call void @use(i32 [[ZEXT_B]])1473; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]1474; CHECK-NEXT:    call void @use(i32 [[ADD]])1475; CHECK-NEXT:    [[LSHR:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]1476; CHECK-NEXT:    ret i32 [[LSHR]]1477;1478  %zext.a = zext i1 %a to i321479  %zext.b = zext i1 %b to i321480  call void @use(i32 %zext.b)1481  %add = add i32 %zext.a, %zext.b1482  call void @use(i32 %add)1483  %lshr = lshr i32 %add, 11484  ret i32 %lshr1485}1486 1487; negative test - too many extra uses1488 1489define i32 @bool_add_lshr_uses3(i1 %a, i1 %b) {1490; CHECK-LABEL: @bool_add_lshr_uses3(1491; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i321492; CHECK-NEXT:    call void @use(i32 [[ZEXT_A]])1493; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext i1 [[B:%.*]] to i321494; CHECK-NEXT:    call void @use(i32 [[ZEXT_B]])1495; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]1496; CHECK-NEXT:    call void @use(i32 [[ADD]])1497; CHECK-NEXT:    [[LSHR:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]1498; CHECK-NEXT:    ret i32 [[LSHR]]1499;1500  %zext.a = zext i1 %a to i321501  call void @use(i32 %zext.a)1502  %zext.b = zext i1 %b to i321503  call void @use(i32 %zext.b)1504  %add = add i32 %zext.a, %zext.b1505  call void @use(i32 %add)1506  %lshr = lshr i32 %add, 11507  ret i32 %lshr1508}1509 1510; negative test1511 1512define <2 x i8> @bool_add_lshr_vec_wrong_shift_amt(<2 x i1> %a, <2 x i1> %b) {1513; CHECK-LABEL: @bool_add_lshr_vec_wrong_shift_amt(1514; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i8>1515; CHECK-NEXT:    [[ZEXT_B:%.*]] = zext <2 x i1> [[B:%.*]] to <2 x i8>1516; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw <2 x i8> [[ZEXT_A]], [[ZEXT_B]]1517; CHECK-NEXT:    [[LSHR:%.*]] = lshr <2 x i8> [[ADD]], <i8 1, i8 2>1518; CHECK-NEXT:    ret <2 x i8> [[LSHR]]1519;1520  %zext.a = zext <2 x i1> %a to <2 x i8>1521  %zext.b = zext <2 x i1> %b to <2 x i8>1522  %add = add <2 x i8> %zext.a, %zext.b1523  %lshr = lshr <2 x i8> %add, <i8 1, i8 2>1524  ret <2 x i8> %lshr1525}1526 1527define i32 @lowbits_of_lshr_mul(i64 %x) {1528; CHECK-LABEL: @lowbits_of_lshr_mul(1529; CHECK-NEXT:  entry:1530; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[X:%.*]] to i321531; CHECK-NEXT:    [[CONV:%.*]] = mul i32 [[TMP0]], 151532; CHECK-NEXT:    ret i32 [[CONV]]1533;1534entry:1535  %mul = mul i64 %x, 644245094401536  %shift = lshr i64 %mul, 321537  %conv = trunc i64 %shift to i321538  ret i32 %conv1539}1540 1541define i32 @lowbits_of_lshr_mul_mask(i32 %x) {1542; CHECK-LABEL: @lowbits_of_lshr_mul_mask(1543; CHECK-NEXT:  entry:1544; CHECK-NEXT:    [[TMP0:%.*]] = mul i32 [[X:%.*]], 16001545; CHECK-NEXT:    [[CONV:%.*]] = and i32 [[TMP0]], 327041546; CHECK-NEXT:    ret i32 [[CONV]]1547;1548entry:1549  %mul = mul i32 %x, 1048576001550  %shift = lshr i32 %mul, 161551  %conv = and i32 %shift, 327671552  ret i32 %conv1553}1554 1555; Negative tests1556 1557define i32 @lowbits_of_lshr_mul_mask_multiuse(i32 %x) {1558; CHECK-LABEL: @lowbits_of_lshr_mul_mask_multiuse(1559; CHECK-NEXT:  entry:1560; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], 1048576001561; CHECK-NEXT:    call void @use(i32 [[MUL]])1562; CHECK-NEXT:    [[SHIFT:%.*]] = lshr exact i32 [[MUL]], 161563; CHECK-NEXT:    [[CONV:%.*]] = and i32 [[SHIFT]], 327041564; CHECK-NEXT:    ret i32 [[CONV]]1565;1566entry:1567  %mul = mul i32 %x, 1048576001568  call void @use(i32 %mul)1569  %shift = lshr i32 %mul, 161570  %conv = and i32 %shift, 327671571  ret i32 %conv1572}1573 1574define i32 @lowbits_of_lshr_mul_mask_indivisible(i32 %x) {1575; CHECK-LABEL: @lowbits_of_lshr_mul_mask_indivisible(1576; CHECK-NEXT:  entry:1577; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], 256001578; CHECK-NEXT:    [[SHIFT:%.*]] = lshr i32 [[MUL]], 161579; CHECK-NEXT:    [[CONV:%.*]] = and i32 [[SHIFT]], 327671580; CHECK-NEXT:    ret i32 [[CONV]]1581;1582entry:1583  %mul = mul i32 %x, 256001584  %shift = lshr i32 %mul, 161585  %conv = and i32 %shift, 327671586  ret i32 %conv1587}1588