brintos

brintos / llvm-project-archived public Read only

0
0
Text · 47.9 KiB · 28c541e Raw
1289 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare i16 @llvm.fshl.i16(i16, i16, i16)5declare i16 @llvm.fshr.i16(i16, i16, i16)6declare i32 @llvm.fshl.i32(i32, i32, i32)7declare i33 @llvm.fshr.i33(i33, i33, i33)8declare <2 x i32> @llvm.fshr.v2i32(<2 x i32>, <2 x i32>, <2 x i32>)9declare <2 x i31> @llvm.fshl.v2i31(<2 x i31>, <2 x i31>, <2 x i31>)10declare <3 x i16> @llvm.fshl.v3i16(<3 x i16>, <3 x i16>, <3 x i16>)11 12declare void @use_v2(<2 x i31>)13declare void @use_v3(<3 x i16>)14 15; If the shift mask doesn't include any demanded bits, the funnel shift can be eliminated.16 17define i32 @fshl_mask_simplify1(i32 %x, i32 %y, i32 %sh) {18; CHECK-LABEL: @fshl_mask_simplify1(19; CHECK-NEXT:    ret i32 [[X:%.*]]20;21  %maskedsh = and i32 %sh, 3222  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)23  ret i32 %r24}25 26define <2 x i32> @fshr_mask_simplify2(<2 x i32> %x, <2 x i32> %y, <2 x i32> %sh) {27; CHECK-LABEL: @fshr_mask_simplify2(28; CHECK-NEXT:    ret <2 x i32> [[Y:%.*]]29;30  %maskedsh = and <2 x i32> %sh, <i32 64, i32 64>31  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %maskedsh)32  ret <2 x i32> %r33}34 35; Negative test.36 37define i32 @fshl_mask_simplify3(i32 %x, i32 %y, i32 %sh) {38; CHECK-LABEL: @fshl_mask_simplify3(39; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 1640; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])41; CHECK-NEXT:    ret i32 [[R]]42;43  %maskedsh = and i32 %sh, 1644  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)45  ret i32 %r46}47 48; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.49 50define i33 @fshr_mask_simplify1(i33 %x, i33 %y, i33 %sh) {51; CHECK-LABEL: @fshr_mask_simplify1(52; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i33 [[SH:%.*]], 6453; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 [[MASKEDSH]])54; CHECK-NEXT:    ret i33 [[R]]55;56  %maskedsh = and i33 %sh, 6457  %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)58  ret i33 %r59}60 61; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.62 63define <2 x i31> @fshl_mask_simplify2(<2 x i31> %x, <2 x i31> %y, <2 x i31> %sh) {64; CHECK-LABEL: @fshl_mask_simplify2(65; CHECK-NEXT:    [[MASKEDSH:%.*]] = and <2 x i31> [[SH:%.*]], splat (i31 32)66; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> [[MASKEDSH]])67; CHECK-NEXT:    ret <2 x i31> [[R]]68;69  %maskedsh = and <2 x i31> %sh, <i31 32, i31 32>70  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> %maskedsh)71  ret <2 x i31> %r72}73 74; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.75 76define i33 @fshr_mask_simplify3(i33 %x, i33 %y, i33 %sh) {77; CHECK-LABEL: @fshr_mask_simplify3(78; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i33 [[SH:%.*]], 3279; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 [[MASKEDSH]])80; CHECK-NEXT:    ret i33 [[R]]81;82  %maskedsh = and i33 %sh, 3283  %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)84  ret i33 %r85}86 87; This mask op is unnecessary.88 89define i32 @fshl_mask_not_required(i32 %x, i32 %y, i32 %sh) {90; CHECK-LABEL: @fshl_mask_not_required(91; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[SH:%.*]])92; CHECK-NEXT:    ret i32 [[R]]93;94  %maskedsh = and i32 %sh, 3195  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)96  ret i32 %r97}98 99; This mask op can be reduced.100 101define i32 @fshl_mask_reduce_constant(i32 %x, i32 %y, i32 %sh) {102; CHECK-LABEL: @fshl_mask_reduce_constant(103; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 1104; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])105; CHECK-NEXT:    ret i32 [[R]]106;107  %maskedsh = and i32 %sh, 33108  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)109  ret i32 %r110}111 112; But this mask op is required.113 114define i32 @fshl_mask_negative(i32 %x, i32 %y, i32 %sh) {115; CHECK-LABEL: @fshl_mask_negative(116; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 15117; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])118; CHECK-NEXT:    ret i32 [[R]]119;120  %maskedsh = and i32 %sh, 15121  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)122  ret i32 %r123}124 125; The transform is not limited to mask ops.126 127define <2 x i32> @fshr_set_but_not_demanded_vec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %sh) {128; CHECK-LABEL: @fshr_set_but_not_demanded_vec(129; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[SH:%.*]])130; CHECK-NEXT:    ret <2 x i32> [[R]]131;132  %bogusbits = or <2 x i32> %sh, <i32 32, i32 32>133  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %bogusbits)134  ret <2 x i32> %r135}136 137; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.138 139define <2 x i31> @fshl_set_but_not_demanded_vec(<2 x i31> %x, <2 x i31> %y, <2 x i31> %sh) {140; CHECK-LABEL: @fshl_set_but_not_demanded_vec(141; CHECK-NEXT:    [[BOGUSBITS:%.*]] = or <2 x i31> [[SH:%.*]], splat (i31 32)142; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> [[BOGUSBITS]])143; CHECK-NEXT:    ret <2 x i31> [[R]]144;145  %bogusbits = or <2 x i31> %sh, <i31 32, i31 32>146  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> %bogusbits)147  ret <2 x i31> %r148}149 150; Simplify one undef or zero operand and constant shift amount.151 152define i32 @fshl_op0_undef(i32 %x) {153; CHECK-LABEL: @fshl_op0_undef(154; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[X:%.*]], 25155; CHECK-NEXT:    ret i32 [[R]]156;157  %r = call i32 @llvm.fshl.i32(i32 undef, i32 %x, i32 7)158  ret i32 %r159}160 161define i32 @fshl_op0_zero(i32 %x) {162; CHECK-LABEL: @fshl_op0_zero(163; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[X:%.*]], 25164; CHECK-NEXT:    ret i32 [[R]]165;166  %r = call i32 @llvm.fshl.i32(i32 0, i32 %x, i32 7)167  ret i32 %r168}169 170define i33 @fshr_op0_undef(i33 %x) {171; CHECK-LABEL: @fshr_op0_undef(172; CHECK-NEXT:    [[R:%.*]] = lshr i33 [[X:%.*]], 7173; CHECK-NEXT:    ret i33 [[R]]174;175  %r = call i33 @llvm.fshr.i33(i33 undef, i33 %x, i33 7)176  ret i33 %r177}178 179define i33 @fshr_op0_zero(i33 %x) {180; CHECK-LABEL: @fshr_op0_zero(181; CHECK-NEXT:    [[R:%.*]] = lshr i33 [[X:%.*]], 7182; CHECK-NEXT:    ret i33 [[R]]183;184  %r = call i33 @llvm.fshr.i33(i33 0, i33 %x, i33 7)185  ret i33 %r186}187 188define i32 @fshl_op1_undef(i32 %x) {189; CHECK-LABEL: @fshl_op1_undef(190; CHECK-NEXT:    [[R:%.*]] = shl i32 [[X:%.*]], 7191; CHECK-NEXT:    ret i32 [[R]]192;193  %r = call i32 @llvm.fshl.i32(i32 %x, i32 undef, i32 7)194  ret i32 %r195}196 197define i32 @fshl_op1_zero(i32 %x) {198; CHECK-LABEL: @fshl_op1_zero(199; CHECK-NEXT:    [[R:%.*]] = shl i32 [[X:%.*]], 7200; CHECK-NEXT:    ret i32 [[R]]201;202  %r = call i32 @llvm.fshl.i32(i32 %x, i32 0, i32 7)203  ret i32 %r204}205 206define i33 @fshr_op1_undef(i33 %x) {207; CHECK-LABEL: @fshr_op1_undef(208; CHECK-NEXT:    [[R:%.*]] = shl i33 [[X:%.*]], 26209; CHECK-NEXT:    ret i33 [[R]]210;211  %r = call i33 @llvm.fshr.i33(i33 %x, i33 undef, i33 7)212  ret i33 %r213}214 215define i33 @fshr_op1_zero(i33 %x) {216; CHECK-LABEL: @fshr_op1_zero(217; CHECK-NEXT:    [[R:%.*]] = shl i33 [[X:%.*]], 26218; CHECK-NEXT:    ret i33 [[R]]219;220  %r = call i33 @llvm.fshr.i33(i33 %x, i33 0, i33 7)221  ret i33 %r222}223 224define <2 x i31> @fshl_op0_zero_splat_vec(<2 x i31> %x) {225; CHECK-LABEL: @fshl_op0_zero_splat_vec(226; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i31> [[X:%.*]], splat (i31 24)227; CHECK-NEXT:    ret <2 x i31> [[R]]228;229  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> zeroinitializer, <2 x i31> %x, <2 x i31> <i31 7, i31 7>)230  ret <2 x i31> %r231}232 233define <2 x i31> @fshl_op1_undef_splat_vec(<2 x i31> %x) {234; CHECK-LABEL: @fshl_op1_undef_splat_vec(235; CHECK-NEXT:    [[R:%.*]] = shl <2 x i31> [[X:%.*]], splat (i31 7)236; CHECK-NEXT:    ret <2 x i31> [[R]]237;238  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> undef, <2 x i31> <i31 7, i31 7>)239  ret <2 x i31> %r240}241 242define <2 x i32> @fshr_op0_undef_splat_vec(<2 x i32> %x) {243; CHECK-LABEL: @fshr_op0_undef_splat_vec(244; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 7)245; CHECK-NEXT:    ret <2 x i32> [[R]]246;247  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> undef, <2 x i32> %x, <2 x i32> <i32 7, i32 7>)248  ret <2 x i32> %r249}250 251define <2 x i32> @fshr_op1_zero_splat_vec(<2 x i32> %x) {252; CHECK-LABEL: @fshr_op1_zero_splat_vec(253; CHECK-NEXT:    [[R:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 25)254; CHECK-NEXT:    ret <2 x i32> [[R]]255;256  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> zeroinitializer, <2 x i32> <i32 7, i32 7>)257  ret <2 x i32> %r258}259 260define <2 x i31> @fshl_op0_zero_vec(<2 x i31> %x) {261; CHECK-LABEL: @fshl_op0_zero_vec(262; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i31> [[X:%.*]], <i31 30, i31 29>263; CHECK-NEXT:    ret <2 x i31> [[R]]264;265  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> zeroinitializer, <2 x i31> %x, <2 x i31> <i31 -1, i31 33>)266  ret <2 x i31> %r267}268 269define <2 x i31> @fshl_op1_undef_vec(<2 x i31> %x) {270; CHECK-LABEL: @fshl_op1_undef_vec(271; CHECK-NEXT:    [[R:%.*]] = shl <2 x i31> [[X:%.*]], <i31 1, i31 2>272; CHECK-NEXT:    ret <2 x i31> [[R]]273;274  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> undef, <2 x i31> <i31 -1, i31 33>)275  ret <2 x i31> %r276}277 278define <2 x i32> @fshr_op0_undef_vec(<2 x i32> %x) {279; CHECK-LABEL: @fshr_op0_undef_vec(280; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 1>281; CHECK-NEXT:    ret <2 x i32> [[R]]282;283  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> undef, <2 x i32> %x, <2 x i32> <i32 -1, i32 33>)284  ret <2 x i32> %r285}286 287define <2 x i32> @fshr_op1_zero_vec(<2 x i32> %x) {288; CHECK-LABEL: @fshr_op1_zero_vec(289; CHECK-NEXT:    [[R:%.*]] = shl <2 x i32> [[X:%.*]], <i32 1, i32 31>290; CHECK-NEXT:    ret <2 x i32> [[R]]291;292  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> zeroinitializer, <2 x i32> <i32 -1, i32 33>)293  ret <2 x i32> %r294}295 296; Only demand bits from one of the operands.297 298define i32 @fshl_only_op0_demanded(i32 %x, i32 %y) {299; CHECK-LABEL: @fshl_only_op0_demanded(300; CHECK-NEXT:    [[Z:%.*]] = shl i32 [[X:%.*]], 7301; CHECK-NEXT:    [[R:%.*]] = and i32 [[Z]], 128302; CHECK-NEXT:    ret i32 [[R]]303;304  %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)305  %r = and i32 %z, 128306  ret i32 %r307}308 309define i32 @fshl_only_op1_demanded(i32 %x, i32 %y) {310; CHECK-LABEL: @fshl_only_op1_demanded(311; CHECK-NEXT:    [[Z:%.*]] = lshr i32 [[Y:%.*]], 25312; CHECK-NEXT:    [[R:%.*]] = and i32 [[Z]], 63313; CHECK-NEXT:    ret i32 [[R]]314;315  %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)316  %r = and i32 %z, 63317  ret i32 %r318}319 320define i33 @fshr_only_op1_demanded(i33 %x, i33 %y) {321; CHECK-LABEL: @fshr_only_op1_demanded(322; CHECK-NEXT:    [[Z:%.*]] = lshr i33 [[Y:%.*]], 7323; CHECK-NEXT:    [[R:%.*]] = and i33 [[Z]], 12392324; CHECK-NEXT:    ret i33 [[R]]325;326  %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 7)327  %r = and i33 %z, 12392328  ret i33 %r329}330 331define i33 @fshr_only_op0_demanded(i33 %x, i33 %y) {332; CHECK-LABEL: @fshr_only_op0_demanded(333; CHECK-NEXT:    [[TMP1:%.*]] = lshr i33 [[X:%.*]], 4334; CHECK-NEXT:    [[R:%.*]] = and i33 [[TMP1]], 7335; CHECK-NEXT:    ret i33 [[R]]336;337  %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 7)338  %r = lshr i33 %z, 30339  ret i33 %r340}341 342define <2 x i31> @fshl_only_op1_demanded_vec_splat(<2 x i31> %x, <2 x i31> %y) {343; CHECK-LABEL: @fshl_only_op1_demanded_vec_splat(344; CHECK-NEXT:    [[Z:%.*]] = lshr <2 x i31> [[Y:%.*]], splat (i31 24)345; CHECK-NEXT:    [[R:%.*]] = and <2 x i31> [[Z]], <i31 63, i31 31>346; CHECK-NEXT:    ret <2 x i31> [[R]]347;348  %z = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 7, i31 7>)349  %r = and <2 x i31> %z, <i31 63, i31 31>350  ret <2 x i31> %r351}352 353define i32 @fshl_constant_shift_amount_modulo_bitwidth(i32 %x, i32 %y) {354; CHECK-LABEL: @fshl_constant_shift_amount_modulo_bitwidth(355; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 1)356; CHECK-NEXT:    ret i32 [[R]]357;358  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 33)359  ret i32 %r360}361 362define i33 @fshr_constant_shift_amount_modulo_bitwidth(i33 %x, i33 %y) {363; CHECK-LABEL: @fshr_constant_shift_amount_modulo_bitwidth(364; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 32)365; CHECK-NEXT:    ret i33 [[R]]366;367  %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 34)368  ret i33 %r369}370 371define i32 @fshl_undef_shift_amount(i32 %x, i32 %y) {372; CHECK-LABEL: @fshl_undef_shift_amount(373; CHECK-NEXT:    ret i32 [[X:%.*]]374;375  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 undef)376  ret i32 %r377}378 379define i33 @fshr_undef_shift_amount(i33 %x, i33 %y) {380; CHECK-LABEL: @fshr_undef_shift_amount(381; CHECK-NEXT:    ret i33 [[Y:%.*]]382;383  %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 undef)384  ret i33 %r385}386 387@external_global = external global i8388 389define i33 @fshr_constant_shift_amount_modulo_bitwidth_constexpr(i33 %x, i33 %y) {390; CHECK-LABEL: @fshr_constant_shift_amount_modulo_bitwidth_constexpr(391; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 ptrtoint (ptr @external_global to i33))392; CHECK-NEXT:    ret i33 [[R]]393;394  %shamt = ptrtoint ptr @external_global to i33395  %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %shamt)396  ret i33 %r397}398 399define <2 x i32> @fshr_constant_shift_amount_modulo_bitwidth_vec(<2 x i32> %x, <2 x i32> %y) {400; CHECK-LABEL: @fshr_constant_shift_amount_modulo_bitwidth_vec(401; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 30, i32 1>)402; CHECK-NEXT:    ret <2 x i32> [[R]]403;404  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> <i32 34, i32 -1>)405  ret <2 x i32> %r406}407 408define <2 x i31> @fshl_constant_shift_amount_modulo_bitwidth_vec(<2 x i31> %x, <2 x i31> %y) {409; CHECK-LABEL: @fshl_constant_shift_amount_modulo_bitwidth_vec(410; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> <i31 3, i31 1>)411; CHECK-NEXT:    ret <2 x i31> [[R]]412;413  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 34, i31 -1>)414  ret <2 x i31> %r415}416 417define <2 x i31> @fshl_constant_shift_amount_modulo_bitwidth_vec_const_expr(<2 x i31> %x, <2 x i31> %y) {418; CHECK-LABEL: @fshl_constant_shift_amount_modulo_bitwidth_vec_const_expr(419; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> <i31 34, i31 ptrtoint (ptr @external_global to i31)>)420; CHECK-NEXT:    ret <2 x i31> [[R]]421;422  %shamt = ptrtoint ptr @external_global to i31423  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 34, i31 ptrtoint (ptr @external_global to i31)>)424  ret <2 x i31> %r425}426 427define <2 x i31> @fshl_undef_shift_amount_vec(<2 x i31> %x, <2 x i31> %y) {428; CHECK-LABEL: @fshl_undef_shift_amount_vec(429; CHECK-NEXT:    ret <2 x i31> [[X:%.*]]430;431  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> undef)432  ret <2 x i31> %r433}434 435define <2 x i32> @fshr_undef_shift_amount_vec(<2 x i32> %x, <2 x i32> %y) {436; CHECK-LABEL: @fshr_undef_shift_amount_vec(437; CHECK-NEXT:    ret <2 x i32> [[Y:%.*]]438;439  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> undef)440  ret <2 x i32> %r441}442 443define i32 @rotl_common_demanded(i32 %a0) {444; CHECK-LABEL: @rotl_common_demanded(445; CHECK-NEXT:    [[X:%.*]] = xor i32 [[A0:%.*]], 2446; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 8)447; CHECK-NEXT:    ret i32 [[R]]448;449  %x = xor i32 %a0, 2450  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 8)451  ret i32 %r452}453 454define i33 @rotr_common_demanded(i33 %a0) {455; CHECK-LABEL: @rotr_common_demanded(456; CHECK-NEXT:    [[X:%.*]] = xor i33 [[A0:%.*]], 2457; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[X]], i33 25)458; CHECK-NEXT:    ret i33 [[R]]459;460  %x = xor i33 %a0, 2461  %r = call i33 @llvm.fshr.i33(i33 %x, i33 %x, i33 8)462  ret i33 %r463}464 465; The shift modulo bitwidth is the same for all vector elements.466 467define <2 x i31> @fshl_only_op1_demanded_vec_nonsplat(<2 x i31> %x, <2 x i31> %y) {468; CHECK-LABEL: @fshl_only_op1_demanded_vec_nonsplat(469; CHECK-NEXT:    [[Z:%.*]] = lshr <2 x i31> [[Y:%.*]], splat (i31 24)470; CHECK-NEXT:    [[R:%.*]] = and <2 x i31> [[Z]], <i31 63, i31 31>471; CHECK-NEXT:    ret <2 x i31> [[R]]472;473  %z = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 7, i31 38>)474  %r = and <2 x i31> %z, <i31 63, i31 31>475  ret <2 x i31> %r476}477 478define i32 @rotl_constant_shift_amount(i32 %x) {479; CHECK-LABEL: @rotl_constant_shift_amount(480; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 1)481; CHECK-NEXT:    ret i32 [[R]]482;483  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 33)484  ret i32 %r485}486 487define <2 x i31> @rotl_constant_shift_amount_vec(<2 x i31> %x) {488; CHECK-LABEL: @rotl_constant_shift_amount_vec(489; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[X]], <2 x i31> splat (i31 1))490; CHECK-NEXT:    ret <2 x i31> [[R]]491;492  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %x, <2 x i31> <i31 32, i31 -1>)493  ret <2 x i31> %r494}495 496define i33 @rotr_constant_shift_amount(i33 %x) {497; CHECK-LABEL: @rotr_constant_shift_amount(498; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X:%.*]], i33 [[X]], i33 32)499; CHECK-NEXT:    ret i33 [[R]]500;501  %r = call i33 @llvm.fshr.i33(i33 %x, i33 %x, i33 34)502  ret i33 %r503}504 505define <2 x i32> @rotr_constant_shift_amount_vec(<2 x i32> %x) {506; CHECK-LABEL: @rotr_constant_shift_amount_vec(507; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[X]], <2 x i32> <i32 31, i32 1>)508; CHECK-NEXT:    ret <2 x i32> [[R]]509;510  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %x, <2 x i32> <i32 33, i32 -1>)511  ret <2 x i32> %r512}513 514; Demand bits from both operands -- cannot simplify.515 516define i32 @fshl_both_ops_demanded(i32 %x, i32 %y) {517; CHECK-LABEL: @fshl_both_ops_demanded(518; CHECK-NEXT:    [[Z:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 7)519; CHECK-NEXT:    [[R:%.*]] = and i32 [[Z]], 192520; CHECK-NEXT:    ret i32 [[R]]521;522  %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)523  %r = and i32 %z, 192524  ret i32 %r525}526 527define i33 @fshr_both_ops_demanded(i33 %x, i33 %y) {528; CHECK-LABEL: @fshr_both_ops_demanded(529; CHECK-NEXT:    [[Z:%.*]] = call i33 @llvm.fshl.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 7)530; CHECK-NEXT:    [[R:%.*]] = and i33 [[Z]], 192531; CHECK-NEXT:    ret i33 [[R]]532;533  %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 26)534  %r = and i33 %z, 192535  ret i33 %r536}537 538; Both operands are demanded, but there are known bits.539 540define i32 @fshl_known_bits(i32 %x, i32 %y) {541; CHECK-LABEL: @fshl_known_bits(542; CHECK-NEXT:    ret i32 128543;544  %x2 = or i32 %x, 1   ; lo bit set545  %y2 = lshr i32 %y, 1 ; hi bit clear546  %z = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 7)547  %r = and i32 %z, 192548  ret i32 %r549}550 551define i33 @fshr_known_bits(i33 %x, i33 %y) {552; CHECK-LABEL: @fshr_known_bits(553; CHECK-NEXT:    ret i33 128554;555  %x2 = or i33 %x, 1 ; lo bit set556  %y2 = lshr i33 %y, 1 ; hi bit set557  %z = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 26)558  %r = and i33 %z, 192559  ret i33 %r560}561 562; This case fails to simplify due to multiple uses.563 564define i33 @fshr_multi_use(i33 %a) {565; CHECK-LABEL: @fshr_multi_use(566; CHECK-NEXT:    [[B:%.*]] = call i33 @llvm.fshl.i33(i33 [[A:%.*]], i33 [[A]], i33 32)567; CHECK-NEXT:    [[C:%.*]] = lshr i33 [[B]], 23568; CHECK-NEXT:    [[D:%.*]] = xor i33 [[C]], [[B]]569; CHECK-NEXT:    [[E:%.*]] = and i33 [[D]], 31570; CHECK-NEXT:    ret i33 [[E]]571;572  %b = tail call i33 @llvm.fshr.i33(i33 %a, i33 %a, i33 1)573  %c = lshr i33 %b, 23574  %d = xor i33 %c, %b575  %e = and i33 %d, 31576  ret i33 %e577}578 579; This demonstrates the same simplification working if the fshr intrinsic580; is expanded into shifts and or.581 582define i33 @expanded_fshr_multi_use(i33 %a) {583; CHECK-LABEL: @expanded_fshr_multi_use(584; CHECK-NEXT:    [[B:%.*]] = call i33 @llvm.fshl.i33(i33 [[A:%.*]], i33 [[A]], i33 32)585; CHECK-NEXT:    [[C:%.*]] = lshr i33 [[B]], 23586; CHECK-NEXT:    [[D:%.*]] = xor i33 [[C]], [[B]]587; CHECK-NEXT:    [[E:%.*]] = and i33 [[D]], 31588; CHECK-NEXT:    ret i33 [[E]]589;590  %t = lshr i33 %a, 1591  %t2 = shl i33 %a, 32592  %b = or i33 %t, %t2593  %c = lshr i33 %b, 23594  %d = xor i33 %c, %b595  %e = and i33 %d, 31596  ret i33 %e597}598 599; Special-case: rotate a 16-bit value left/right by 8-bits is bswap.600 601define i16 @fshl_bswap(i16 %x) {602; CHECK-LABEL: @fshl_bswap(603; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])604; CHECK-NEXT:    ret i16 [[R]]605;606  %r = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 8)607  ret i16 %r608}609 610define i16 @fshr_bswap(i16 %x) {611; CHECK-LABEL: @fshr_bswap(612; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])613; CHECK-NEXT:    ret i16 [[R]]614;615  %r = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 8)616  ret i16 %r617}618 619define <3 x i16> @fshl_bswap_vector(<3 x i16> %x) {620; CHECK-LABEL: @fshl_bswap_vector(621; CHECK-NEXT:    [[R:%.*]] = call <3 x i16> @llvm.bswap.v3i16(<3 x i16> [[X:%.*]])622; CHECK-NEXT:    ret <3 x i16> [[R]]623;624  %r = call <3 x i16> @llvm.fshl.v3i16(<3 x i16> %x, <3 x i16> %x, <3 x i16> <i16 8, i16 8, i16 8>)625  ret <3 x i16> %r626}627 628; Negative test629 630define i16 @fshl_bswap_wrong_op(i16 %x, i16 %y) {631; CHECK-LABEL: @fshl_bswap_wrong_op(632; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[Y:%.*]], i16 8)633; CHECK-NEXT:    ret i16 [[R]]634;635  %r = call i16 @llvm.fshl.i16(i16 %x, i16 %y, i16 8)636  ret i16 %r637}638 639; Negative test640 641define i16 @fshr_bswap_wrong_amount(i16 %x) {642; CHECK-LABEL: @fshr_bswap_wrong_amount(643; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 12)644; CHECK-NEXT:    ret i16 [[R]]645;646  %r = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 4)647  ret i16 %r648}649 650; Negative test651 652define i32 @fshl_bswap_wrong_width(i32 %x) {653; CHECK-LABEL: @fshl_bswap_wrong_width(654; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 8)655; CHECK-NEXT:    ret i32 [[R]]656;657  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 8)658  ret i32 %r659}660 661define i32 @fshl_mask_args_same1(i32 %a) {662; CHECK-LABEL: @fshl_mask_args_same1(663; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[A:%.*]], 16664; CHECK-NEXT:    ret i32 [[T2]]665;666  %t1 = and i32 %a, 4294901760 ; 0xffff0000667  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 16)668  ret i32 %t2669}670 671define i32 @fshl_mask_args_same2(i32 %a) {672; CHECK-LABEL: @fshl_mask_args_same2(673; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16674; CHECK-NEXT:    [[REV:%.*]] = shl i16 [[TRUNC]], 8675; CHECK-NEXT:    [[T2:%.*]] = zext i16 [[REV]] to i32676; CHECK-NEXT:    ret i32 [[T2]]677;678  %t1 = and i32 %a, 255679  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 8)680  ret i32 %t2681}682 683define i32 @fshl_mask_args_same3(i32 %a) {684; CHECK-LABEL: @fshl_mask_args_same3(685; CHECK-NEXT:    [[REV:%.*]] = shl i32 [[A:%.*]], 24686; CHECK-NEXT:    ret i32 [[REV]]687;688  %t1 = and i32 %a, 255689  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 24)690  ret i32 %t2691}692 693define i32 @fshl_mask_args_different(i32 %a) {694; CHECK-LABEL: @fshl_mask_args_different(695; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[A:%.*]], 15696; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T1]], 130560697; CHECK-NEXT:    ret i32 [[T3]]698;699  %t2 = and i32 %a, 4294901760 ; 0xfffff00f700  %t1 = and i32 %a, 4278190080 ; 0xff00f00f701  %t3 = call i32 @llvm.fshl.i32(i32 %t2, i32 %t1, i32 17)702  ret i32 %t3703}704 705define i32 @fsh_andconst_rotate(i32 %a) {706; CHECK-LABEL: @fsh_andconst_rotate(707; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[A:%.*]], 16708; CHECK-NEXT:    ret i32 [[T2]]709;710  %t1 = and i32 %a, 4294901760 ; 0xffff0000711  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 16)712  ret i32 %t2713}714 715define i32 @fsh_orconst_rotate(i32 %a) {716; CHECK-LABEL: @fsh_orconst_rotate(717; CHECK-NEXT:    [[T2:%.*]] = call i32 @llvm.fshl.i32(i32 [[A:%.*]], i32 -268435456, i32 4)718; CHECK-NEXT:    ret i32 [[T2]]719;720  %t1 = or i32 %a, 4026531840 ; 0xf0000000721  %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 4)722  ret i32 %t2723}724 725define i32 @fsh_rotate_5(i8 %x, i32 %y) {726; CHECK-LABEL: @fsh_rotate_5(727; CHECK-NEXT:    [[T1:%.*]] = zext i8 [[X:%.*]] to i32728; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[T1]]729; CHECK-NEXT:    [[OR2:%.*]] = call i32 @llvm.fshl.i32(i32 [[OR1]], i32 [[OR1]], i32 5)730; CHECK-NEXT:    ret i32 [[OR2]]731;732 733  %t1 = zext i8 %x to i32734  %or1 = or i32 %t1, %y735  %shr = lshr i32 %or1, 27736  %shl = shl i32 %or1, 5737  %or2 = or i32 %shr, %shl738  ret i32 %or2739}740 741define i32 @fsh_rotate_18(i8 %x, i32 %y) {742; CHECK-LABEL: @fsh_rotate_18(743; CHECK-NEXT:    [[T1:%.*]] = zext i8 [[X:%.*]] to i32744; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[T1]]745; CHECK-NEXT:    [[OR2:%.*]] = call i32 @llvm.fshl.i32(i32 [[OR1]], i32 [[OR1]], i32 18)746; CHECK-NEXT:    ret i32 [[OR2]]747;748 749  %t1 = zext i8 %x to i32750  %or1 = or i32 %t1, %y751  %shr = lshr i32 %or1, 14752  %shl = shl i32 %or1, 18753  %or2 = or i32 %shr, %shl754  ret i32 %or2755}756 757define i32 @fsh_load_rotate_12(ptr %data) {758; CHECK-LABEL: @fsh_load_rotate_12(759; CHECK-NEXT:  entry:760; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[DATA:%.*]], align 1761; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[TMP0]] to i32762; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[CONV]], 24763; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[DATA]], i64 1764; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1765; CHECK-NEXT:    [[CONV2:%.*]] = zext i8 [[TMP1]] to i32766; CHECK-NEXT:    [[SHL3:%.*]] = shl nuw nsw i32 [[CONV2]], 16767; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[SHL3]], [[SHL]]768; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[DATA]], i64 2769; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1770; CHECK-NEXT:    [[CONV5:%.*]] = zext i8 [[TMP2]] to i32771; CHECK-NEXT:    [[SHL6:%.*]] = shl nuw nsw i32 [[CONV5]], 8772; CHECK-NEXT:    [[OR7:%.*]] = or disjoint i32 [[OR]], [[SHL6]]773; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[DATA]], i64 3774; CHECK-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX8]], align 1775; CHECK-NEXT:    [[CONV9:%.*]] = zext i8 [[TMP3]] to i32776; CHECK-NEXT:    [[OR10:%.*]] = or disjoint i32 [[OR7]], [[CONV9]]777; CHECK-NEXT:    [[OR15:%.*]] = call i32 @llvm.fshl.i32(i32 [[OR10]], i32 [[OR10]], i32 12)778; CHECK-NEXT:    ret i32 [[OR15]]779;780 781entry:782  %0 = load i8, ptr %data783  %conv = zext i8 %0 to i32784  %shl = shl nuw i32 %conv, 24785  %arrayidx1 = getelementptr inbounds i8, ptr %data, i64 1786  %1 = load i8, ptr %arrayidx1787  %conv2 = zext i8 %1 to i32788  %shl3 = shl nuw nsw i32 %conv2, 16789  %or = or i32 %shl3, %shl790  %arrayidx4 = getelementptr inbounds i8, ptr %data, i64 2791  %2 = load i8, ptr %arrayidx4792  %conv5 = zext i8 %2 to i32793  %shl6 = shl nuw nsw i32 %conv5, 8794  %or7 = or i32 %or, %shl6795  %arrayidx8 = getelementptr inbounds i8, ptr %data, i64 3796  %3 = load i8, ptr %arrayidx8797  %conv9 = zext i8 %3 to i32798  %or10 = or i32 %or7, %conv9799  %shr = lshr i32 %or10, 20800  %shl7 = shl i32 %or10, 12801  %or15 = or i32 %shr, %shl7802  ret i32 %or15803}804 805define i32 @fsh_load_rotate_25(ptr %data) {806; CHECK-LABEL: @fsh_load_rotate_25(807; CHECK-NEXT:  entry:808; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[DATA:%.*]], align 1809; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[TMP0]] to i32810; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[CONV]], 24811; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[DATA]], i64 1812; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1813; CHECK-NEXT:    [[CONV2:%.*]] = zext i8 [[TMP1]] to i32814; CHECK-NEXT:    [[SHL3:%.*]] = shl nuw nsw i32 [[CONV2]], 16815; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[SHL3]], [[SHL]]816; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[DATA]], i64 2817; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1818; CHECK-NEXT:    [[CONV5:%.*]] = zext i8 [[TMP2]] to i32819; CHECK-NEXT:    [[SHL6:%.*]] = shl nuw nsw i32 [[CONV5]], 8820; CHECK-NEXT:    [[OR7:%.*]] = or disjoint i32 [[OR]], [[SHL6]]821; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[DATA]], i64 3822; CHECK-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX8]], align 1823; CHECK-NEXT:    [[CONV9:%.*]] = zext i8 [[TMP3]] to i32824; CHECK-NEXT:    [[OR10:%.*]] = or disjoint i32 [[OR7]], [[CONV9]]825; CHECK-NEXT:    [[OR15:%.*]] = call i32 @llvm.fshl.i32(i32 [[OR10]], i32 [[OR10]], i32 25)826; CHECK-NEXT:    ret i32 [[OR15]]827;828 829entry:830  %0 = load i8, ptr %data831  %conv = zext i8 %0 to i32832  %shl = shl nuw i32 %conv, 24833  %arrayidx1 = getelementptr inbounds i8, ptr %data, i64 1834  %1 = load i8, ptr %arrayidx1835  %conv2 = zext i8 %1 to i32836  %shl3 = shl nuw nsw i32 %conv2, 16837  %or = or i32 %shl3, %shl838  %arrayidx4 = getelementptr inbounds i8, ptr %data, i64 2839  %2 = load i8, ptr %arrayidx4840  %conv5 = zext i8 %2 to i32841  %shl6 = shl nuw nsw i32 %conv5, 8842  %or7 = or i32 %or, %shl6843  %arrayidx8 = getelementptr inbounds i8, ptr %data, i64 3844  %3 = load i8, ptr %arrayidx8845  %conv9 = zext i8 %3 to i32846  %or10 = or i32 %or7, %conv9847  %shr = lshr i32 %or10, 7848  %shl7 = shl i32 %or10, 25849  %or15 = or i32 %shr, %shl7850  ret i32 %or15851}852 853define <2 x i31> @fshr_mask_args_same_vector(<2 x i31> %a) {854; CHECK-LABEL: @fshr_mask_args_same_vector(855; CHECK-NEXT:    [[T3:%.*]] = shl <2 x i31> [[A:%.*]], splat (i31 10)856; CHECK-NEXT:    ret <2 x i31> [[T3]]857;858  %t1 = and <2 x i31> %a, <i31 1000, i31 1000>859  %t2 = and <2 x i31> %a, <i31 6442450943, i31 6442450943>860  %t3 = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %t2, <2 x i31> %t1, <2 x i31> <i31 10, i31 10>)861  ret <2 x i31> %t3862}863 864define <2 x i32> @fshr_mask_args_same_vector2(<2 x i32> %a, <2 x i32> %b) {865; CHECK-LABEL: @fshr_mask_args_same_vector2(866; CHECK-NEXT:    [[T1:%.*]] = and <2 x i32> [[A:%.*]], <i32 1000000, i32 100000>867; CHECK-NEXT:    [[T3:%.*]] = lshr exact <2 x i32> [[T1]], splat (i32 3)868; CHECK-NEXT:    ret <2 x i32> [[T3]]869;870  %t1 = and <2 x i32> %a, <i32 1000000, i32 100000>871  %t2 = and <2 x i32> %a, <i32 6442450943, i32 6442450943>872  %t3 = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %t1, <2 x i32> %t1, <2 x i32> <i32 3, i32 3>)873  ret <2 x i32> %t3874}875 876define <2 x i31> @fshr_mask_args_same_vector3_different_but_still_prunable(<2 x i31> %a) {877; CHECK-LABEL: @fshr_mask_args_same_vector3_different_but_still_prunable(878; CHECK-NEXT:    [[T1:%.*]] = and <2 x i31> [[A:%.*]], splat (i31 1000)879; CHECK-NEXT:    [[T3:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[A]], <2 x i31> [[T1]], <2 x i31> <i31 10, i31 3>)880; CHECK-NEXT:    ret <2 x i31> [[T3]]881;882  %t1 = and <2 x i31> %a, <i31 1000, i31 1000>883  %t2 = and <2 x i31> %a, <i31 6442450943, i31 6442450943>884  %t3 = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %t2, <2 x i31> %t1, <2 x i31> <i31 10, i31 3>)885  ret <2 x i31> %t3886}887 888define <2 x i32> @fsh_unary_shuffle_ops(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {889; CHECK-LABEL: @fsh_unary_shuffle_ops(890; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[Z:%.*]])891; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>892; CHECK-NEXT:    ret <2 x i32> [[R]]893;894  %a = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> <i32 1, i32 0>895  %b = shufflevector <2 x i32> %y, <2 x i32> poison, <2 x i32> <i32 1, i32 0>896  %c = shufflevector <2 x i32> %z, <2 x i32> poison, <2 x i32> <i32 1, i32 0>897  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c)898  ret <2 x i32> %r899}900 901define <3 x i16> @fsh_unary_shuffle_ops_widening(<2 x i16> %x, <2 x i16> %y, <2 x i16> %z) {902; CHECK-LABEL: @fsh_unary_shuffle_ops_widening(903; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x i16> [[X:%.*]], <2 x i16> poison, <3 x i32> <i32 1, i32 0, i32 1>904; CHECK-NEXT:    call void @use_v3(<3 x i16> [[A]])905; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i16> @llvm.fshl.v2i16(<2 x i16> [[X]], <2 x i16> [[Y:%.*]], <2 x i16> [[Z:%.*]])906; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <3 x i32> <i32 1, i32 0, i32 1>907; CHECK-NEXT:    ret <3 x i16> [[R]]908;909  %a = shufflevector <2 x i16> %x, <2 x i16> poison, <3 x i32> <i32 1, i32 0, i32 1>910  call void @use_v3(<3 x i16> %a)911  %b = shufflevector <2 x i16> %y, <2 x i16> poison, <3 x i32> <i32 1, i32 0, i32 1>912  %c = shufflevector <2 x i16> %z, <2 x i16> poison, <3 x i32> <i32 1, i32 0, i32 1>913  %r = call <3 x i16> @llvm.fshl.v3i16(<3 x i16> %a, <3 x i16> %b, <3 x i16> %c)914  ret <3 x i16> %r915}916 917define <2 x i31> @fsh_unary_shuffle_ops_narrowing(<3 x i31> %x, <3 x i31> %y, <3 x i31> %z) {918; CHECK-LABEL: @fsh_unary_shuffle_ops_narrowing(919; CHECK-NEXT:    [[B:%.*]] = shufflevector <3 x i31> [[Y:%.*]], <3 x i31> poison, <2 x i32> <i32 1, i32 0>920; CHECK-NEXT:    call void @use_v2(<2 x i31> [[B]])921; CHECK-NEXT:    [[TMP1:%.*]] = call <3 x i31> @llvm.fshl.v3i31(<3 x i31> [[X:%.*]], <3 x i31> [[Y]], <3 x i31> [[Z:%.*]])922; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x i31> [[TMP1]], <3 x i31> poison, <2 x i32> <i32 1, i32 0>923; CHECK-NEXT:    ret <2 x i31> [[R]]924;925  %a = shufflevector <3 x i31> %x, <3 x i31> poison, <2 x i32> <i32 1, i32 0>926  %b = shufflevector <3 x i31> %y, <3 x i31> poison, <2 x i32> <i32 1, i32 0>927  call void @use_v2(<2 x i31> %b)928  %c = shufflevector <3 x i31> %z, <3 x i31> poison, <2 x i32> <i32 1, i32 0>929  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %a, <2 x i31> %b, <2 x i31> %c)930  ret <2 x i31> %r931}932 933define <2 x i32> @fsh_unary_shuffle_ops_1_const(<2 x i32> %x, <2 x i32> %y) {934; CHECK-LABEL: @fsh_unary_shuffle_ops_1_const(935; CHECK-NEXT:    [[Y:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> <i32 2, i32 1>, <2 x i32> [[X:%.*]], <2 x i32> [[Y1:%.*]])936; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x i32> [[Y]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>937; CHECK-NEXT:    ret <2 x i32> [[B]]938;939  %a = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> <i32 1, i32 0>940  %b = shufflevector <2 x i32> %y, <2 x i32> poison, <2 x i32> <i32 1, i32 0>941  %r = call <2 x i32> @llvm.fshr(<2 x i32> <i32 1, i32 2>, <2 x i32> %a, <2 x i32> %b)942  ret <2 x i32> %r943}944 945define <2 x i32> @fsh_unary_shuffle_ops_2_const(<2 x i32> %x) {946; CHECK-LABEL: @fsh_unary_shuffle_ops_2_const(947; CHECK-NEXT:    [[X:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> <i32 2, i32 1>, <2 x i32> <i32 2, i32 1>, <2 x i32> [[X1:%.*]])948; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x i32> [[X]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>949; CHECK-NEXT:    ret <2 x i32> [[A]]950;951  %a = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> <i32 1, i32 0>952  %r = call <2 x i32> @llvm.fshr(<2 x i32> <i32 1, i32 2>, <2 x i32> <i32 1, i32 2>, <2 x i32> %a)953  ret <2 x i32> %r954}955 956define <vscale x 2 x i32> @fsh_unary_shuffle_ops_1_const_scalable(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y) {957; CHECK-LABEL: @fsh_unary_shuffle_ops_1_const_scalable(958; CHECK-NEXT:    [[Y:%.*]] = call <vscale x 2 x i32> @llvm.fshr.nxv2i32(<vscale x 2 x i32> splat (i32 42), <vscale x 2 x i32> [[X:%.*]], <vscale x 2 x i32> [[Y1:%.*]])959; CHECK-NEXT:    [[B:%.*]] = shufflevector <vscale x 2 x i32> [[Y]], <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer960; CHECK-NEXT:    ret <vscale x 2 x i32> [[B]]961;962  %a = shufflevector <vscale x 2 x i32> %x, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer963  %b = shufflevector <vscale x 2 x i32> %y, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer964  %r = call <vscale x 2 x i32> @llvm.fshr(<vscale x 2 x i32> splat (i32 42), <vscale x 2 x i32> %a, <vscale x 2 x i32> %b)965  ret <vscale x 2 x i32> %r966}967 968define <vscale x 2 x i32> @fsh_unary_shuffle_ops_2_const_scalable(<vscale x 2 x i32> %x) {969; CHECK-LABEL: @fsh_unary_shuffle_ops_2_const_scalable(970; CHECK-NEXT:    [[X:%.*]] = call <vscale x 2 x i32> @llvm.fshr.nxv2i32(<vscale x 2 x i32> splat (i32 42), <vscale x 2 x i32> splat (i32 42), <vscale x 2 x i32> [[X1:%.*]])971; CHECK-NEXT:    [[A:%.*]] = shufflevector <vscale x 2 x i32> [[X]], <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer972; CHECK-NEXT:    ret <vscale x 2 x i32> [[A]]973;974  %a = shufflevector <vscale x 2 x i32> %x, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer975  %r = call <vscale x 2 x i32> @llvm.fshr(<vscale x 2 x i32> splat (i32 42), <vscale x 2 x i32> splat (i32 42), <vscale x 2 x i32> %a)976  ret <vscale x 2 x i32> %r977}978 979define <3 x i32> @fsh_unary_shuffle_ops_widening_1_const(<2 x i32> %x, <2 x i32> %y) {980; CHECK-LABEL: @fsh_unary_shuffle_ops_widening_1_const(981; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <3 x i32> <i32 1, i32 0, i32 poison>982; CHECK-NEXT:    call void @use_v3(<3 x i32> [[A]])983; CHECK-NEXT:    [[Y:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> splat (i32 42), <2 x i32> [[X]], <2 x i32> [[Y1:%.*]])984; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x i32> [[Y]], <2 x i32> poison, <3 x i32> <i32 1, i32 0, i32 poison>985; CHECK-NEXT:    ret <3 x i32> [[B]]986;987  %a = shufflevector <2 x i32> %x, <2 x i32> poison, <3 x i32> <i32 1, i32 0, i32 poison>988  call void @use_v3(<3 x i32> %a)989  %b = shufflevector <2 x i32> %y, <2 x i32> poison, <3 x i32> <i32 1, i32 0, i32 poison>990  %r = call <3 x i32> @llvm.fshr(<3 x i32> splat (i32 42), <3 x i32> %a, <3 x i32> %b)991  ret <3 x i32> %r992}993 994; negative test - must have 3 shuffles995 996define <2 x i32> @fsh_unary_shuffle_ops_unshuffled(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {997; CHECK-LABEL: @fsh_unary_shuffle_ops_unshuffled(998; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>999; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x i32> [[Y:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>1000; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[A]], <2 x i32> [[B]], <2 x i32> [[Z:%.*]])1001; CHECK-NEXT:    ret <2 x i32> [[R]]1002;1003  %a = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> <i32 1, i32 0>1004  %b = shufflevector <2 x i32> %y, <2 x i32> poison, <2 x i32> <i32 1, i32 0>1005  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %z)1006  ret <2 x i32> %r1007}1008 1009; negative test - must have identical masks1010 1011define <2 x i32> @fsh_unary_shuffle_ops_wrong_mask(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {1012; CHECK-LABEL: @fsh_unary_shuffle_ops_wrong_mask(1013; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>1014; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x i32> [[Y:%.*]], <2 x i32> poison, <2 x i32> zeroinitializer1015; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i32> [[Z:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>1016; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[A]], <2 x i32> [[B]], <2 x i32> [[C]])1017; CHECK-NEXT:    ret <2 x i32> [[R]]1018;1019  %a = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> <i32 1, i32 0>1020  %b = shufflevector <2 x i32> %y, <2 x i32> poison, <2 x i32> <i32 0, i32 0>1021  %c = shufflevector <2 x i32> %z, <2 x i32> poison, <2 x i32> <i32 1, i32 0>1022  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c)1023  ret <2 x i32> %r1024}1025 1026; negative test - too many uses1027 1028define <2 x i31> @fsh_unary_shuffle_ops_uses(<2 x i31> %x, <2 x i31> %y, <2 x i31> %z) {1029; CHECK-LABEL: @fsh_unary_shuffle_ops_uses(1030; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x i31> [[X:%.*]], <2 x i31> poison, <2 x i32> <i32 1, i32 0>1031; CHECK-NEXT:    call void @use_v2(<2 x i31> [[A]])1032; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x i31> [[Y:%.*]], <2 x i31> poison, <2 x i32> <i32 1, i32 0>1033; CHECK-NEXT:    call void @use_v2(<2 x i31> [[B]])1034; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i31> [[Z:%.*]], <2 x i31> poison, <2 x i32> <i32 1, i32 0>1035; CHECK-NEXT:    call void @use_v2(<2 x i31> [[C]])1036; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[A]], <2 x i31> [[B]], <2 x i31> [[C]])1037; CHECK-NEXT:    ret <2 x i31> [[R]]1038;1039  %a = shufflevector <2 x i31> %x, <2 x i31> poison, <2 x i32> <i32 1, i32 0>1040  call void @use_v2(<2 x i31> %a)1041  %b = shufflevector <2 x i31> %y, <2 x i31> poison, <2 x i32> <i32 1, i32 0>1042  call void @use_v2(<2 x i31> %b)1043  %c = shufflevector <2 x i31> %z, <2 x i31> poison, <2 x i32> <i32 1, i32 0>1044  call void @use_v2(<2 x i31> %c)1045  %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %a, <2 x i31> %b, <2 x i31> %c)1046  ret <2 x i31> %r1047}1048 1049; negative test - all source ops must have the same type1050 1051define <2 x i32> @fsh_unary_shuffle_ops_partial_widening(<3 x i32> %x, <2 x i32> %y, <2 x i32> %z) {1052; CHECK-LABEL: @fsh_unary_shuffle_ops_partial_widening(1053; CHECK-NEXT:    [[A:%.*]] = shufflevector <3 x i32> [[X:%.*]], <3 x i32> poison, <2 x i32> <i32 1, i32 0>1054; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x i32> [[Y:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>1055; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i32> [[Z:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>1056; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[A]], <2 x i32> [[B]], <2 x i32> [[C]])1057; CHECK-NEXT:    ret <2 x i32> [[R]]1058;1059  %a = shufflevector <3 x i32> %x, <3 x i32> poison, <2 x i32> <i32 1, i32 0>1060  %b = shufflevector <2 x i32> %y, <2 x i32> poison, <2 x i32> <i32 1, i32 0>1061  %c = shufflevector <2 x i32> %z, <2 x i32> poison, <2 x i32> <i32 1, i32 0>1062  %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c)1063  ret <2 x i32> %r1064}1065 1066define <2 x i32> @fshr_vec_zero_elem(<2 x i32> %x, <2 x i32> %y) {1067; CHECK-LABEL: @fshr_vec_zero_elem(1068; CHECK-NEXT:    [[FSH:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 2, i32 0>)1069; CHECK-NEXT:    ret <2 x i32> [[FSH]]1070;1071  %fsh = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> <i32 2, i32 0>)1072  ret <2 x i32> %fsh1073}1074 1075define i16 @fshl_i16_shl(i16 %x, i16 %y) {1076; CHECK-LABEL: @fshl_i16_shl(1077; CHECK-NEXT:  entry:1078; CHECK-NEXT:    [[TMP0:%.*]] = and i16 [[Y:%.*]], 151079; CHECK-NEXT:    [[RES:%.*]] = shl i16 [[X:%.*]], [[TMP0]]1080; CHECK-NEXT:    ret i16 [[RES]]1081;1082entry:1083  %res = call i16 @llvm.fshl.i16(i16 %x, i16 0, i16 %y)1084  ret i16 %res1085}1086 1087define i32 @fshl_i32_shl(i32 %x, i32 %y) {1088; CHECK-LABEL: @fshl_i32_shl(1089; CHECK-NEXT:  entry:1090; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[Y:%.*]], 311091; CHECK-NEXT:    [[RES:%.*]] = shl i32 [[X:%.*]], [[TMP0]]1092; CHECK-NEXT:    ret i32 [[RES]]1093;1094entry:1095  %res = call i32 @llvm.fshl.i32(i32 %x, i32 0, i32 %y)1096  ret i32 %res1097}1098 1099define <2 x i16> @fshl_vi16_shl(<2 x i16> %x, <2 x i16> %y) {1100; CHECK-LABEL: @fshl_vi16_shl(1101; CHECK-NEXT:  entry:1102; CHECK-NEXT:    [[TMP0:%.*]] = and <2 x i16> [[Y:%.*]], splat (i16 15)1103; CHECK-NEXT:    [[RES:%.*]] = shl <2 x i16> [[X:%.*]], [[TMP0]]1104; CHECK-NEXT:    ret <2 x i16> [[RES]]1105;1106entry:1107  %res = call <2 x i16> @llvm.fshl.v2i16(<2 x i16> %x, <2 x i16> zeroinitializer, <2 x i16> %y)1108  ret <2 x i16> %res1109}1110 1111define i32 @fshr_i32_shl_negative_test(i32 %x, i32 %y) {1112; CHECK-LABEL: @fshr_i32_shl_negative_test(1113; CHECK-NEXT:  entry:1114; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 0, i32 [[Y:%.*]])1115; CHECK-NEXT:    ret i32 [[RES]]1116;1117entry:1118  %res = call i32 @llvm.fshr.i32(i32 %x, i32 0, i32 %y)1119  ret i32 %res1120}1121 1122define <2 x i31> @fshl_vi31_shl_negative_test(<2 x i31> %x, <2 x i31> %y) {1123; CHECK-LABEL: @fshl_vi31_shl_negative_test(1124; CHECK-NEXT:  entry:1125; CHECK-NEXT:    [[RES:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> zeroinitializer, <2 x i31> [[Y:%.*]])1126; CHECK-NEXT:    ret <2 x i31> [[RES]]1127;1128entry:1129  %res = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> zeroinitializer, <2 x i31>  %y)1130  ret <2 x i31>  %res1131}1132 1133;; Issue #124387 Range attribute no longer holds after operands changed.1134define i8 @fshl_range_trunc(i1 %x) {1135; CHECK-LABEL: @fshl_range_trunc(1136; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[X:%.*]] to i321137; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[ZEXT]], 1261138; CHECK-NEXT:    [[FSHL:%.*]] = call i32 @llvm.fshl.i32(i32 [[OR]], i32 -2, i32 1)1139; CHECK-NEXT:    [[TR:%.*]] = trunc nuw i32 [[FSHL]] to i81140; CHECK-NEXT:    ret i8 [[TR]]1141;1142  %zext = zext i1 %x to i321143  %or = or disjoint i32 %zext, -21144  %fshl = call range(i32 -4, 2) i32 @llvm.fshl.i32(i32 %or, i32 %or, i32 1)1145  %tr = trunc nsw i32 %fshl to i81146  ret i8 %tr1147}1148 1149;; Issue #138334 negative rotate amounts can be folded into the opposite direction1150define i32 @fshl_neg_amount(i32 %x, i32 %y) {1151; CHECK-LABEL: @fshl_neg_amount(1152; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])1153; CHECK-NEXT:    ret i32 [[R]]1154;1155  %n = sub i32 0, %y1156  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %n)1157  ret i32 %r1158}1159 1160define i32 @fshr_neg_amount(i32 %x, i32 %y) {1161; CHECK-LABEL: @fshr_neg_amount(1162; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])1163; CHECK-NEXT:    ret i32 [[R]]1164;1165  %n = sub i32 0, %y1166  %r = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %n)1167  ret i32 %r1168}1169 1170;; negative test, funnel shift is not a rotate1171 1172define i32 @fshl_neg_amount_non_rotate(i32 %x, i32 %y, i32 %z) {1173; CHECK-LABEL: @fshl_neg_amount_non_rotate(1174; CHECK-NEXT:    [[N:%.*]] = sub i32 0, [[Y:%.*]]1175; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Z:%.*]], i32 [[N]])1176; CHECK-NEXT:    ret i32 [[R]]1177;1178  %n = sub i32 0, %y1179  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %z, i32 %n)1180  ret i32 %r1181}1182 1183define i32 @fshr_neg_amount_non_rotate(i32 %x, i32 %y, i32 %z) {1184; CHECK-LABEL: @fshr_neg_amount_non_rotate(1185; CHECK-NEXT:    [[N:%.*]] = sub i32 0, [[Y:%.*]]1186; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[Z:%.*]], i32 [[N]])1187; CHECK-NEXT:    ret i32 [[R]]1188;1189  %n = sub i32 0, %y1190  %r = call i32 @llvm.fshr.i32(i32 %x, i32 %z, i32 %n)1191  ret i32 %r1192}1193 1194;; negative test, bitwidth is not a power of two1195 1196define i31 @fshl_neg_amount_non_power_two(i31 %x, i31 %y) {1197; CHECK-LABEL: @fshl_neg_amount_non_power_two(1198; CHECK-NEXT:    [[N:%.*]] = sub i31 0, [[Y:%.*]]1199; CHECK-NEXT:    [[R:%.*]] = call i31 @llvm.fshl.i31(i31 [[X:%.*]], i31 [[X]], i31 [[N]])1200; CHECK-NEXT:    ret i31 [[R]]1201;1202  %n = sub i31 0, %y1203  %r = call i31 @llvm.fshl.i31(i31 %x, i31 %x, i31 %n)1204  ret i31 %r1205}1206 1207define i31 @fshr_neg_amount_non_power_two(i31 %x, i31 %y) {1208; CHECK-LABEL: @fshr_neg_amount_non_power_two(1209; CHECK-NEXT:    [[N:%.*]] = sub i31 0, [[Y:%.*]]1210; CHECK-NEXT:    [[R:%.*]] = call i31 @llvm.fshr.i31(i31 [[X:%.*]], i31 [[X]], i31 [[N]])1211; CHECK-NEXT:    ret i31 [[R]]1212;1213  %n = sub i31 0, %y1214  %r = call i31 @llvm.fshr.i31(i31 %x, i31 %x, i31 %n)1215  ret i31 %r1216}1217 1218define i32 @rot_const_consecutive(i32 %x) {1219; CHECK-LABEL: @rot_const_consecutive(1220; CHECK-NEXT:    [[R2:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 8)1221; CHECK-NEXT:    ret i32 [[R2]]1222;1223  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 13)1224  %r2 = call i32 @llvm.fshl.i32(i32 %r, i32 %r, i32 27)1225  ret i32 %r21226}1227 1228define i32 @rot_const_consecutive_multi_use(i32 %x) {1229; CHECK-LABEL: @rot_const_consecutive_multi_use(1230; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 7)1231; CHECK-NEXT:    [[R3:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 11)1232; CHECK-NEXT:    [[R2:%.*]] = and i32 [[R]], [[R3]]1233; CHECK-NEXT:    ret i32 [[R2]]1234;1235  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 7)1236  %r2 = call i32 @llvm.fshl.i32(i32 %r, i32 %r, i32 4)1237  %and = and i32 %r, %r21238  ret i32 %and1239}1240 1241define i32 @rot_const_consecutive_cancel_out(i32 %x) {1242; CHECK-LABEL: @rot_const_consecutive_cancel_out(1243; CHECK-NEXT:    ret i32 [[X:%.*]]1244;1245  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 7)1246  %r2 = call i32 @llvm.fshl.i32(i32 %r, i32 %r, i32 25)1247  ret i32 %r21248}1249 1250;; negative test, consecutive rotates only fold if shift amounts are const1251 1252define i32 @rot_nonconst_shift(i32 %x, i32 %amt) {1253; CHECK-LABEL: @rot_nonconst_shift(1254; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 7)1255; CHECK-NEXT:    [[R2:%.*]] = call i32 @llvm.fshl.i32(i32 [[R]], i32 [[R]], i32 [[AMT:%.*]])1256; CHECK-NEXT:    ret i32 [[R2]]1257;1258  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 7)1259  %r2 = call i32 @llvm.fshl.i32(i32 %r, i32 %r, i32 %amt)1260  ret i32 %r21261}1262 1263;; negative test, 1st funnel shift isn't a rotate.1264 1265define i32 @fsh_rot(i32 %x, i32 %y) {1266; CHECK-LABEL: @fsh_rot(1267; CHECK-NEXT:    [[FSH:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 7)1268; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[FSH]], i32 [[FSH]], i32 4)1269; CHECK-NEXT:    ret i32 [[R]]1270;1271  %fsh = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)1272  %r = call i32 @llvm.fshl.i32(i32 %fsh, i32 %fsh, i32 4)1273  ret i32 %r1274}1275 1276;; negative test, 2nd funnel shift isn't a rotate.1277 1278define i32 @rot_fsh(i32 %x, i32 %y) {1279; CHECK-LABEL: @rot_fsh(1280; CHECK-NEXT:    [[Y:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 7)1281; CHECK-NEXT:    [[R2:%.*]] = call i32 @llvm.fshl.i32(i32 [[Y]], i32 [[R:%.*]], i32 4)1282; CHECK-NEXT:    ret i32 [[R2]]1283;1284  %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 7)1285  %r2 = call i32 @llvm.fshl.i32(i32 %r, i32 %y, i32 4)1286  ret i32 %r21287}1288 1289