1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; If we extract (via lshr) some high bits, and then perform their sign-extension 5; conditionally depending on whether the extracted value is negative or not 6; (i.e. interpreting the highest extracted bit, which was the original signbit 7; of the value from which we extracted as a signbit), then we should just 8; 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]], 0 22; 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 0 24; 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, %nbits 33 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 34 %should_signext = icmp slt i32 %data, 0 35 %all_bits_except_low_nbits = shl i32 -1, %nbits 36 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 37 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, %magic 45 ret i32 %signextended 46} 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]], 0 53; 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 0 55; 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, %nbits 64 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 65 %should_signext = icmp slt i32 %data, 0 66 %all_bits_except_low_nbits = shl i32 -1, %nbits 67 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 68 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, %magic 76 ret i32 %signextended 77} 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]], 0 84; 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 0 86; 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, %nbits 95 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 96 %should_signext = icmp slt i32 %data, 0 97 %higher_bit_after_signbit = shl i32 1, %nbits 98 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0 99 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, %magic 107 ret i32 %signextended 108} 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 i64 114; 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 i32 116; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0 117; 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 i32 126; CHECK-NEXT: ret i32 [[SIGNEXTENDED]] 127; 128 %low_bits_to_skip = sub i32 64, %nbits 129 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64 130 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide 131 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 132 %should_signext = icmp slt i64 %data, 0 133 %all_bits_except_low_nbits = shl i32 -1, %nbits 134 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use 135 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_extracted 144 ret i32 %signextended 145} 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 i64 151; 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 i32 153; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0 154; 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 i32 163; CHECK-NEXT: ret i32 [[SIGNEXTENDED]] 164; 165 %low_bits_to_skip = sub i32 64, %nbits 166 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64 167 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide 168 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 169 %should_signext = icmp slt i64 %data, 0 170 %all_bits_except_low_nbits = shl i32 -1, %nbits 171 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use 172 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_extracted 181 ret i32 %signextended 182} 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 i64 188; 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 i32 190; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0 191; 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 i32 200; CHECK-NEXT: ret i32 [[SIGNEXTENDED]] 201; 202 %low_bits_to_skip = sub i32 64, %nbits 203 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64 204 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide 205 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 206 %should_signext = icmp slt i64 %data, 0 207 %higher_bit_after_signbit = shl i32 1, %nbits 208 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0 ; one-use 209 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, %magic 218 ret i32 %signextended 219} 220 221; Commutativity 222 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]], 0 228; 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 0 230; 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, %nbits 239 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 240 %should_signext = icmp slt i32 %data, 0 241 %all_bits_except_low_nbits = shl i32 -1, %nbits 242 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 243 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, %magic 251 ret i32 %signextended 252} 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]], -1 258; 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, %nbits 269 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 270 %should_signext = icmp sgt i32 %data, -1 ; swapped 271 %all_bits_except_low_nbits = shl i32 -1, %nbits 272 %magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; swapped 273 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, %magic 281 ret i32 %signextended 282} 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]], 0 288; 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 0 290; 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, %nbits 299 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 300 %should_signext = icmp slt i32 %data, 0 301 %all_bits_except_low_nbits = shl i32 -1, %nbits 302 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 303 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 ; swapped 311 ret i32 %signextended 312} 313 314; Extra uses 315 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 i64 320; 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 i32 322; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0 323; 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 i32 332; CHECK-NEXT: ret i32 [[SIGNEXTENDED]] 333; 334 %low_bits_to_skip = sub i32 64, %nbits 335 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64 336 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide 337 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use 338 %should_signext = icmp slt i64 %data, 0 339 %all_bits_except_low_nbits = shl i32 -1, %nbits 340 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use 341 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_extracted 350 ret i32 %signextended 351} 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 i64 356; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]] 357; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0 358; 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 0 360; 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 i32 368; CHECK-NEXT: ret i32 [[SIGNEXTENDED]] 369; 370 %low_bits_to_skip = sub i32 64, %nbits 371 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64 372 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide 373 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; one-use 374 %should_signext = icmp slt i64 %data, 0 375 %all_bits_except_low_nbits = shl i32 -1, %nbits 376 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use 377 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_extracted 386 ret i32 %signextended 387} 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 i64 392; 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 i32 394; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0 395; 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 0 397; 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, %nbits 408 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64 409 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide 410 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use 411 %should_signext = icmp slt i64 %data, 0 412 %all_bits_except_low_nbits = shl i32 -1, %nbits 413 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use 414 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_extracted 424 ret i32 %signextended 425} 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]], 0 432; 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 0 434; 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, %nbits 443 %high_bits_extracted = lshr exact i32 %data, %low_bits_to_skip 444 %should_signext = icmp slt i32 %data, 0 445 %all_bits_except_low_nbits = shl i32 -1, %nbits 446 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 447 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, %magic 455 ret i32 %signextended 456} 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 i16 461; 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 i32 463; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_32]] 464; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0 465; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS]] to i32 466; 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 0 468; 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 i16 480 %low_bits_to_skip = sub i16 32, %nbits_16bit 481 %low_bits_to_skip_32 = zext i16 %low_bits_to_skip to i32 482 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip_32 483 %should_signext = icmp slt i32 %data, 0 484 %nbits_32bit = zext i8 %nbits to i32 485 %all_bits_except_low_nbits = shl i32 -1, %nbits_32bit 486 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 487 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, %magic 498 ret i32 %signextended 499} 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 i32 504; 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]], 0 507; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16 508; 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 0 510; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32 511; 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 i32 523 %low_bits_to_skip = sub i32 32, %nbits_32bit 524 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 525 %should_signext = icmp slt i32 %data, 0 526 %nbits_16bit = zext i8 %nbits to i16 527 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit 528 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0 529 %magic_wide = sext i16 %magic to i32 530 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_wide 541 ret i32 %signextended 542} 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 i32 547; 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]], 0 550; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16 551; 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 0 553; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32 554; 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 i32 566 %low_bits_to_skip = sub i32 32, %nbits_32bit 567 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 568 %should_signext = icmp slt i32 %data, 0 569 %nbits_16bit = zext i8 %nbits to i16 570 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit 571 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0 572 %magic_wide = zext i16 %magic to i32 573 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_wide 584 ret i32 %signextended 585} 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 i32 590; 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]], 0 593; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16 594; 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 i32 596; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0 597; 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 i32 609 %low_bits_to_skip = sub i32 32, %nbits_32bit 610 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 611 %should_signext = icmp slt i32 %data, 0 612 %nbits_16bit = zext i8 %nbits to i16 613 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit 614 %all_bits_except_low_nbits_wide = sext i16 %all_bits_except_low_nbits to i32 615 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0 616 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, %magic 627 ret i32 %signextended 628} 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 i32 633; 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]], 0 636; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16 637; 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 i32 639; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0 640; 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 i32 652 %low_bits_to_skip = sub i32 32, %nbits_32bit 653 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 654 %should_signext = icmp slt i32 %data, 0 655 %nbits_16bit = zext i8 %nbits to i16 656 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit 657 %all_bits_except_low_nbits_wide = zext i16 %all_bits_except_low_nbits to i32 658 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0 659 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, %magic 670 ret i32 %signextended 671} 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]], 0 680; 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 0 682; 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 32 691 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 692 %should_signext = icmp slt i32 %data, 0 693 %all_bits_except_low_nbits = shl i32 -1, %nbits 694 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 695 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, %magic 703 ret i32 %signextended 704} 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]], 0 711; 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 0 713; 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, %nbits 722 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 723 %should_signext = icmp slt i32 %data, 0 724 %all_bits_except_low_nbits = shl i32 1, %nbits ; not -1 725 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 726 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, %magic 734 ret i32 %signextended 735} 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]], 0 742; 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, %nbits 753 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 754 %should_signext = icmp slt i32 %data, 0 755 %all_bits_except_low_nbits = shl i32 -1, %nbits 756 %magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; wrong order 757 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, %magic 765 ret i32 %signextended 766} 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:%.*]], 0 773; 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 0 775; 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, %nbits 784 %high_bits_extracted = lshr i32 %data1, %low_bits_to_skip ; not %data2 785 %should_signext = icmp slt i32 %data2, 0 ; not %data1 786 %all_bits_except_low_nbits = shl i32 -1, %nbits 787 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 788 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, %magic 796 ret i32 %signextended 797} 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]], 0 804; 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 0 806; 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 %nbits2 815 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 816 %should_signext = icmp slt i32 %data, 0 817 %all_bits_except_low_nbits = shl i32 -1, %nbits2 ; not %nbits1 818 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 819 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, %magic 827 ret i32 %signextended 828} 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]], 0 835; 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 0 837; 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, %nbits 846 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 847 %should_signext = icmp sgt i32 %data, 0 ; this isn't a sign bit test 848 %all_bits_except_low_nbits = shl i32 -1, %nbits 849 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 850 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, %magic 858 ret i32 %signextended 859} 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 i64 865; 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 i32 867; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0 868; 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 0 870; 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 64 881 %low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64 882 %high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide 883 %high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 884 %should_signext = icmp slt i64 %data, 0 885 %all_bits_except_low_nbits = shl i32 -1, %nbits 886 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 887 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_extracted 897 ret i32 %signextended 898} 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]], 0 905; 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 0 907; 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, %nbits 916 %high_bits_extracted = ashr i32 %data, %low_bits_to_skip ; not `lshr` 917 %should_signext = icmp slt i32 %data, 0 918 %all_bits_except_low_nbits = shl i32 -1, %nbits 919 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 920 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, %magic 928 ret i32 %signextended 929} 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]], 0 936; 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 0 938; 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, %nbits 947 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 948 %should_signext = icmp slt i32 %data, 0 949 %higher_bit_after_signbit = shl i32 1, %nbits 950 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0 951 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 commutative 959 ret i32 %signextended 960} 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]], 0 967; 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 0 969; 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, %nbits 978 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 979 %should_signext = icmp slt i32 %data, 0 980 %higher_bit_after_signbit = shl i32 -1, %nbits ; not 1 981 %magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0 982 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, %magic 990 ret i32 %signextended 991} 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]], 0 998; 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 -1 1000; 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, %nbits 1009 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 1010 %should_signext = icmp slt i32 %data, 0 1011 %all_bits_except_low_nbits = shl i32 -1, %nbits 1012 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 -1 ; not 0 1013 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, %magic 1021 ret i32 %signextended 1022} 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 i32 1027; 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]], 0 1030; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16 1031; 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 0 1033; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32 1034; 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 i32 1046 %low_bits_to_skip = sub i32 32, %nbits_32bit 1047 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 1048 %should_signext = icmp slt i32 %data, 0 1049 %nbits_16bit = zext i8 %nbits to i16 1050 %all_bits_except_low_nbits = shl i16 -1, %nbits_16bit 1051 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0 1052 %magic_wide = zext i16 %magic to i32 ; not sext 1053 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_wide 1064 ret i32 %signextended 1065} 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 i32 1070; 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]], 0 1073; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16 1074; 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 0 1076; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32 1077; 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 i32 1089 %low_bits_to_skip = sub i32 32, %nbits_32bit 1090 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 1091 %should_signext = icmp slt i32 %data, 0 1092 %nbits_16bit = zext i8 %nbits to i16 1093 %all_bits_except_low_nbits = shl i16 1, %nbits_16bit 1094 %magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0 1095 %magic_wide = sext i16 %magic to i32 ; not zext 1096 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_wide 1107 ret i32 %signextended 1108} 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]], 0 1115; 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 0 1117; 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, %nbits 1126 %high_bits_extracted = lshr i32 %data, %low_bits_to_skip 1127 %should_signext = icmp slt i32 %data, 0 1128 %all_bits_except_low_nbits = shl i32 1, %nbits ; not -1 1129 %magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 1130 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, %magic 1138 ret i32 %signextended 1139} 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 i32 1145; CHECK-NEXT: [[SHR:%.*]] = lshr i32 1, [[NEG_EXT]] 1146; CHECK-NEXT: [[INC:%.*]] = add nuw nsw i32 [[SHR]], 1 1147; CHECK-NEXT: ret i32 [[INC]] 1148; 1149 %neg = sub i3 0, %arg 1150 %neg.ext = zext i3 %neg to i32 1151 %shr = lshr i32 1, %neg.ext 1152 %inc = add i32 %shr, 1 1153 ret i32 %inc 1154} 1155