1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; This test makes sure that these instructions are properly eliminated. 3; 4; RUN: opt < %s -passes=instcombine -S | FileCheck %s 5 6declare void @use(i8) 7 8define i32 @shl_C1_add_A_C2_i32(i16 %A) { 9; CHECK-LABEL: @shl_C1_add_A_C2_i32( 10; CHECK-NEXT: [[B:%.*]] = zext i16 [[A:%.*]] to i32 11; CHECK-NEXT: [[D:%.*]] = shl i32 192, [[B]] 12; CHECK-NEXT: ret i32 [[D]] 13; 14 %B = zext i16 %A to i32 15 %C = add i32 %B, 5 16 %D = shl i32 6, %C 17 ret i32 %D 18} 19 20define i32 @ashr_C1_add_A_C2_i32(i32 %A) { 21; CHECK-LABEL: @ashr_C1_add_A_C2_i32( 22; CHECK-NEXT: ret i32 0 23; 24 %B = and i32 %A, 65535 25 %C = add i32 %B, 5 26 %D = ashr i32 6, %C 27 ret i32 %D 28} 29 30define i32 @lshr_C1_add_A_C2_i32(i32 %A) { 31; CHECK-LABEL: @lshr_C1_add_A_C2_i32( 32; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], 65535 33; CHECK-NEXT: [[D:%.*]] = shl i32 192, [[B]] 34; CHECK-NEXT: ret i32 [[D]] 35; 36 %B = and i32 %A, 65535 37 %C = add i32 %B, 5 38 %D = shl i32 6, %C 39 ret i32 %D 40} 41 42define <4 x i32> @shl_C1_add_A_C2_v4i32(<4 x i16> %A) { 43; CHECK-LABEL: @shl_C1_add_A_C2_v4i32( 44; CHECK-NEXT: [[B:%.*]] = zext <4 x i16> [[A:%.*]] to <4 x i32> 45; CHECK-NEXT: [[D:%.*]] = shl <4 x i32> <i32 6, i32 4, i32 poison, i32 -458752>, [[B]] 46; CHECK-NEXT: ret <4 x i32> [[D]] 47; 48 %B = zext <4 x i16> %A to <4 x i32> 49 %C = add <4 x i32> %B, <i32 0, i32 1, i32 50, i32 16> 50 %D = shl <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %C 51 ret <4 x i32> %D 52} 53 54define <4 x i32> @ashr_C1_add_A_C2_v4i32(<4 x i32> %A) { 55; CHECK-LABEL: @ashr_C1_add_A_C2_v4i32( 56; CHECK-NEXT: [[B:%.*]] = and <4 x i32> [[A:%.*]], <i32 0, i32 15, i32 255, i32 65535> 57; CHECK-NEXT: [[D:%.*]] = ashr <4 x i32> <i32 6, i32 1, i32 poison, i32 -1>, [[B]] 58; CHECK-NEXT: ret <4 x i32> [[D]] 59; 60 %B = and <4 x i32> %A, <i32 0, i32 15, i32 255, i32 65535> 61 %C = add <4 x i32> %B, <i32 0, i32 1, i32 50, i32 16> 62 %D = ashr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %C 63 ret <4 x i32> %D 64} 65 66define <4 x i32> @lshr_C1_add_A_C2_v4i32(<4 x i32> %A) { 67; CHECK-LABEL: @lshr_C1_add_A_C2_v4i32( 68; CHECK-NEXT: [[B:%.*]] = and <4 x i32> [[A:%.*]], <i32 0, i32 15, i32 255, i32 65535> 69; CHECK-NEXT: [[D:%.*]] = lshr <4 x i32> <i32 6, i32 1, i32 poison, i32 65535>, [[B]] 70; CHECK-NEXT: ret <4 x i32> [[D]] 71; 72 %B = and <4 x i32> %A, <i32 0, i32 15, i32 255, i32 65535> 73 %C = add <4 x i32> %B, <i32 0, i32 1, i32 50, i32 16> 74 %D = lshr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %C 75 ret <4 x i32> %D 76} 77 78define <4 x i32> @shl_C1_add_A_C2_v4i32_splat(i16 %I) { 79; CHECK-LABEL: @shl_C1_add_A_C2_v4i32_splat( 80; CHECK-NEXT: [[A:%.*]] = zext i16 [[I:%.*]] to i32 81; CHECK-NEXT: [[B:%.*]] = insertelement <4 x i32> undef, i32 [[A]], i64 0 82; CHECK-NEXT: [[C:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> undef, <4 x i32> zeroinitializer 83; CHECK-NEXT: [[E:%.*]] = shl <4 x i32> <i32 6, i32 4, i32 poison, i32 -458752>, [[C]] 84; CHECK-NEXT: ret <4 x i32> [[E]] 85; 86 %A = zext i16 %I to i32 87 %B = insertelement <4 x i32> undef, i32 %A, i32 0 88 %C = shufflevector <4 x i32> %B, <4 x i32> undef, <4 x i32> zeroinitializer 89 %D = add <4 x i32> %C, <i32 0, i32 1, i32 50, i32 16> 90 %E = shl <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %D 91 ret <4 x i32> %E 92} 93 94define <4 x i32> @ashr_C1_add_A_C2_v4i32_splat(i16 %I) { 95; CHECK-LABEL: @ashr_C1_add_A_C2_v4i32_splat( 96; CHECK-NEXT: [[A:%.*]] = zext i16 [[I:%.*]] to i32 97; CHECK-NEXT: [[B:%.*]] = insertelement <4 x i32> undef, i32 [[A]], i64 0 98; CHECK-NEXT: [[C:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> undef, <4 x i32> zeroinitializer 99; CHECK-NEXT: [[E:%.*]] = ashr <4 x i32> <i32 6, i32 1, i32 poison, i32 -1>, [[C]] 100; CHECK-NEXT: ret <4 x i32> [[E]] 101; 102 %A = zext i16 %I to i32 103 %B = insertelement <4 x i32> undef, i32 %A, i32 0 104 %C = shufflevector <4 x i32> %B, <4 x i32> undef, <4 x i32> zeroinitializer 105 %D = add <4 x i32> %C, <i32 0, i32 1, i32 50, i32 16> 106 %E = ashr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %D 107 ret <4 x i32> %E 108} 109 110define <4 x i32> @lshr_C1_add_A_C2_v4i32_splat(i16 %I) { 111; CHECK-LABEL: @lshr_C1_add_A_C2_v4i32_splat( 112; CHECK-NEXT: [[A:%.*]] = zext i16 [[I:%.*]] to i32 113; CHECK-NEXT: [[B:%.*]] = insertelement <4 x i32> undef, i32 [[A]], i64 0 114; CHECK-NEXT: [[C:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> undef, <4 x i32> zeroinitializer 115; CHECK-NEXT: [[E:%.*]] = lshr <4 x i32> <i32 6, i32 1, i32 poison, i32 65535>, [[C]] 116; CHECK-NEXT: ret <4 x i32> [[E]] 117; 118 %A = zext i16 %I to i32 119 %B = insertelement <4 x i32> undef, i32 %A, i32 0 120 %C = shufflevector <4 x i32> %B, <4 x i32> undef, <4 x i32> zeroinitializer 121 %D = add <4 x i32> %C, <i32 0, i32 1, i32 50, i32 16> 122 %E = lshr <4 x i32> <i32 6, i32 2, i32 1, i32 -7>, %D 123 ret <4 x i32> %E 124} 125 126define i32 @shl_add_nuw(i32 %x) { 127; CHECK-LABEL: @shl_add_nuw( 128; CHECK-NEXT: [[R:%.*]] = shl i32 192, [[X:%.*]] 129; CHECK-NEXT: ret i32 [[R]] 130; 131 %a = add nuw i32 %x, 5 132 %r = shl i32 6, %a 133 ret i32 %r 134} 135 136; vectors with arbitrary constants work too 137 138define <2 x i12> @lshr_add_nuw(<2 x i12> %x) { 139; CHECK-LABEL: @lshr_add_nuw( 140; CHECK-NEXT: [[R:%.*]] = lshr <2 x i12> <i12 0, i12 21>, [[X:%.*]] 141; CHECK-NEXT: ret <2 x i12> [[R]] 142; 143 %a = add nuw <2 x i12> %x, <i12 5, i12 1> 144 %r = lshr <2 x i12> <i12 6, i12 42>, %a 145 ret <2 x i12> %r 146} 147 148; extra use is ok and in this case the result can be simplified to a constant 149 150define i32 @ashr_add_nuw(i32 %x, i32* %p) { 151; CHECK-LABEL: @ashr_add_nuw( 152; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 5 153; CHECK-NEXT: store i32 [[A]], i32* [[P:%.*]], align 4 154; CHECK-NEXT: ret i32 -1 155; 156 %a = add nuw i32 %x, 5 157 store i32 %a, i32* %p 158 %r = ashr i32 -6, %a 159 ret i32 %r 160} 161 162; negative test - must have 'nuw' 163 164define i32 @shl_add_nsw(i32 %x) { 165; CHECK-LABEL: @shl_add_nsw( 166; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 5 167; CHECK-NEXT: [[R:%.*]] = shl i32 6, [[A]] 168; CHECK-NEXT: ret i32 [[R]] 169; 170 %a = add nsw i32 %x, 5 171 %r = shl i32 6, %a 172 ret i32 %r 173} 174 175; offset precondition check (must be negative constant) for lshr_exact_add_negative_shift_positive 176 177define i32 @lshr_exact_add_positive_shift_positive(i32 %x) { 178; CHECK-LABEL: @lshr_exact_add_positive_shift_positive( 179; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 1 180; CHECK-NEXT: [[R:%.*]] = lshr exact i32 2, [[A]] 181; CHECK-NEXT: ret i32 [[R]] 182; 183 %a = add i32 %x, 1 184 %r = lshr exact i32 2, %a 185 ret i32 %r 186} 187 188define i32 @lshr_exact_add_big_negative_offset(i32 %x) { 189; CHECK-LABEL: @lshr_exact_add_big_negative_offset( 190; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], -33 191; CHECK-NEXT: [[R:%.*]] = lshr exact i32 2, [[A]] 192; CHECK-NEXT: ret i32 [[R]] 193; 194 %a = add i32 %x, -33 195 %r = lshr exact i32 2, %a 196 ret i32 %r 197} 198 199; leading zeros for shifted constant precondition check for lshr_exact_add_negative_shift_positive 200 201define i32 @lshr_exact_add_negative_shift_negative(i32 %x) { 202; CHECK-LABEL: @lshr_exact_add_negative_shift_negative( 203; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], -1 204; CHECK-NEXT: [[R:%.*]] = lshr exact i32 -2, [[A]] 205; CHECK-NEXT: ret i32 [[R]] 206; 207 %a = add i32 %x, -1 208 %r = lshr exact i32 -2, %a 209 ret i32 %r 210} 211 212; exact precondition check for lshr_exact_add_negative_shift_positive 213 214define i32 @lshr_add_negative_shift_no_exact(i32 %x) { 215; CHECK-LABEL: @lshr_add_negative_shift_no_exact( 216; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], -1 217; CHECK-NEXT: [[R:%.*]] = lshr i32 2, [[A]] 218; CHECK-NEXT: ret i32 [[R]] 219; 220 %a = add i32 %x, -1 221 %r = lshr i32 2, %a 222 ret i32 %r 223} 224 225define i32 @lshr_exact_add_negative_shift_positive(i32 %x) { 226; CHECK-LABEL: @lshr_exact_add_negative_shift_positive( 227; CHECK-NEXT: [[R:%.*]] = lshr exact i32 4, [[X:%.*]] 228; CHECK-NEXT: ret i32 [[R]] 229; 230 %a = add i32 %x, -1 231 %r = lshr exact i32 2, %a 232 ret i32 %r 233} 234 235define i8 @lshr_exact_add_negative_shift_positive_extra_use(i8 %x) { 236; CHECK-LABEL: @lshr_exact_add_negative_shift_positive_extra_use( 237; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], -1 238; CHECK-NEXT: call void @use(i8 [[A]]) 239; CHECK-NEXT: [[R:%.*]] = lshr exact i8 -128, [[X]] 240; CHECK-NEXT: ret i8 [[R]] 241; 242 %a = add i8 %x, -1 243 call void @use(i8 %a) 244 %r = lshr exact i8 64, %a 245 ret i8 %r 246} 247 248define <2 x i9> @lshr_exact_add_negative_shift_positive_vec(<2 x i9> %x) { 249; CHECK-LABEL: @lshr_exact_add_negative_shift_positive_vec( 250; CHECK-NEXT: [[R:%.*]] = lshr exact <2 x i9> <i9 -256, i9 -256>, [[X:%.*]] 251; CHECK-NEXT: ret <2 x i9> [[R]] 252; 253 %a = add <2 x i9> %x, <i9 -7, i9 -7> 254 %r = lshr exact <2 x i9> <i9 2, i9 2>, %a 255 ret <2 x i9> %r 256} 257 258; not enough leading zeros in shift constant 259 260define <2 x i9> @lshr_exact_add_negative_shift_lzcnt(<2 x i9> %x) { 261; CHECK-LABEL: @lshr_exact_add_negative_shift_lzcnt( 262; CHECK-NEXT: [[A:%.*]] = add <2 x i9> [[X:%.*]], <i9 -7, i9 -7> 263; CHECK-NEXT: [[R:%.*]] = lshr exact <2 x i9> <i9 4, i9 4>, [[A]] 264; CHECK-NEXT: ret <2 x i9> [[R]] 265; 266 %a = add <2 x i9> %x, <i9 -7, i9 -7> 267 %r = lshr exact <2 x i9> <i9 4, i9 4>, %a 268 ret <2 x i9> %r 269} 270 271; leading ones precondition check for ashr_exact_add_negative_shift_[positive,negative] 272 273define i8 @ashr_exact_add_negative_shift_no_trailing_zeros(i8 %x) { 274; CHECK-LABEL: @ashr_exact_add_negative_shift_no_trailing_zeros( 275; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], -4 276; CHECK-NEXT: [[R:%.*]] = ashr exact i8 -112, [[A]] 277; CHECK-NEXT: ret i8 [[R]] 278; 279 %a = add i8 %x, -4 280 %r = ashr exact i8 -112, %a ; 0b1001_0000 281 ret i8 %r 282} 283 284define i32 @ashr_exact_add_big_negative_offset(i32 %x) { 285; CHECK-LABEL: @ashr_exact_add_big_negative_offset( 286; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], -33 287; CHECK-NEXT: [[R:%.*]] = ashr exact i32 -2, [[A]] 288; CHECK-NEXT: ret i32 [[R]] 289; 290 %a = add i32 %x, -33 291 %r = ashr exact i32 -2, %a 292 ret i32 %r 293} 294 295; exact precondition check for ashr_exact_add_negative_shift_[positive,negative] 296 297define i32 @ashr_add_negative_shift_no_exact(i32 %x) { 298; CHECK-LABEL: @ashr_add_negative_shift_no_exact( 299; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], -1 300; CHECK-NEXT: [[R:%.*]] = ashr i32 -2, [[A]] 301; CHECK-NEXT: ret i32 [[R]] 302; 303 %a = add i32 %x, -1 304 %r = ashr i32 -2, %a 305 ret i32 %r 306} 307 308define i32 @ashr_exact_add_negative_shift_negative(i32 %x) { 309; CHECK-LABEL: @ashr_exact_add_negative_shift_negative( 310; CHECK-NEXT: [[R:%.*]] = ashr exact i32 -4, [[X:%.*]] 311; CHECK-NEXT: ret i32 [[R]] 312; 313 %a = add i32 %x, -1 314 %r = ashr exact i32 -2, %a 315 ret i32 %r 316} 317 318define i8 @ashr_exact_add_negative_shift_negative_extra_use(i8 %x) { 319; CHECK-LABEL: @ashr_exact_add_negative_shift_negative_extra_use( 320; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], -2 321; CHECK-NEXT: call void @use(i8 [[A]]) 322; CHECK-NEXT: [[R:%.*]] = ashr exact i8 -128, [[X]] 323; CHECK-NEXT: ret i8 [[R]] 324; 325 %a = add i8 %x, -2 326 call void @use(i8 %a) 327 %r = ashr exact i8 -32, %a 328 ret i8 %r 329} 330 331define <2 x i7> @ashr_exact_add_negative_shift_negative_vec(<2 x i7> %x) { 332; CHECK-LABEL: @ashr_exact_add_negative_shift_negative_vec( 333; CHECK-NEXT: [[R:%.*]] = ashr exact <2 x i7> <i7 -64, i7 -64>, [[X:%.*]] 334; CHECK-NEXT: ret <2 x i7> [[R]] 335; 336 %a = add <2 x i7> %x, <i7 -5, i7 -5> 337 %r = ashr exact <2 x i7> <i7 -2, i7 -2>, %a 338 ret <2 x i7> %r 339} 340 341; not enough leading ones in shift constant 342 343define <2 x i7> @ashr_exact_add_negative_leading_ones_vec(<2 x i7> %x) { 344; CHECK-LABEL: @ashr_exact_add_negative_leading_ones_vec( 345; CHECK-NEXT: [[A:%.*]] = add <2 x i7> [[X:%.*]], <i7 -5, i7 -5> 346; CHECK-NEXT: [[R:%.*]] = ashr exact <2 x i7> <i7 -4, i7 -4>, [[A]] 347; CHECK-NEXT: ret <2 x i7> [[R]] 348; 349 %a = add <2 x i7> %x, <i7 -5, i7 -5> 350 %r = ashr exact <2 x i7> <i7 -4, i7 -4>, %a 351 ret <2 x i7> %r 352} 353 354; PR54890 355 356define i32 @shl_nsw_add_negative(i32 %x) { 357; CHECK-LABEL: @shl_nsw_add_negative( 358; CHECK-NEXT: [[R:%.*]] = shl i32 1, [[X:%.*]] 359; CHECK-NEXT: ret i32 [[R]] 360; 361 %a = add i32 %x, -1 362 %r = shl nsw i32 2, %a 363 ret i32 %r 364} 365 366; vectors and extra uses are allowed 367; nuw propagates to the new shift 368 369define <2 x i8> @shl_nuw_add_negative_splat_uses(<2 x i8> %x, <2 x i8>* %p) { 370; CHECK-LABEL: @shl_nuw_add_negative_splat_uses( 371; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -2, i8 -2> 372; CHECK-NEXT: store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2 373; CHECK-NEXT: [[R:%.*]] = shl nuw <2 x i8> <i8 3, i8 3>, [[X]] 374; CHECK-NEXT: ret <2 x i8> [[R]] 375; 376 %a = add <2 x i8> %x, <i8 -2, i8 -2> 377 store <2 x i8> %a, <2 x i8>* %p 378 %r = shl nuw <2 x i8> <i8 12, i8 12>, %a 379 ret <2 x i8> %r 380} 381 382; negative test - shift constant must have enough trailing zeros to allow the pre-shift 383 384define i32 @shl_nsw_add_negative_invalid_constant(i32 %x) { 385; CHECK-LABEL: @shl_nsw_add_negative_invalid_constant( 386; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], -2 387; CHECK-NEXT: [[R:%.*]] = shl nsw i32 2, [[A]] 388; CHECK-NEXT: ret i32 [[R]] 389; 390 %a = add i32 %x, -2 391 %r = shl nsw i32 2, %a 392 ret i32 %r 393} 394 395; negative test - the offset constant must be negative 396 397define i32 @shl_nsw_add_positive_invalid_constant(i32 %x) { 398; CHECK-LABEL: @shl_nsw_add_positive_invalid_constant( 399; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 2 400; CHECK-NEXT: [[R:%.*]] = shl nsw i32 4, [[A]] 401; CHECK-NEXT: ret i32 [[R]] 402; 403 %a = add i32 %x, 2 404 %r = shl nsw i32 4, %a 405 ret i32 %r 406} 407 408; negative test - a large shift must be detected without crashing 409 410define i32 @shl_nsw_add_negative_invalid_constant2(i32 %x) { 411; CHECK-LABEL: @shl_nsw_add_negative_invalid_constant2( 412; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], -33 413; CHECK-NEXT: [[R:%.*]] = shl nsw i32 2, [[A]] 414; CHECK-NEXT: ret i32 [[R]] 415; 416 %a = add i32 %x, -33 417 %r = shl nsw i32 2, %a 418 ret i32 %r 419} 420 421; negative test - currently transformed to 'xor' before we see it, 422; but INT_MIN should be handled too 423 424define i4 @shl_nsw_add_negative_invalid_constant3(i4 %x) { 425; CHECK-LABEL: @shl_nsw_add_negative_invalid_constant3( 426; CHECK-NEXT: [[A:%.*]] = xor i4 [[X:%.*]], -8 427; CHECK-NEXT: [[R:%.*]] = shl nsw i4 2, [[A]] 428; CHECK-NEXT: ret i4 [[R]] 429; 430 %a = add i4 %x, 8 431 %r = shl nsw i4 2, %a 432 ret i4 %r 433} 434