1155 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; If we extract (via lshr) some high bits, and then perform their sign-extension5; conditionally depending on whether the extracted value is negative or not6; (i.e. interpreting the highest extracted bit, which was the original signbit7; of the value from which we extracted as a signbit), then we should just8; perform extraction via `ashr`.9 10; Base patterns.11 12declare void @use1(i1)13declare void @use16(i16)14declare void @use32(i32)15declare void @use64(i64)16 17define i32 @t0_notrunc_add(i32 %data, i32 %nbits) {18; CHECK-LABEL: @t0_notrunc_add(19; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]20; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]21; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 022; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]23; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 024; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])25; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])26; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])27; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])28; CHECK-NEXT: call void @use32(i32 [[MAGIC]])29; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]30; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]31;32 %low_bits_to_skip = sub i32 32, %nbits33 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip34 %should_signext = icmp slt i32 %data, 035 %all_bits_except_low_nbits = shl i32 -1, %nbits36 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 037 38 call void @use32(i32 %low_bits_to_skip)39 call void @use32(i32 %high_bits_extracted)40 call void @use1(i1 %should_signext)41 call void @use32(i32 %all_bits_except_low_nbits)42 call void @use32(i32 %magic)43 44 %signextended = add i32 %high_bits_extracted, %magic45 ret i32 %signextended46}47 48define i32 @t0_notrunc_or(i32 %data, i32 %nbits) {49; CHECK-LABEL: @t0_notrunc_or(50; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]51; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]52; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 053; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]54; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 055; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])56; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])57; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])58; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])59; CHECK-NEXT: call void @use32(i32 [[MAGIC]])60; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]61; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]62;63 %low_bits_to_skip = sub i32 32, %nbits64 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip65 %should_signext = icmp slt i32 %data, 066 %all_bits_except_low_nbits = shl i32 -1, %nbits67 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 068 69 call void @use32(i32 %low_bits_to_skip)70 call void @use32(i32 %high_bits_extracted)71 call void @use1(i1 %should_signext)72 call void @use32(i32 %all_bits_except_low_nbits)73 call void @use32(i32 %magic)74 75 %signextended = or i32 %high_bits_extracted, %magic76 ret i32 %signextended77}78 79define i32 @t1_notrunc_sub(i32 %data, i32 %nbits) {80; CHECK-LABEL: @t1_notrunc_sub(81; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]82; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]83; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 084; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]85; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 086; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])87; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])88; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])89; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])90; CHECK-NEXT: call void @use32(i32 [[MAGIC]])91; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]92; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]93;94 %low_bits_to_skip = sub i32 32, %nbits95 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip96 %should_signext = icmp slt i32 %data, 097 %higher_bit_after_signbit = shl i32 1, %nbits98 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 099 100 call void @use32(i32 %low_bits_to_skip)101 call void @use32(i32 %high_bits_extracted)102 call void @use1(i1 %should_signext)103 call void @use32(i32 %higher_bit_after_signbit)104 call void @use32(i32 %magic)105 106 %signextended = sub i32 %high_bits_extracted, %magic107 ret i32 %signextended108}109 110define i32 @t2_trunc_add(i64 %data, i32 %nbits) {111; CHECK-LABEL: @t2_trunc_add(112; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]113; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64114; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]115; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32116; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0117; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]118; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])119; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])120; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])121; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])122; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])123; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])124; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]125; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32126; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]127;128 %low_bits_to_skip = sub i32 64, %nbits129 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64130 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide131 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32132 %should_signext = icmp slt i64 %data, 0133 %all_bits_except_low_nbits = shl i32 -1, %nbits134 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use135 136 call void @use32(i32 %low_bits_to_skip)137 call void @use64(i64 %low_bits_to_skip_wide)138 call void @use64(i64 %high_bits_extracted_wide)139 call void @use32(i32 %high_bits_extracted)140 call void @use1(i1 %should_signext)141 call void @use32(i32 %all_bits_except_low_nbits)142 143 %signextended = add i32 %magic, %high_bits_extracted144 ret i32 %signextended145}146 147define i32 @t2_trunc_or(i64 %data, i32 %nbits) {148; CHECK-LABEL: @t2_trunc_or(149; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]150; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64151; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]152; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32153; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0154; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]155; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])156; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])157; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])158; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])159; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])160; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])161; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]162; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32163; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]164;165 %low_bits_to_skip = sub i32 64, %nbits166 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64167 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide168 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32169 %should_signext = icmp slt i64 %data, 0170 %all_bits_except_low_nbits = shl i32 -1, %nbits171 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use172 173 call void @use32(i32 %low_bits_to_skip)174 call void @use64(i64 %low_bits_to_skip_wide)175 call void @use64(i64 %high_bits_extracted_wide)176 call void @use32(i32 %high_bits_extracted)177 call void @use1(i1 %should_signext)178 call void @use32(i32 %all_bits_except_low_nbits)179 180 %signextended = or i32 %magic, %high_bits_extracted181 ret i32 %signextended182}183 184define i32 @t3_trunc_sub(i64 %data, i32 %nbits) {185; CHECK-LABEL: @t3_trunc_sub(186; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]187; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64188; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]189; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32190; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0191; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]192; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])193; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])194; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])195; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])196; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])197; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])198; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]199; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32200; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]201;202 %low_bits_to_skip = sub i32 64, %nbits203 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64204 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide205 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32206 %should_signext = icmp slt i64 %data, 0207 %higher_bit_after_signbit = shl i32 1, %nbits208 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0 ; one-use209 210 call void @use32(i32 %low_bits_to_skip)211 call void @use64(i64 %low_bits_to_skip_wide)212 call void @use64(i64 %high_bits_extracted_wide)213 call void @use32(i32 %high_bits_extracted)214 call void @use1(i1 %should_signext)215 call void @use32(i32 %higher_bit_after_signbit)216 217 %signextended = sub i32 %high_bits_extracted, %magic218 ret i32 %signextended219}220 221; Commutativity222 223define i32 @t4_commutativity0(i32 %data, i32 %nbits) {224; CHECK-LABEL: @t4_commutativity0(225; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]226; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]227; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0228; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]229; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0230; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])231; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])232; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])233; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])234; CHECK-NEXT: call void @use32(i32 [[MAGIC]])235; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]236; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]237;238 %low_bits_to_skip = sub i32 32, %nbits239 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip240 %should_signext = icmp slt i32 %data, 0241 %all_bits_except_low_nbits = shl i32 -1, %nbits242 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0243 244 call void @use32(i32 %low_bits_to_skip)245 call void @use32(i32 %high_bits_extracted)246 call void @use1(i1 %should_signext)247 call void @use32(i32 %all_bits_except_low_nbits)248 call void @use32(i32 %magic)249 250 %signextended = add i32 %high_bits_extracted, %magic251 ret i32 %signextended252}253define i32 @t5_commutativity1(i32 %data, i32 %nbits) {254; CHECK-LABEL: @t5_commutativity1(255; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]256; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]257; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], -1258; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]259; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]260; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])261; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])262; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])263; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])264; CHECK-NEXT: call void @use32(i32 [[MAGIC]])265; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]266; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]267;268 %low_bits_to_skip = sub i32 32, %nbits269 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip270 %should_signext = icmp sgt i32 %data, -1 ; swapped271 %all_bits_except_low_nbits = shl i32 -1, %nbits272 %magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; swapped273 274 call void @use32(i32 %low_bits_to_skip)275 call void @use32(i32 %high_bits_extracted)276 call void @use1(i1 %should_signext)277 call void @use32(i32 %all_bits_except_low_nbits)278 call void @use32(i32 %magic)279 280 %signextended = add i32 %high_bits_extracted, %magic281 ret i32 %signextended282}283define i32 @t6_commutativity2(i32 %data, i32 %nbits) {284; CHECK-LABEL: @t6_commutativity2(285; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]286; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]287; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0288; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]289; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0290; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])291; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])292; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])293; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])294; CHECK-NEXT: call void @use32(i32 [[MAGIC]])295; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]296; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]297;298 %low_bits_to_skip = sub i32 32, %nbits299 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip300 %should_signext = icmp slt i32 %data, 0301 %all_bits_except_low_nbits = shl i32 -1, %nbits302 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0303 304 call void @use32(i32 %low_bits_to_skip)305 call void @use32(i32 %high_bits_extracted)306 call void @use1(i1 %should_signext)307 call void @use32(i32 %all_bits_except_low_nbits)308 call void @use32(i32 %magic)309 310 %signextended = add i32 %magic, %high_bits_extracted ; swapped311 ret i32 %signextended312}313 314; Extra uses315 316define i32 @t7_trunc_extrause0(i64 %data, i32 %nbits) {317; CHECK-LABEL: @t7_trunc_extrause0(318; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]319; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64320; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]321; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32322; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0323; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]324; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])325; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])326; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])327; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])328; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])329; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])330; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]331; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32332; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]333;334 %low_bits_to_skip = sub i32 64, %nbits335 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64336 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide337 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use338 %should_signext = icmp slt i64 %data, 0339 %all_bits_except_low_nbits = shl i32 -1, %nbits340 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use341 342 call void @use32(i32 %low_bits_to_skip)343 call void @use64(i64 %low_bits_to_skip_wide)344 call void @use64(i64 %high_bits_extracted_wide)345 call void @use32(i32 %high_bits_extracted)346 call void @use1(i1 %should_signext)347 call void @use32(i32 %all_bits_except_low_nbits)348 349 %signextended = add i32 %magic, %high_bits_extracted350 ret i32 %signextended351}352define i32 @t8_trunc_extrause1(i64 %data, i32 %nbits) {353; CHECK-LABEL: @t8_trunc_extrause1(354; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]355; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64356; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]357; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0358; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]359; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0360; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])361; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])362; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])363; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])364; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])365; CHECK-NEXT: call void @use32(i32 [[MAGIC]])366; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]367; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32368; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]369;370 %low_bits_to_skip = sub i32 64, %nbits371 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64372 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide373 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; one-use374 %should_signext = icmp slt i64 %data, 0375 %all_bits_except_low_nbits = shl i32 -1, %nbits376 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use377 378 call void @use32(i32 %low_bits_to_skip)379 call void @use64(i64 %low_bits_to_skip_wide)380 call void @use64(i64 %high_bits_extracted_wide)381 call void @use1(i1 %should_signext)382 call void @use32(i32 %all_bits_except_low_nbits)383 call void @use32(i32 %magic)384 385 %signextended = add i32 %magic, %high_bits_extracted386 ret i32 %signextended387}388define i32 @n9_trunc_extrause2(i64 %data, i32 %nbits) {389; CHECK-LABEL: @n9_trunc_extrause2(390; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]391; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64392; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]393; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32394; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0395; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]396; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0397; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])398; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])399; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])400; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])401; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])402; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])403; CHECK-NEXT: call void @use32(i32 [[MAGIC]])404; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]405; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]406;407 %low_bits_to_skip = sub i32 64, %nbits408 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64409 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide410 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use411 %should_signext = icmp slt i64 %data, 0412 %all_bits_except_low_nbits = shl i32 -1, %nbits413 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use414 415 call void @use32(i32 %low_bits_to_skip)416 call void @use64(i64 %low_bits_to_skip_wide)417 call void @use64(i64 %high_bits_extracted_wide)418 call void @use32(i32 %high_bits_extracted)419 call void @use1(i1 %should_signext)420 call void @use32(i32 %all_bits_except_low_nbits)421 call void @use32(i32 %magic)422 423 %signextended = add i32 %magic, %high_bits_extracted424 ret i32 %signextended425}426 427define i32 @t10_preserve_exact(i32 %data, i32 %nbits) {428; CHECK-LABEL: @t10_preserve_exact(429; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]430; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr exact i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]431; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0432; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]433; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0434; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])435; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])436; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])437; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])438; CHECK-NEXT: call void @use32(i32 [[MAGIC]])439; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr exact i32 [[DATA]], [[LOW_BITS_TO_SKIP]]440; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]441;442 %low_bits_to_skip = sub i32 32, %nbits443 %high_bits_extracted = lshr exact i32 %data, %low_bits_to_skip444 %should_signext = icmp slt i32 %data, 0445 %all_bits_except_low_nbits = shl i32 -1, %nbits446 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0447 448 call void @use32(i32 %low_bits_to_skip)449 call void @use32(i32 %high_bits_extracted)450 call void @use1(i1 %should_signext)451 call void @use32(i32 %all_bits_except_low_nbits)452 call void @use32(i32 %magic)453 454 %signextended = add i32 %high_bits_extracted, %magic455 ret i32 %signextended456}457 458define i32 @t11_different_zext_of_shamt(i32 %data, i8 %nbits) {459; CHECK-LABEL: @t11_different_zext_of_shamt(460; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS:%.*]] to i16461; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i16 32, [[NBITS_16BIT]]462; CHECK-NEXT: [[LOW_BITS_TO_SKIP_32:%.*]] = zext i16 [[LOW_BITS_TO_SKIP]] to i32463; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_32]]464; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0465; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS]] to i32466; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS_32BIT]]467; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0468; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])469; CHECK-NEXT: call void @use16(i16 [[LOW_BITS_TO_SKIP]])470; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP_32]])471; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])472; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])473; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])474; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])475; CHECK-NEXT: call void @use32(i32 [[MAGIC]])476; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP_32]]477; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]478;479 %nbits_16bit = zext i8 %nbits to i16480 %low_bits_to_skip = sub i16 32, %nbits_16bit481 %low_bits_to_skip_32 = zext i16 %low_bits_to_skip to i32482 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip_32483 %should_signext = icmp slt i32 %data, 0484 %nbits_32bit = zext i8 %nbits to i32485 %all_bits_except_low_nbits = shl i32 -1, %nbits_32bit486 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0487 488 call void @use16(i16 %nbits_16bit)489 call void @use16(i16 %low_bits_to_skip)490 call void @use32(i32 %low_bits_to_skip_32)491 call void @use32(i32 %high_bits_extracted)492 call void @use1(i1 %should_signext)493 call void @use32(i32 %nbits_32bit)494 call void @use32(i32 %all_bits_except_low_nbits)495 call void @use32(i32 %magic)496 497 %signextended = add i32 %high_bits_extracted, %magic498 ret i32 %signextended499}500 501define i32 @t12_add_sext_of_magic(i32 %data, i8 %nbits) {502; CHECK-LABEL: @t12_add_sext_of_magic(503; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32504; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]505; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]506; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0507; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16508; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]509; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0510; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32511; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])512; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])513; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])514; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])515; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])516; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])517; CHECK-NEXT: call void @use16(i16 [[MAGIC]])518; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])519; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]520; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]521;522 %nbits_32bit = zext i8 %nbits to i32523 %low_bits_to_skip = sub i32 32, %nbits_32bit524 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip525 %should_signext = icmp slt i32 %data, 0526 %nbits_16bit = zext i8 %nbits to i16527 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit528 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0529 %magic_wide = sext i16 %magic to i32530 531 call void @use32(i32 %nbits_32bit)532 call void @use32(i32 %low_bits_to_skip)533 call void @use32(i32 %high_bits_extracted)534 call void @use1(i1 %should_signext)535 call void @use16(i16 %nbits_16bit)536 call void @use16(i16 %all_bits_except_low_nbits)537 call void @use16(i16 %magic)538 call void @use32(i32 %magic_wide)539 540 %signextended = add i32 %high_bits_extracted, %magic_wide541 ret i32 %signextended542}543 544define i32 @t13_sub_zext_of_magic(i32 %data, i8 %nbits) {545; CHECK-LABEL: @t13_sub_zext_of_magic(546; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32547; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]548; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]549; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0550; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16551; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]552; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0553; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32554; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])555; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])556; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])557; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])558; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])559; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])560; CHECK-NEXT: call void @use16(i16 [[MAGIC]])561; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])562; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]563; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]564;565 %nbits_32bit = zext i8 %nbits to i32566 %low_bits_to_skip = sub i32 32, %nbits_32bit567 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip568 %should_signext = icmp slt i32 %data, 0569 %nbits_16bit = zext i8 %nbits to i16570 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit571 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0572 %magic_wide = zext i16 %magic to i32573 574 call void @use32(i32 %nbits_32bit)575 call void @use32(i32 %low_bits_to_skip)576 call void @use32(i32 %high_bits_extracted)577 call void @use1(i1 %should_signext)578 call void @use16(i16 %nbits_16bit)579 call void @use16(i16 %all_bits_except_low_nbits)580 call void @use16(i16 %magic)581 call void @use32(i32 %magic_wide)582 583 %signextended = sub i32 %high_bits_extracted, %magic_wide584 ret i32 %signextended585}586 587define i32 @t14_add_sext_of_shl(i32 %data, i8 %nbits) {588; CHECK-LABEL: @t14_add_sext_of_shl(589; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32590; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]591; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]592; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0593; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16594; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]595; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = sext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32596; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0597; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])598; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])599; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])600; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])601; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])602; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])603; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]])604; CHECK-NEXT: call void @use32(i32 [[MAGIC]])605; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]606; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]607;608 %nbits_32bit = zext i8 %nbits to i32609 %low_bits_to_skip = sub i32 32, %nbits_32bit610 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip611 %should_signext = icmp slt i32 %data, 0612 %nbits_16bit = zext i8 %nbits to i16613 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit614 %all_bits_except_low_nbits_wide = sext i16 %all_bits_except_low_nbits to i32615 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0616 617 call void @use32(i32 %nbits_32bit)618 call void @use32(i32 %low_bits_to_skip)619 call void @use32(i32 %high_bits_extracted)620 call void @use1(i1 %should_signext)621 call void @use16(i16 %nbits_16bit)622 call void @use16(i16 %all_bits_except_low_nbits)623 call void @use32(i32 %all_bits_except_low_nbits_wide)624 call void @use32(i32 %magic)625 626 %signextended = add i32 %high_bits_extracted, %magic627 ret i32 %signextended628}629 630define i32 @t15_sub_zext_of_shl(i32 %data, i8 %nbits) {631; CHECK-LABEL: @t15_sub_zext_of_shl(632; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32633; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]634; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]635; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0636; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16637; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]638; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = zext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32639; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0640; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])641; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])642; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])643; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])644; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])645; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])646; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]])647; CHECK-NEXT: call void @use32(i32 [[MAGIC]])648; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]649; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]650;651 %nbits_32bit = zext i8 %nbits to i32652 %low_bits_to_skip = sub i32 32, %nbits_32bit653 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip654 %should_signext = icmp slt i32 %data, 0655 %nbits_16bit = zext i8 %nbits to i16656 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit657 %all_bits_except_low_nbits_wide = zext i16 %all_bits_except_low_nbits to i32658 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0659 660 call void @use32(i32 %nbits_32bit)661 call void @use32(i32 %low_bits_to_skip)662 call void @use32(i32 %high_bits_extracted)663 call void @use1(i1 %should_signext)664 call void @use16(i16 %nbits_16bit)665 call void @use16(i16 %all_bits_except_low_nbits)666 call void @use32(i32 %all_bits_except_low_nbits_wide)667 call void @use32(i32 %magic)668 669 %signextended = sub i32 %high_bits_extracted, %magic670 ret i32 %signextended671}672 673; Negative tests.674 675define i32 @n16(i32 %data, i32 %nbits) {676; CHECK-LABEL: @n16(677; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 31, [[NBITS:%.*]]678; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]679; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0680; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]681; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0682; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])683; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])684; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])685; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])686; CHECK-NEXT: call void @use32(i32 [[MAGIC]])687; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]688; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]689;690 %low_bits_to_skip = sub i32 31, %nbits ; not 32691 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip692 %should_signext = icmp slt i32 %data, 0693 %all_bits_except_low_nbits = shl i32 -1, %nbits694 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0695 696 call void @use32(i32 %low_bits_to_skip)697 call void @use32(i32 %high_bits_extracted)698 call void @use1(i1 %should_signext)699 call void @use32(i32 %all_bits_except_low_nbits)700 call void @use32(i32 %magic)701 702 %signextended = add i32 %high_bits_extracted, %magic703 ret i32 %signextended704}705 706define i32 @n17_add(i32 %data, i32 %nbits) {707; CHECK-LABEL: @n17_add(708; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]709; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]710; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0711; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i32 1, [[NBITS]]712; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0713; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])714; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])715; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])716; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])717; CHECK-NEXT: call void @use32(i32 [[MAGIC]])718; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]719; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]720;721 %low_bits_to_skip = sub i32 32, %nbits722 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip723 %should_signext = icmp slt i32 %data, 0724 %all_bits_except_low_nbits = shl i32 1, %nbits ; not -1725 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0726 727 call void @use32(i32 %low_bits_to_skip)728 call void @use32(i32 %high_bits_extracted)729 call void @use1(i1 %should_signext)730 call void @use32(i32 %all_bits_except_low_nbits)731 call void @use32(i32 %magic)732 733 %signextended = add i32 %high_bits_extracted, %magic734 ret i32 %signextended735}736 737define i32 @n18(i32 %data, i32 %nbits) {738; CHECK-LABEL: @n18(739; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]740; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]741; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0742; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]743; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]744; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])745; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])746; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])747; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])748; CHECK-NEXT: call void @use32(i32 [[MAGIC]])749; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]750; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]751;752 %low_bits_to_skip = sub i32 32, %nbits753 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip754 %should_signext = icmp slt i32 %data, 0755 %all_bits_except_low_nbits = shl i32 -1, %nbits756 %magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; wrong order757 758 call void @use32(i32 %low_bits_to_skip)759 call void @use32(i32 %high_bits_extracted)760 call void @use1(i1 %should_signext)761 call void @use32(i32 %all_bits_except_low_nbits)762 call void @use32(i32 %magic)763 764 %signextended = add i32 %high_bits_extracted, %magic765 ret i32 %signextended766}767 768define i32 @n19(i32 %data1, i32 %data2, i32 %nbits) {769; CHECK-LABEL: @n19(770; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]771; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA1:%.*]], [[LOW_BITS_TO_SKIP]]772; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA2:%.*]], 0773; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]774; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0775; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])776; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])777; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])778; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])779; CHECK-NEXT: call void @use32(i32 [[MAGIC]])780; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]781; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]782;783 %low_bits_to_skip = sub i32 32, %nbits784 %high_bits_extracted = lshr i32 %data1, %low_bits_to_skip ; not %data2785 %should_signext = icmp slt i32 %data2, 0 ; not %data1786 %all_bits_except_low_nbits = shl i32 -1, %nbits787 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0788 789 call void @use32(i32 %low_bits_to_skip)790 call void @use32(i32 %high_bits_extracted)791 call void @use1(i1 %should_signext)792 call void @use32(i32 %all_bits_except_low_nbits)793 call void @use32(i32 %magic)794 795 %signextended = add i32 %high_bits_extracted, %magic796 ret i32 %signextended797}798 799define i32 @n20(i32 %data, i32 %nbits1, i32 %nbits2) {800; CHECK-LABEL: @n20(801; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS1:%.*]]802; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]803; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0804; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS2:%.*]]805; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0806; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])807; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])808; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])809; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])810; CHECK-NEXT: call void @use32(i32 [[MAGIC]])811; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]812; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]813;814 %low_bits_to_skip = sub i32 32, %nbits1 ; not %nbits2815 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip816 %should_signext = icmp slt i32 %data, 0817 %all_bits_except_low_nbits = shl i32 -1, %nbits2 ; not %nbits1818 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0819 820 call void @use32(i32 %low_bits_to_skip)821 call void @use32(i32 %high_bits_extracted)822 call void @use1(i1 %should_signext)823 call void @use32(i32 %all_bits_except_low_nbits)824 call void @use32(i32 %magic)825 826 %signextended = add i32 %high_bits_extracted, %magic827 ret i32 %signextended828}829 830define i32 @n21(i32 %data, i32 %nbits) {831; CHECK-LABEL: @n21(832; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]833; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]834; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], 0835; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]836; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0837; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])838; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])839; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])840; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])841; CHECK-NEXT: call void @use32(i32 [[MAGIC]])842; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]843; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]844;845 %low_bits_to_skip = sub i32 32, %nbits846 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip847 %should_signext = icmp sgt i32 %data, 0 ; this isn't a sign bit test848 %all_bits_except_low_nbits = shl i32 -1, %nbits849 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0850 851 call void @use32(i32 %low_bits_to_skip)852 call void @use32(i32 %high_bits_extracted)853 call void @use1(i1 %should_signext)854 call void @use32(i32 %all_bits_except_low_nbits)855 call void @use32(i32 %magic)856 857 %signextended = add i32 %high_bits_extracted, %magic858 ret i32 %signextended859}860 861define i32 @n22(i64 %data, i32 %nbits) {862; CHECK-LABEL: @n22(863; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 63, [[NBITS:%.*]]864; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64865; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]866; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32867; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0868; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]869; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0870; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])871; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])872; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])873; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])874; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])875; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])876; CHECK-NEXT: call void @use32(i32 [[MAGIC]])877; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]878; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]879;880 %low_bits_to_skip = sub i32 63, %nbits ; not 64881 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64882 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide883 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32884 %should_signext = icmp slt i64 %data, 0885 %all_bits_except_low_nbits = shl i32 -1, %nbits886 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0887 888 call void @use32(i32 %low_bits_to_skip)889 call void @use64(i64 %low_bits_to_skip_wide)890 call void @use64(i64 %high_bits_extracted_wide)891 call void @use32(i32 %high_bits_extracted)892 call void @use1(i1 %should_signext)893 call void @use32(i32 %all_bits_except_low_nbits)894 call void @use32(i32 %magic)895 896 %signextended = add i32 %magic, %high_bits_extracted897 ret i32 %signextended898}899 900define i32 @n23(i32 %data, i32 %nbits) {901; CHECK-LABEL: @n23(902; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]903; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = ashr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]904; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0905; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]906; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0907; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])908; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])909; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])910; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])911; CHECK-NEXT: call void @use32(i32 [[MAGIC]])912; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]913; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]914;915 %low_bits_to_skip = sub i32 32, %nbits916 %high_bits_extracted = ashr i32 %data, %low_bits_to_skip ; not `lshr`917 %should_signext = icmp slt i32 %data, 0918 %all_bits_except_low_nbits = shl i32 -1, %nbits919 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0920 921 call void @use32(i32 %low_bits_to_skip)922 call void @use32(i32 %high_bits_extracted)923 call void @use1(i1 %should_signext)924 call void @use32(i32 %all_bits_except_low_nbits)925 call void @use32(i32 %magic)926 927 %signextended = add i32 %high_bits_extracted, %magic928 ret i32 %signextended929}930 931define i32 @n24(i32 %data, i32 %nbits) {932; CHECK-LABEL: @n24(933; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]934; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]935; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0936; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nuw i32 1, [[NBITS]]937; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0938; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])939; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])940; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])941; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])942; CHECK-NEXT: call void @use32(i32 [[MAGIC]])943; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]944; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]945;946 %low_bits_to_skip = sub i32 32, %nbits947 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip948 %should_signext = icmp slt i32 %data, 0949 %higher_bit_after_signbit = shl i32 1, %nbits950 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0951 952 call void @use32(i32 %low_bits_to_skip)953 call void @use32(i32 %high_bits_extracted)954 call void @use1(i1 %should_signext)955 call void @use32(i32 %higher_bit_after_signbit)956 call void @use32(i32 %magic)957 958 %signextended = sub i32 %magic, %high_bits_extracted ; wrong order; `sub` is not commutative959 ret i32 %signextended960}961 962define i32 @n25_sub(i32 %data, i32 %nbits) {963; CHECK-LABEL: @n25_sub(964; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]965; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]966; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0967; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nsw i32 -1, [[NBITS]]968; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0969; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])970; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])971; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])972; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])973; CHECK-NEXT: call void @use32(i32 [[MAGIC]])974; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]975; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]976;977 %low_bits_to_skip = sub i32 32, %nbits978 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip979 %should_signext = icmp slt i32 %data, 0980 %higher_bit_after_signbit = shl i32 -1, %nbits ; not 1981 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0982 983 call void @use32(i32 %low_bits_to_skip)984 call void @use32(i32 %high_bits_extracted)985 call void @use1(i1 %should_signext)986 call void @use32(i32 %higher_bit_after_signbit)987 call void @use32(i32 %magic)988 989 %signextended = sub i32 %high_bits_extracted, %magic990 ret i32 %signextended991}992 993define i32 @n26(i32 %data, i32 %nbits) {994; CHECK-LABEL: @n26(995; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]996; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]997; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0998; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]999; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 -11000; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])1001; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])1002; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])1003; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])1004; CHECK-NEXT: call void @use32(i32 [[MAGIC]])1005; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]1006; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]1007;1008 %low_bits_to_skip = sub i32 32, %nbits1009 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip1010 %should_signext = icmp slt i32 %data, 01011 %all_bits_except_low_nbits = shl i32 -1, %nbits1012 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 -1 ; not 01013 1014 call void @use32(i32 %low_bits_to_skip)1015 call void @use32(i32 %high_bits_extracted)1016 call void @use1(i1 %should_signext)1017 call void @use32(i32 %all_bits_except_low_nbits)1018 call void @use32(i32 %magic)1019 1020 %signextended = add i32 %high_bits_extracted, %magic1021 ret i32 %signextended1022}1023 1024define i32 @n27_add_zext_of_magic(i32 %data, i8 %nbits) {1025; CHECK-LABEL: @n27_add_zext_of_magic(1026; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i321027; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]1028; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]1029; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 01030; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i161031; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]1032; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 01033; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i321034; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])1035; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])1036; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])1037; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])1038; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])1039; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])1040; CHECK-NEXT: call void @use16(i16 [[MAGIC]])1041; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])1042; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC_WIDE]]1043; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]1044;1045 %nbits_32bit = zext i8 %nbits to i321046 %low_bits_to_skip = sub i32 32, %nbits_32bit1047 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip1048 %should_signext = icmp slt i32 %data, 01049 %nbits_16bit = zext i8 %nbits to i161050 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit1051 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 01052 %magic_wide = zext i16 %magic to i32 ; not sext1053 1054 call void @use32(i32 %nbits_32bit)1055 call void @use32(i32 %low_bits_to_skip)1056 call void @use32(i32 %high_bits_extracted)1057 call void @use1(i1 %should_signext)1058 call void @use16(i16 %nbits_16bit)1059 call void @use16(i16 %all_bits_except_low_nbits)1060 call void @use16(i16 %magic)1061 call void @use32(i32 %magic_wide)1062 1063 %signextended = add i32 %high_bits_extracted, %magic_wide1064 ret i32 %signextended1065}1066 1067define i32 @n28_sub_sext_of_magic(i32 %data, i8 %nbits) {1068; CHECK-LABEL: @n28_sub_sext_of_magic(1069; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i321070; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]1071; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]1072; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 01073; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i161074; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i16 1, [[NBITS_16BIT]]1075; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 01076; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i321077; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])1078; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])1079; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])1080; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])1081; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])1082; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])1083; CHECK-NEXT: call void @use16(i16 [[MAGIC]])1084; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])1085; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC_WIDE]]1086; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]1087;1088 %nbits_32bit = zext i8 %nbits to i321089 %low_bits_to_skip = sub i32 32, %nbits_32bit1090 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip1091 %should_signext = icmp slt i32 %data, 01092 %nbits_16bit = zext i8 %nbits to i161093 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit1094 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 01095 %magic_wide = sext i16 %magic to i32 ; not zext1096 1097 call void @use32(i32 %nbits_32bit)1098 call void @use32(i32 %low_bits_to_skip)1099 call void @use32(i32 %high_bits_extracted)1100 call void @use1(i1 %should_signext)1101 call void @use16(i16 %nbits_16bit)1102 call void @use16(i16 %all_bits_except_low_nbits)1103 call void @use16(i16 %magic)1104 call void @use32(i32 %magic_wide)1105 1106 %signextended = sub i32 %high_bits_extracted, %magic_wide1107 ret i32 %signextended1108}1109 1110define i32 @n290_or_with_wrong_magic(i32 %data, i32 %nbits) {1111; CHECK-LABEL: @n290_or_with_wrong_magic(1112; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]1113; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]1114; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 01115; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nuw i32 1, [[NBITS]]1116; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 01117; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])1118; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])1119; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])1120; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])1121; CHECK-NEXT: call void @use32(i32 [[MAGIC]])1122; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]1123; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]1124;1125 %low_bits_to_skip = sub i32 32, %nbits1126 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip1127 %should_signext = icmp slt i32 %data, 01128 %all_bits_except_low_nbits = shl i32 1, %nbits ; not -11129 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 01130 1131 call void @use32(i32 %low_bits_to_skip)1132 call void @use32(i32 %high_bits_extracted)1133 call void @use1(i1 %should_signext)1134 call void @use32(i32 %all_bits_except_low_nbits)1135 call void @use32(i32 %magic)1136 1137 %signextended = or i32 %high_bits_extracted, %magic1138 ret i32 %signextended1139}1140 1141define i32 @bitwidth_does_not_fit(i3 %arg) {1142; CHECK-LABEL: @bitwidth_does_not_fit(1143; CHECK-NEXT: [[NEG:%.*]] = sub i3 0, [[ARG:%.*]]1144; CHECK-NEXT: [[NEG_EXT:%.*]] = zext i3 [[NEG]] to i321145; CHECK-NEXT: [[SHR:%.*]] = lshr i32 1, [[NEG_EXT]]1146; CHECK-NEXT: [[INC:%.*]] = add nuw nsw i32 [[SHR]], 11147; CHECK-NEXT: ret i32 [[INC]]1148;1149 %neg = sub i3 0, %arg1150 %neg.ext = zext i3 %neg to i321151 %shr = lshr i32 1, %neg.ext1152 %inc = add i32 %shr, 11153 ret i32 %inc1154}1155