brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.7 KiB · 55bad9a Raw
576 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use16(i16)5declare void @use32(i32)6declare void @use64(i64)7 8define i32 @t0(i64 %data, i32 %nbits) {9; CHECK-LABEL: @t0(10; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]11; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])12; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i6413; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])14; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]15; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])16; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i3217; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])18; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]19; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])20; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]21; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i3222; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]23;24  %skip_high = sub i32 64, %nbits25  call void @use32(i32 %skip_high)26  %skip_high_wide = zext i32 %skip_high to i6427  call void @use64(i64 %skip_high_wide)28  %extracted = lshr i64 %data, %skip_high_wide29  call void @use64(i64 %extracted)30  %extracted_narrow = trunc i64 %extracted to i3231  call void @use32(i32 %extracted_narrow)32  %num_high_bits_to_smear_narrow = sub i32 32, %nbits33  call void @use32(i32 %num_high_bits_to_smear_narrow)34  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow35  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow36  ret i32 %signextended37}38define i32 @t0_zext_of_nbits(i64 %data, i8 %nbits_narrow) {39; CHECK-LABEL: @t0_zext_of_nbits(40; CHECK-NEXT:    [[NBITS:%.*]] = zext i8 [[NBITS_NARROW:%.*]] to i1641; CHECK-NEXT:    call void @use16(i16 [[NBITS]])42; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub nsw i16 64, [[NBITS]]43; CHECK-NEXT:    call void @use16(i16 [[SKIP_HIGH]])44; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i16 [[SKIP_HIGH]] to i6445; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])46; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]47; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])48; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i3249; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])50; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW_NARROW:%.*]] = sub nsw i16 32, [[NBITS]]51; CHECK-NEXT:    call void @use16(i16 [[NUM_HIGH_BITS_TO_SMEAR_NARROW_NARROW]])52; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = zext i16 [[NUM_HIGH_BITS_TO_SMEAR_NARROW_NARROW]] to i3253; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])54; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]55; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i3256; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]57;58  %nbits = zext i8 %nbits_narrow to i1659  call void @use16(i16 %nbits)60  %skip_high = sub i16 64, %nbits61  call void @use16(i16 %skip_high)62  %skip_high_wide = zext i16 %skip_high to i6463  call void @use64(i64 %skip_high_wide)64  %extracted = lshr i64 %data, %skip_high_wide65  call void @use64(i64 %extracted)66  %extracted_narrow = trunc i64 %extracted to i3267  call void @use32(i32 %extracted_narrow)68  %num_high_bits_to_smear_narrow_narrow = sub i16 32, %nbits69  call void @use16(i16 %num_high_bits_to_smear_narrow_narrow)70  %num_high_bits_to_smear_narrow = zext i16 %num_high_bits_to_smear_narrow_narrow to i3271  call void @use32(i32 %num_high_bits_to_smear_narrow)72  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow73  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow74  ret i32 %signextended75}76define i32 @t0_exact(i64 %data, i32 %nbits) {77; CHECK-LABEL: @t0_exact(78; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]79; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])80; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i6481; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])82; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr exact i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]83; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])84; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i3285; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])86; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]87; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])88; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i64 [[DATA]], [[SKIP_HIGH_WIDE]]89; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i3290; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]91;92  %skip_high = sub i32 64, %nbits93  call void @use32(i32 %skip_high)94  %skip_high_wide = zext i32 %skip_high to i6495  call void @use64(i64 %skip_high_wide)96  %extracted = lshr exact i64 %data, %skip_high_wide ; We can preserve `exact`-ness of the original shift.97  call void @use64(i64 %extracted)98  %extracted_narrow = trunc i64 %extracted to i3299  call void @use32(i32 %extracted_narrow)100  %num_high_bits_to_smear_narrow = sub i32 32, %nbits101  call void @use32(i32 %num_high_bits_to_smear_narrow)102  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow103  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow104  ret i32 %signextended105}106 107define i32 @t1_redundant_sext(i64 %data, i32 %nbits) {108; CHECK-LABEL: @t1_redundant_sext(109; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]110; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])111; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64112; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])113; CHECK-NEXT:    [[EXTRACTED_WITH_SIGNEXTENSION:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]114; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED_WITH_SIGNEXTENSION]])115; CHECK-NEXT:    [[EXTRACTED_WITH_SIGNEXTENSION_NARROW:%.*]] = trunc i64 [[EXTRACTED_WITH_SIGNEXTENSION]] to i32116; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_WITH_SIGNEXTENSION_NARROW]])117; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]118; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])119; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_WITH_SIGNEXTENSION_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]120; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT_POSITIONED]])121; CHECK-NEXT:    ret i32 [[EXTRACTED_WITH_SIGNEXTENSION_NARROW]]122;123  %skip_high = sub i32 64, %nbits124  call void @use32(i32 %skip_high)125  %skip_high_wide = zext i32 %skip_high to i64126  call void @use64(i64 %skip_high_wide)127  %extracted_with_signextension = ashr i64 %data, %skip_high_wide128  call void @use64(i64 %extracted_with_signextension)129  %extracted_with_signextension_narrow = trunc i64 %extracted_with_signextension to i32 ; this is already the answer.130  call void @use32(i32 %extracted_with_signextension_narrow)131  %num_high_bits_to_smear_narrow = sub i32 32, %nbits132  call void @use32(i32 %num_high_bits_to_smear_narrow)133  %signbit_positioned = shl i32 %extracted_with_signextension_narrow, %num_high_bits_to_smear_narrow134  call void @use32(i32 %signbit_positioned)135  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow136  ret i32 %signextended137}138 139define i64 @t2_notrunc(i64 %data, i64 %nbits) {140; CHECK-LABEL: @t2_notrunc(141; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i64 64, [[NBITS:%.*]]142; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH]])143; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH]]144; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])145; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR:%.*]] = sub i64 64, [[NBITS]]146; CHECK-NEXT:    call void @use64(i64 [[NUM_HIGH_BITS_TO_SMEAR]])147; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i64 [[EXTRACTED]], [[NUM_HIGH_BITS_TO_SMEAR]]148; CHECK-NEXT:    call void @use64(i64 [[SIGNBIT_POSITIONED]])149; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH]]150; CHECK-NEXT:    ret i64 [[SIGNEXTENDED]]151;152  %skip_high = sub i64 64, %nbits153  call void @use64(i64 %skip_high)154  %extracted = lshr i64 %data, %skip_high155  call void @use64(i64 %extracted)156  %num_high_bits_to_smear = sub i64 64, %nbits157  call void @use64(i64 %num_high_bits_to_smear)158  %signbit_positioned = shl i64 %extracted, %num_high_bits_to_smear ;159  call void @use64(i64 %signbit_positioned)160  %signextended = ashr i64 %signbit_positioned, %num_high_bits_to_smear ; can just shift %data itself.161  ret i64 %signextended162}163 164define i64 @t3_notrunc_redundant_sext(i64 %data, i64 %nbits) {165; CHECK-LABEL: @t3_notrunc_redundant_sext(166; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i64 64, [[NBITS:%.*]]167; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH]])168; CHECK-NEXT:    [[EXTRACTED:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH]]169; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])170; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR:%.*]] = sub i64 64, [[NBITS]]171; CHECK-NEXT:    call void @use64(i64 [[NUM_HIGH_BITS_TO_SMEAR]])172; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i64 [[EXTRACTED]], [[NUM_HIGH_BITS_TO_SMEAR]]173; CHECK-NEXT:    call void @use64(i64 [[SIGNBIT_POSITIONED]])174; CHECK-NEXT:    ret i64 [[EXTRACTED]]175;176  %skip_high = sub i64 64, %nbits177  call void @use64(i64 %skip_high)178  %extracted = ashr i64 %data, %skip_high ; this is already the answer.179  call void @use64(i64 %extracted)180  %num_high_bits_to_smear = sub i64 64, %nbits181  call void @use64(i64 %num_high_bits_to_smear)182  %signbit_positioned = shl i64 %extracted, %num_high_bits_to_smear183  call void @use64(i64 %signbit_positioned)184  %signextended = ashr i64 %signbit_positioned, %num_high_bits_to_smear185  ret i64 %signextended186}187 188define <2 x i32> @t4_vec(<2 x i64> %data, <2 x i32> %nbits) {189; CHECK-LABEL: @t4_vec(190; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub <2 x i32> splat (i32 64), [[NBITS:%.*]]191; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext nneg <2 x i32> [[SKIP_HIGH]] to <2 x i64>192; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i64> [[DATA:%.*]], [[SKIP_HIGH_WIDE]]193; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i32>194; CHECK-NEXT:    ret <2 x i32> [[SIGNEXTENDED]]195;196  %skip_high = sub <2 x i32> <i32 64, i32 64>, %nbits197  %skip_high_wide = zext <2 x i32> %skip_high to <2 x i64>198  %extracted = lshr <2 x i64> %data, %skip_high_wide199  %extracted_narrow = trunc <2 x i64> %extracted to <2 x i32>200  %num_high_bits_to_smear_narrow = sub <2 x i32> <i32 32, i32 32>, %nbits201  %signbit_positioned = shl <2 x i32> %extracted_narrow, %num_high_bits_to_smear_narrow202  %signextended = ashr <2 x i32> %signbit_positioned, %num_high_bits_to_smear_narrow203  ret <2 x i32> %signextended204}205 206define <3 x i32> @t5_vec_poison(<3 x i64> %data, <3 x i32> %nbits) {207; CHECK-LABEL: @t5_vec_poison(208; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub <3 x i32> <i32 64, i32 64, i32 poison>, [[NBITS:%.*]]209; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext nneg <3 x i32> [[SKIP_HIGH]] to <3 x i64>210; CHECK-NEXT:    [[TMP1:%.*]] = ashr <3 x i64> [[DATA:%.*]], [[SKIP_HIGH_WIDE]]211; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc <3 x i64> [[TMP1]] to <3 x i32>212; CHECK-NEXT:    ret <3 x i32> [[SIGNEXTENDED]]213;214  %skip_high = sub <3 x i32> <i32 64, i32 64, i32 poison>, %nbits215  %skip_high_wide = zext <3 x i32> %skip_high to <3 x i64>216  %extracted = lshr <3 x i64> %data, %skip_high_wide217  %extracted_narrow = trunc <3 x i64> %extracted to <3 x i32>218  %num_high_bits_to_smear_narrow0 = sub <3 x i32> <i32 32, i32 32, i32 poison>, %nbits219  %num_high_bits_to_smear_narrow1 = sub <3 x i32> <i32 poison, i32 32, i32 32>, %nbits220  %signbit_positioned = shl <3 x i32> %extracted_narrow, %num_high_bits_to_smear_narrow0221  %signextended = ashr <3 x i32> %signbit_positioned, %num_high_bits_to_smear_narrow1222  ret <3 x i32> %signextended223}224 225; Extra-uses226define i32 @t6_extrause_good0(i64 %data, i32 %nbits) {227; CHECK-LABEL: @t6_extrause_good0(228; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]229; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])230; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64231; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])232; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]233; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])234; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32235; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])236; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]237; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])238; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]239; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32240; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]241;242  %skip_high = sub i32 64, %nbits243  call void @use32(i32 %skip_high)244  %skip_high_wide = zext i32 %skip_high to i64245  call void @use64(i64 %skip_high_wide)246  %extracted = lshr i64 %data, %skip_high_wide247  call void @use64(i64 %extracted)248  %extracted_narrow = trunc i64 %extracted to i32249  call void @use32(i32 %extracted_narrow)250  %num_high_bits_to_smear_narrow = sub i32 32, %nbits251  call void @use32(i32 %num_high_bits_to_smear_narrow)252  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow ; will go away253  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow254  ret i32 %signextended255}256define i32 @t7_extrause_good1(i64 %data, i32 %nbits) {257; CHECK-LABEL: @t7_extrause_good1(258; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]259; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])260; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64261; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])262; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]263; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])264; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32265; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])266; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW0:%.*]] = sub i32 32, [[NBITS]]267; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW0]])268; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW0]]269; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT_POSITIONED]])270; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[DATA]], [[SKIP_HIGH_WIDE]]271; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32272; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]273;274  %skip_high = sub i32 64, %nbits275  call void @use32(i32 %skip_high)276  %skip_high_wide = zext i32 %skip_high to i64277  call void @use64(i64 %skip_high_wide)278  %extracted = lshr i64 %data, %skip_high_wide279  call void @use64(i64 %extracted)280  %extracted_narrow = trunc i64 %extracted to i32281  call void @use32(i32 %extracted_narrow)282  %num_high_bits_to_smear_narrow0 = sub i32 32, %nbits283  call void @use32(i32 %num_high_bits_to_smear_narrow0)284  %num_high_bits_to_smear_narrow1 = sub i32 32, %nbits ; will go away.285  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow0286  call void @use32(i32 %signbit_positioned)287  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow1288  ret i32 %signextended289}290define i32 @n8_extrause_bad(i64 %data, i32 %nbits) {291; CHECK-LABEL: @n8_extrause_bad(292; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]293; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])294; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64295; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])296; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]297; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])298; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32299; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])300; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]301; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])302; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]303; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT_POSITIONED]])304; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]305; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]306;307  %skip_high = sub i32 64, %nbits308  call void @use32(i32 %skip_high)309  %skip_high_wide = zext i32 %skip_high to i64310  call void @use64(i64 %skip_high_wide)311  %extracted = lshr i64 %data, %skip_high_wide312  call void @use64(i64 %extracted)313  %extracted_narrow = trunc i64 %extracted to i32314  call void @use32(i32 %extracted_narrow)315  %num_high_bits_to_smear_narrow = sub i32 32, %nbits316  call void @use32(i32 %num_high_bits_to_smear_narrow)317  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow318  call void @use32(i32 %signbit_positioned)319  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow ; neither of operands will go away.320  ret i32 %signextended321}322 323; Negative tests324define i32 @n9(i64 %data, i32 %nbits) {325; CHECK-LABEL: @n9(326; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 63, [[NBITS:%.*]]327; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])328; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64329; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])330; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]331; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])332; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32333; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])334; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]335; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])336; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]337; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]338; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]339;340  %skip_high = sub i32 63, %nbits ; not 64341  call void @use32(i32 %skip_high)342  %skip_high_wide = zext i32 %skip_high to i64343  call void @use64(i64 %skip_high_wide)344  %extracted = lshr i64 %data, %skip_high_wide345  call void @use64(i64 %extracted)346  %extracted_narrow = trunc i64 %extracted to i32347  call void @use32(i32 %extracted_narrow)348  %num_high_bits_to_smear_narrow = sub i32 32, %nbits349  call void @use32(i32 %num_high_bits_to_smear_narrow)350  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow351  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow352  ret i32 %signextended353}354 355define i32 @n10(i64 %data, i32 %nbits) {356; CHECK-LABEL: @n10(357; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]358; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])359; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64360; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])361; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]362; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])363; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32364; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])365; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 31, [[NBITS]]366; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])367; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]368; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]369; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]370;371  %skip_high = sub i32 64, %nbits372  call void @use32(i32 %skip_high)373  %skip_high_wide = zext i32 %skip_high to i64374  call void @use64(i64 %skip_high_wide)375  %extracted = lshr i64 %data, %skip_high_wide376  call void @use64(i64 %extracted)377  %extracted_narrow = trunc i64 %extracted to i32378  call void @use32(i32 %extracted_narrow)379  %num_high_bits_to_smear_narrow = sub i32 31, %nbits ; not 32380  call void @use32(i32 %num_high_bits_to_smear_narrow)381  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow382  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow383  ret i32 %signextended384}385 386define i32 @n11(i64 %data, i32 %nbits1, i32 %nbits2) {387; CHECK-LABEL: @n11(388; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS1:%.*]]389; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])390; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64391; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])392; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]393; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])394; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32395; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])396; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS2:%.*]]397; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])398; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]399; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr exact i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]400; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]401;402  %skip_high = sub i32 64, %nbits1 ; not %nbits2403  call void @use32(i32 %skip_high)404  %skip_high_wide = zext i32 %skip_high to i64405  call void @use64(i64 %skip_high_wide)406  %extracted = lshr i64 %data, %skip_high_wide407  call void @use64(i64 %extracted)408  %extracted_narrow = trunc i64 %extracted to i32409  call void @use32(i32 %extracted_narrow)410  %num_high_bits_to_smear_narrow = sub i32 32, %nbits2 ; not %nbits1411  call void @use32(i32 %num_high_bits_to_smear_narrow)412  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow413  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow414  ret i32 %signextended415}416 417define i32 @n12(i64 %data, i32 %nbits1, i32 %nbits2) {418; CHECK-LABEL: @n12(419; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS1:%.*]]420; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])421; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64422; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])423; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]424; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])425; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32426; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])427; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW1:%.*]] = sub i32 32, [[NBITS1]]428; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW2:%.*]] = sub i32 32, [[NBITS2:%.*]]429; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW1]])430; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW2]])431; CHECK-NEXT:    [[SIGNBIT_POSITIONED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW1]]432; CHECK-NEXT:    [[SIGNEXTENDED:%.*]] = ashr i32 [[SIGNBIT_POSITIONED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW2]]433; CHECK-NEXT:    ret i32 [[SIGNEXTENDED]]434;435  %skip_high = sub i32 64, %nbits1436  call void @use32(i32 %skip_high)437  %skip_high_wide = zext i32 %skip_high to i64438  call void @use64(i64 %skip_high_wide)439  %extracted = lshr i64 %data, %skip_high_wide440  call void @use64(i64 %extracted)441  %extracted_narrow = trunc i64 %extracted to i32442  call void @use32(i32 %extracted_narrow)443  %num_high_bits_to_smear_narrow1 = sub i32 32, %nbits1 ; not %nbits2444  %num_high_bits_to_smear_narrow2 = sub i32 32, %nbits2 ; not %nbits1445  call void @use32(i32 %num_high_bits_to_smear_narrow1)446  call void @use32(i32 %num_high_bits_to_smear_narrow2)447  %signbit_positioned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow1448  %signextended = ashr i32 %signbit_positioned, %num_high_bits_to_smear_narrow2449  ret i32 %signextended450}451 452define i32 @n13(i64 %data, i32 %nbits) {453; CHECK-LABEL: @n13(454; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]455; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])456; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64457; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])458; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]459; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])460; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32461; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])462; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]463; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])464; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 -1, [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]465; CHECK-NEXT:    [[RES:%.*]] = and i32 [[TMP1]], [[EXTRACTED_NARROW]]466; CHECK-NEXT:    ret i32 [[RES]]467;468  %skip_high = sub i32 64, %nbits469  call void @use32(i32 %skip_high)470  %skip_high_wide = zext i32 %skip_high to i64471  call void @use64(i64 %skip_high_wide)472  %extracted = lshr i64 %data, %skip_high_wide473  call void @use64(i64 %extracted)474  %extracted_narrow = trunc i64 %extracted to i32475  call void @use32(i32 %extracted_narrow)476  %num_high_bits_to_smear_narrow = sub i32 32, %nbits477  call void @use32(i32 %num_high_bits_to_smear_narrow)478  %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow479  %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr480  ret i32 %res481}482define i32 @n13_extrause(i64 %data, i32 %nbits) {483; CHECK-LABEL: @n13_extrause(484; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]485; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])486; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64487; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])488; CHECK-NEXT:    [[EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]489; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])490; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32491; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])492; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]493; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])494; CHECK-NEXT:    [[HIGHBITS_CLEANED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]495; CHECK-NEXT:    call void @use32(i32 [[HIGHBITS_CLEANED]])496; CHECK-NEXT:    [[RES:%.*]] = lshr exact i32 [[HIGHBITS_CLEANED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]497; CHECK-NEXT:    ret i32 [[RES]]498;499  %skip_high = sub i32 64, %nbits500  call void @use32(i32 %skip_high)501  %skip_high_wide = zext i32 %skip_high to i64502  call void @use64(i64 %skip_high_wide)503  %extracted = lshr i64 %data, %skip_high_wide504  call void @use64(i64 %extracted)505  %extracted_narrow = trunc i64 %extracted to i32506  call void @use32(i32 %extracted_narrow)507  %num_high_bits_to_smear_narrow = sub i32 32, %nbits508  call void @use32(i32 %num_high_bits_to_smear_narrow)509  %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow510  call void @use32(i32 %highbits_cleaned)511  %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr512  ret i32 %res513}514define i32 @n14(i64 %data, i32 %nbits) {515; CHECK-LABEL: @n14(516; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]517; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])518; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64519; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])520; CHECK-NEXT:    [[EXTRACTED:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]521; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])522; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32523; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])524; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]525; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])526; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 -1, [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]527; CHECK-NEXT:    [[RES:%.*]] = and i32 [[TMP1]], [[EXTRACTED_NARROW]]528; CHECK-NEXT:    ret i32 [[RES]]529;530  %skip_high = sub i32 64, %nbits531  call void @use32(i32 %skip_high)532  %skip_high_wide = zext i32 %skip_high to i64533  call void @use64(i64 %skip_high_wide)534  %extracted = ashr i64 %data, %skip_high_wide535  call void @use64(i64 %extracted)536  %extracted_narrow = trunc i64 %extracted to i32537  call void @use32(i32 %extracted_narrow)538  %num_high_bits_to_smear_narrow = sub i32 32, %nbits539  call void @use32(i32 %num_high_bits_to_smear_narrow)540  %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow541  %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr542  ret i32 %res543}544define i32 @n14_extrause(i64 %data, i32 %nbits) {545; CHECK-LABEL: @n14_extrause(546; CHECK-NEXT:    [[SKIP_HIGH:%.*]] = sub i32 64, [[NBITS:%.*]]547; CHECK-NEXT:    call void @use32(i32 [[SKIP_HIGH]])548; CHECK-NEXT:    [[SKIP_HIGH_WIDE:%.*]] = zext i32 [[SKIP_HIGH]] to i64549; CHECK-NEXT:    call void @use64(i64 [[SKIP_HIGH_WIDE]])550; CHECK-NEXT:    [[EXTRACTED:%.*]] = ashr i64 [[DATA:%.*]], [[SKIP_HIGH_WIDE]]551; CHECK-NEXT:    call void @use64(i64 [[EXTRACTED]])552; CHECK-NEXT:    [[EXTRACTED_NARROW:%.*]] = trunc i64 [[EXTRACTED]] to i32553; CHECK-NEXT:    call void @use32(i32 [[EXTRACTED_NARROW]])554; CHECK-NEXT:    [[NUM_HIGH_BITS_TO_SMEAR_NARROW:%.*]] = sub i32 32, [[NBITS]]555; CHECK-NEXT:    call void @use32(i32 [[NUM_HIGH_BITS_TO_SMEAR_NARROW]])556; CHECK-NEXT:    [[HIGHBITS_CLEANED:%.*]] = shl i32 [[EXTRACTED_NARROW]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]557; CHECK-NEXT:    call void @use32(i32 [[HIGHBITS_CLEANED]])558; CHECK-NEXT:    [[RES:%.*]] = lshr exact i32 [[HIGHBITS_CLEANED]], [[NUM_HIGH_BITS_TO_SMEAR_NARROW]]559; CHECK-NEXT:    ret i32 [[RES]]560;561  %skip_high = sub i32 64, %nbits562  call void @use32(i32 %skip_high)563  %skip_high_wide = zext i32 %skip_high to i64564  call void @use64(i64 %skip_high_wide)565  %extracted = ashr i64 %data, %skip_high_wide566  call void @use64(i64 %extracted)567  %extracted_narrow = trunc i64 %extracted to i32568  call void @use32(i32 %extracted_narrow)569  %num_high_bits_to_smear_narrow = sub i32 32, %nbits570  call void @use32(i32 %num_high_bits_to_smear_narrow)571  %highbits_cleaned = shl i32 %extracted_narrow, %num_high_bits_to_smear_narrow572  call void @use32(i32 %highbits_cleaned)573  %res = lshr i32 %highbits_cleaned, %num_high_bits_to_smear_narrow ; not ashr574  ret i32 %res575}576