1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use(i64) 5 6define i8 @shl_and(i8 %x, i8 %y) { 7; CHECK-LABEL: @shl_and( 8; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5 9; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[Y:%.*]], 2 10; CHECK-NEXT: [[SH1:%.*]] = and i8 [[TMP1]], [[TMP2]] 11; CHECK-NEXT: ret i8 [[SH1]] 12; 13 %sh0 = shl i8 %x, 3 14 %r = and i8 %sh0, %y 15 %sh1 = shl i8 %r, 2 16 ret i8 %sh1 17} 18 19define <2 x i8> @shl_and_nonuniform(<2 x i8> %x, <2 x i8> %y) { 20; CHECK-LABEL: @shl_and_nonuniform( 21; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 5, i8 4> 22; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[Y:%.*]], <i8 2, i8 0> 23; CHECK-NEXT: [[SH1:%.*]] = and <2 x i8> [[TMP1]], [[TMP2]] 24; CHECK-NEXT: ret <2 x i8> [[SH1]] 25; 26 %sh0 = shl <2 x i8> %x, <i8 3, i8 4> 27 %r = and <2 x i8> %sh0, %y 28 %sh1 = shl <2 x i8> %r, <i8 2, i8 0> 29 ret <2 x i8> %sh1 30} 31 32define i16 @shl_or(i16 %x, i16 %py) { 33; CHECK-LABEL: @shl_or( 34; CHECK-NEXT: [[Y:%.*]] = srem i16 [[PY:%.*]], 42 35; CHECK-NEXT: [[TMP1:%.*]] = shl i16 [[X:%.*]], 12 36; CHECK-NEXT: [[TMP2:%.*]] = shl nsw i16 [[Y]], 7 37; CHECK-NEXT: [[SH1:%.*]] = or i16 [[TMP1]], [[TMP2]] 38; CHECK-NEXT: ret i16 [[SH1]] 39; 40 %y = srem i16 %py, 42 ; thwart complexity-based canonicalization 41 %sh0 = shl i16 %x, 5 42 %r = or i16 %y, %sh0 43 %sh1 = shl i16 %r, 7 44 ret i16 %sh1 45} 46 47define <2 x i16> @shl_or_poison(<2 x i16> %x, <2 x i16> %py) { 48; CHECK-LABEL: @shl_or_poison( 49; CHECK-NEXT: [[Y:%.*]] = srem <2 x i16> [[PY:%.*]], splat (i16 42) 50; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i16> [[X:%.*]], <i16 12, i16 poison> 51; CHECK-NEXT: [[TMP2:%.*]] = shl nsw <2 x i16> [[Y]], <i16 7, i16 poison> 52; CHECK-NEXT: [[SH1:%.*]] = or <2 x i16> [[TMP1]], [[TMP2]] 53; CHECK-NEXT: ret <2 x i16> [[SH1]] 54; 55 %y = srem <2 x i16> %py, <i16 42, i16 42> ; thwart complexity-based canonicalization 56 %sh0 = shl <2 x i16> %x, <i16 5, i16 poison> 57 %r = or <2 x i16> %y, %sh0 58 %sh1 = shl <2 x i16> %r, <i16 7, i16 poison> 59 ret <2 x i16> %sh1 60} 61 62define i32 @shl_xor(i32 %x, i32 %y) { 63; CHECK-LABEL: @shl_xor( 64; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 12 65; CHECK-NEXT: [[TMP2:%.*]] = shl i32 [[Y:%.*]], 7 66; CHECK-NEXT: [[SH1:%.*]] = xor i32 [[TMP1]], [[TMP2]] 67; CHECK-NEXT: ret i32 [[SH1]] 68; 69 %sh0 = shl i32 %x, 5 70 %r = xor i32 %sh0, %y 71 %sh1 = shl i32 %r, 7 72 ret i32 %sh1 73} 74 75define <2 x i32> @shl_xor_nonuniform(<2 x i32> %x, <2 x i32> %y) { 76; CHECK-LABEL: @shl_xor_nonuniform( 77; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 12, i32 14> 78; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 7, i32 8> 79; CHECK-NEXT: [[SH1:%.*]] = xor <2 x i32> [[TMP1]], [[TMP2]] 80; CHECK-NEXT: ret <2 x i32> [[SH1]] 81; 82 %sh0 = shl <2 x i32> %x, <i32 5, i32 6> 83 %r = xor <2 x i32> %sh0, %y 84 %sh1 = shl <2 x i32> %r, <i32 7, i32 8> 85 ret <2 x i32> %sh1 86} 87 88define i64 @lshr_and(i64 %x, i64 %py) { 89; CHECK-LABEL: @lshr_and( 90; CHECK-NEXT: [[Y:%.*]] = srem i64 [[PY:%.*]], 42 91; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 12 92; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[Y]], 7 93; CHECK-NEXT: [[SH1:%.*]] = and i64 [[TMP1]], [[TMP2]] 94; CHECK-NEXT: ret i64 [[SH1]] 95; 96 %y = srem i64 %py, 42 ; thwart complexity-based canonicalization 97 %sh0 = lshr i64 %x, 5 98 %r = and i64 %y, %sh0 99 %sh1 = lshr i64 %r, 7 100 ret i64 %sh1 101} 102 103define <2 x i64> @lshr_and_poison(<2 x i64> %x, <2 x i64> %py) { 104; CHECK-LABEL: @lshr_and_poison( 105; CHECK-NEXT: [[Y:%.*]] = srem <2 x i64> [[PY:%.*]], splat (i64 42) 106; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i64> [[X:%.*]], <i64 12, i64 poison> 107; CHECK-NEXT: [[TMP2:%.*]] = lshr <2 x i64> [[Y]], <i64 7, i64 poison> 108; CHECK-NEXT: [[SH1:%.*]] = and <2 x i64> [[TMP1]], [[TMP2]] 109; CHECK-NEXT: ret <2 x i64> [[SH1]] 110; 111 %y = srem <2 x i64> %py, <i64 42, i64 42> ; thwart complexity-based canonicalization 112 %sh0 = lshr <2 x i64> %x, <i64 5, i64 poison> 113 %r = and <2 x i64> %y, %sh0 114 %sh1 = lshr <2 x i64> %r, <i64 7, i64 poison> 115 ret <2 x i64> %sh1 116} 117 118define <4 x i32> @lshr_or(<4 x i32> %x, <4 x i32> %y) { 119; CHECK-LABEL: @lshr_or( 120; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> [[X:%.*]], splat (i32 12) 121; CHECK-NEXT: [[TMP2:%.*]] = lshr <4 x i32> [[Y:%.*]], splat (i32 7) 122; CHECK-NEXT: [[SH1:%.*]] = or <4 x i32> [[TMP1]], [[TMP2]] 123; CHECK-NEXT: ret <4 x i32> [[SH1]] 124; 125 %sh0 = lshr <4 x i32> %x, <i32 5, i32 5, i32 5, i32 5> 126 %r = or <4 x i32> %sh0, %y 127 %sh1 = lshr <4 x i32> %r, <i32 7, i32 7, i32 7, i32 7> 128 ret <4 x i32> %sh1 129} 130 131define <8 x i16> @lshr_xor(<8 x i16> %x, <8 x i16> %py) { 132; CHECK-LABEL: @lshr_xor( 133; CHECK-NEXT: [[Y:%.*]] = srem <8 x i16> [[PY:%.*]], splat (i16 42) 134; CHECK-NEXT: [[TMP1:%.*]] = lshr <8 x i16> [[X:%.*]], splat (i16 12) 135; CHECK-NEXT: [[TMP2:%.*]] = lshr <8 x i16> [[Y]], splat (i16 7) 136; CHECK-NEXT: [[SH1:%.*]] = xor <8 x i16> [[TMP1]], [[TMP2]] 137; CHECK-NEXT: ret <8 x i16> [[SH1]] 138; 139 %y = srem <8 x i16> %py, <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 -42> ; thwart complexity-based canonicalization 140 %sh0 = lshr <8 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5> 141 %r = xor <8 x i16> %y, %sh0 142 %sh1 = lshr <8 x i16> %r, <i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7> 143 ret <8 x i16> %sh1 144} 145 146define <16 x i8> @ashr_and(<16 x i8> %x, <16 x i8> %py, <16 x i8> %pz) { 147; CHECK-LABEL: @ashr_and( 148; CHECK-NEXT: [[Y:%.*]] = srem <16 x i8> [[PY:%.*]], [[PZ:%.*]] 149; CHECK-NEXT: [[TMP1:%.*]] = ashr <16 x i8> [[X:%.*]], splat (i8 5) 150; CHECK-NEXT: [[TMP2:%.*]] = ashr <16 x i8> [[Y]], splat (i8 2) 151; CHECK-NEXT: [[SH1:%.*]] = and <16 x i8> [[TMP1]], [[TMP2]] 152; CHECK-NEXT: ret <16 x i8> [[SH1]] 153; 154 %y = srem <16 x i8> %py, %pz ; thwart complexity-based canonicalization 155 %sh0 = ashr <16 x i8> %x, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> 156 %r = and <16 x i8> %y, %sh0 157 %sh1 = ashr <16 x i8> %r, <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2> 158 ret <16 x i8> %sh1 159} 160 161define <2 x i64> @ashr_or(<2 x i64> %x, <2 x i64> %y) { 162; CHECK-LABEL: @ashr_or( 163; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i64> [[X:%.*]], splat (i64 12) 164; CHECK-NEXT: [[TMP2:%.*]] = ashr <2 x i64> [[Y:%.*]], splat (i64 7) 165; CHECK-NEXT: [[SH1:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]] 166; CHECK-NEXT: ret <2 x i64> [[SH1]] 167; 168 %sh0 = ashr <2 x i64> %x, <i64 5, i64 5> 169 %r = or <2 x i64> %sh0, %y 170 %sh1 = ashr <2 x i64> %r, <i64 7, i64 7> 171 ret <2 x i64> %sh1 172} 173 174define i32 @ashr_xor(i32 %x, i32 %py) { 175; CHECK-LABEL: @ashr_xor( 176; CHECK-NEXT: [[Y:%.*]] = srem i32 [[PY:%.*]], 42 177; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 12 178; CHECK-NEXT: [[TMP2:%.*]] = ashr i32 [[Y]], 7 179; CHECK-NEXT: [[SH1:%.*]] = xor i32 [[TMP1]], [[TMP2]] 180; CHECK-NEXT: ret i32 [[SH1]] 181; 182 %y = srem i32 %py, 42 ; thwart complexity-based canonicalization 183 %sh0 = ashr i32 %x, 5 184 %r = xor i32 %y, %sh0 185 %sh1 = ashr i32 %r, 7 186 ret i32 %sh1 187} 188 189define i32 @shr_mismatch_xor(i32 %x, i32 %y) { 190; CHECK-LABEL: @shr_mismatch_xor( 191; CHECK-NEXT: [[SH0:%.*]] = ashr i32 [[X:%.*]], 5 192; CHECK-NEXT: [[R:%.*]] = xor i32 [[Y:%.*]], [[SH0]] 193; CHECK-NEXT: [[SH1:%.*]] = lshr i32 [[R]], 7 194; CHECK-NEXT: ret i32 [[SH1]] 195; 196 %sh0 = ashr i32 %x, 5 197 %r = xor i32 %y, %sh0 198 %sh1 = lshr i32 %r, 7 199 ret i32 %sh1 200} 201 202define i32 @ashr_overshift_xor(i32 %x, i32 %y) { 203; CHECK-LABEL: @ashr_overshift_xor( 204; CHECK-NEXT: [[SH0:%.*]] = ashr i32 [[X:%.*]], 15 205; CHECK-NEXT: [[R:%.*]] = xor i32 [[Y:%.*]], [[SH0]] 206; CHECK-NEXT: [[SH1:%.*]] = ashr i32 [[R]], 17 207; CHECK-NEXT: ret i32 [[SH1]] 208; 209 %sh0 = ashr i32 %x, 15 210 %r = xor i32 %y, %sh0 211 %sh1 = ashr i32 %r, 17 212 ret i32 %sh1 213} 214 215define <2 x i32> @ashr_poison_poison_xor(<2 x i32> %x, <2 x i32> %y) { 216; CHECK-LABEL: @ashr_poison_poison_xor( 217; CHECK-NEXT: [[SH0:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 15, i32 poison> 218; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[Y:%.*]], [[SH0]] 219; CHECK-NEXT: [[SH1:%.*]] = ashr <2 x i32> [[R]], <i32 poison, i32 17> 220; CHECK-NEXT: ret <2 x i32> [[SH1]] 221; 222 %sh0 = ashr <2 x i32> %x, <i32 15, i32 poison> 223 %r = xor <2 x i32> %y, %sh0 224 %sh1 = ashr <2 x i32> %r, <i32 poison, i32 17> 225 ret <2 x i32> %sh1 226} 227 228define i32 @lshr_or_extra_use(i32 %x, i32 %y, ptr %p) { 229; CHECK-LABEL: @lshr_or_extra_use( 230; CHECK-NEXT: [[SH0:%.*]] = lshr i32 [[X:%.*]], 5 231; CHECK-NEXT: [[R:%.*]] = or i32 [[SH0]], [[Y:%.*]] 232; CHECK-NEXT: store i32 [[R]], ptr [[P:%.*]], align 4 233; CHECK-NEXT: [[SH1:%.*]] = lshr i32 [[R]], 7 234; CHECK-NEXT: ret i32 [[SH1]] 235; 236 %sh0 = lshr i32 %x, 5 237 %r = or i32 %sh0, %y 238 store i32 %r, ptr %p 239 %sh1 = lshr i32 %r, 7 240 ret i32 %sh1 241} 242 243; Avoid crashing on constant expressions. 244 245@g = external global i32 246 247define i32 @PR44028(i32 %x) { 248; CHECK-LABEL: @PR44028( 249; CHECK-NEXT: [[SH1:%.*]] = ashr exact i32 [[X:%.*]], 16 250; CHECK-NEXT: [[SH2:%.*]] = shl i32 ptrtoint (ptr @g to i32), 16 251; CHECK-NEXT: [[T0:%.*]] = xor i32 [[SH1]], [[SH2]] 252; CHECK-NEXT: [[T27:%.*]] = ashr exact i32 [[T0]], 16 253; CHECK-NEXT: ret i32 [[T27]] 254; 255 %sh1 = ashr exact i32 %x, 16 256 %sh2 = shl i32 ptrtoint (ptr @g to i32), 16 257 %t0 = xor i32 %sh1, %sh2 258 %t27 = ashr exact i32 %t0, 16 259 ret i32 %t27 260} 261 262define i64 @lshr_mul(i64 %0) { 263; CHECK-LABEL: @lshr_mul( 264; CHECK-NEXT: [[TMP2:%.*]] = mul nuw nsw i64 [[TMP0:%.*]], 13 265; CHECK-NEXT: ret i64 [[TMP2]] 266; 267 %2 = mul nuw i64 %0, 52 268 %3 = lshr i64 %2, 2 269 ret i64 %3 270} 271 272define i64 @lshr_mul_nuw_nsw(i64 %0) { 273; CHECK-LABEL: @lshr_mul_nuw_nsw( 274; CHECK-NEXT: [[TMP2:%.*]] = mul nuw nsw i64 [[TMP0:%.*]], 13 275; CHECK-NEXT: ret i64 [[TMP2]] 276; 277 %2 = mul nuw nsw i64 %0, 52 278 %3 = lshr i64 %2, 2 279 ret i64 %3 280} 281 282define <4 x i32> @lshr_mul_vector(<4 x i32> %0) { 283; CHECK-LABEL: @lshr_mul_vector( 284; CHECK-NEXT: [[TMP2:%.*]] = mul nuw nsw <4 x i32> [[TMP0:%.*]], splat (i32 13) 285; CHECK-NEXT: ret <4 x i32> [[TMP2]] 286; 287 %2 = mul nuw <4 x i32> %0, <i32 52, i32 52, i32 52, i32 52> 288 %3 = lshr <4 x i32> %2, <i32 2, i32 2, i32 2, i32 2> 289 ret <4 x i32> %3 290} 291 292define i64 @lshr_mul_negative_noexact(i64 %0) { 293; CHECK-LABEL: @lshr_mul_negative_noexact( 294; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0:%.*]], 53 295; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 2 296; CHECK-NEXT: ret i64 [[TMP3]] 297; 298 %2 = mul nuw i64 %0, 53 299 %3 = lshr i64 %2, 2 300 ret i64 %3 301} 302 303define i64 @lshr_mul_negative_oneuse(i64 %0) { 304; CHECK-LABEL: @lshr_mul_negative_oneuse( 305; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0:%.*]], 52 306; CHECK-NEXT: call void @use(i64 [[TMP2]]) 307; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i64 [[TMP2]], 2 308; CHECK-NEXT: ret i64 [[TMP3]] 309; 310 %2 = mul nuw i64 %0, 52 311 call void @use(i64 %2) 312 %3 = lshr i64 %2, 2 313 ret i64 %3 314} 315 316define i64 @lshr_mul_negative_nonuw(i64 %0) { 317; CHECK-LABEL: @lshr_mul_negative_nonuw( 318; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP0:%.*]], 52 319; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i64 [[TMP2]], 2 320; CHECK-NEXT: ret i64 [[TMP3]] 321; 322 %2 = mul i64 %0, 52 323 %3 = lshr i64 %2, 2 324 ret i64 %3 325} 326 327define i64 @lshr_mul_negative_nsw(i64 %0) { 328; CHECK-LABEL: @lshr_mul_negative_nsw( 329; CHECK-NEXT: [[TMP2:%.*]] = mul nsw i64 [[TMP0:%.*]], 52 330; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i64 [[TMP2]], 2 331; CHECK-NEXT: ret i64 [[TMP3]] 332; 333 %2 = mul nsw i64 %0, 52 334 %3 = lshr i64 %2, 2 335 ret i64 %3 336} 337 338define i8 @shl_add(i8 %x, i8 %y) { 339; CHECK-LABEL: @shl_add( 340; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5 341; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[Y:%.*]], 2 342; CHECK-NEXT: [[SH1:%.*]] = add i8 [[TMP1]], [[TMP2]] 343; CHECK-NEXT: ret i8 [[SH1]] 344; 345 %sh0 = shl i8 %x, 3 346 %r = add i8 %sh0, %y 347 %sh1 = shl i8 %r, 2 348 ret i8 %sh1 349} 350 351define i8 @shl_add_multiuse(i8 %x) { 352; CHECK-LABEL: @shl_add_multiuse( 353; CHECK-NEXT: [[SH0:%.*]] = shl i8 [[X:%.*]], 3 354; CHECK-NEXT: call void @use(i8 [[SH0]]) 355; CHECK-NEXT: [[R:%.*]] = shl i8 [[X]], 5 356; CHECK-NEXT: [[SH1:%.*]] = add i8 [[R]], 88 357; CHECK-NEXT: ret i8 [[SH1]] 358; 359 %sh0 = shl i8 %x, 3 360 %r = add i8 %sh0, -42 361 call void @use(i8 %sh0) 362 %sh1 = shl i8 %r, 2 363 ret i8 %sh1 364} 365 366define i8 @shl_add_multiuse_nonconstant(i8 %x, i8 %y) { 367; CHECK-LABEL: @shl_add_multiuse_nonconstant( 368; CHECK-NEXT: [[SH0:%.*]] = shl i8 [[X:%.*]], 3 369; CHECK-NEXT: [[R:%.*]] = add i8 [[SH0]], [[Y:%.*]] 370; CHECK-NEXT: call void @use(i8 [[SH0]]) 371; CHECK-NEXT: [[SH1:%.*]] = shl i8 [[R]], 2 372; CHECK-NEXT: ret i8 [[SH1]] 373; 374 %sh0 = shl i8 %x, 3 375 %r = add i8 %sh0, %y 376 call void @use(i8 %sh0) 377 %sh1 = shl i8 %r, 2 378 ret i8 %sh1 379} 380 381define <2 x i8> @shl_add_nonuniform(<2 x i8> %x, <2 x i8> %y) { 382; CHECK-LABEL: @shl_add_nonuniform( 383; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 5, i8 4> 384; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[Y:%.*]], <i8 2, i8 0> 385; CHECK-NEXT: [[SH1:%.*]] = add <2 x i8> [[TMP1]], [[TMP2]] 386; CHECK-NEXT: ret <2 x i8> [[SH1]] 387; 388 %sh0 = shl <2 x i8> %x, <i8 3, i8 4> 389 %r = add <2 x i8> %sh0, %y 390 %sh1 = shl <2 x i8> %r, <i8 2, i8 0> 391 ret <2 x i8> %sh1 392} 393 394 395define <2 x i64> @shl_add_poison(<2 x i64> %x, <2 x i64> %py) { 396; CHECK-LABEL: @shl_add_poison( 397; CHECK-NEXT: [[Y:%.*]] = srem <2 x i64> [[PY:%.*]], splat (i64 42) 398; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i64> [[X:%.*]], <i64 12, i64 poison> 399; CHECK-NEXT: [[TMP2:%.*]] = shl nsw <2 x i64> [[Y]], <i64 7, i64 poison> 400; CHECK-NEXT: [[SH1:%.*]] = add <2 x i64> [[TMP1]], [[TMP2]] 401; CHECK-NEXT: ret <2 x i64> [[SH1]] 402; 403 %y = srem <2 x i64> %py, <i64 42, i64 42> ; thwart complexity-based canonicalization 404 %sh0 = shl <2 x i64> %x, <i64 5, i64 poison> 405 %r = add <2 x i64> %y, %sh0 406 %sh1 = shl <2 x i64> %r, <i64 7, i64 poison> 407 ret <2 x i64> %sh1 408} 409 410 411define i8 @lshr_add(i8 %x, i8 %y) { 412; CHECK-LABEL: @lshr_add( 413; CHECK-NEXT: [[SH0:%.*]] = lshr i8 [[X:%.*]], 3 414; CHECK-NEXT: [[R:%.*]] = add i8 [[SH0]], [[Y:%.*]] 415; CHECK-NEXT: [[SH1:%.*]] = lshr i8 [[R]], 2 416; CHECK-NEXT: ret i8 [[SH1]] 417; 418 %sh0 = lshr i8 %x, 3 419 %r = add i8 %sh0, %y 420 %sh1 = lshr i8 %r, 2 421 ret i8 %sh1 422} 423 424define <2 x i8> @lshr_add_nonuniform(<2 x i8> %x, <2 x i8> %y) { 425; CHECK-LABEL: @lshr_add_nonuniform( 426; CHECK-NEXT: [[SH0:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 3, i8 4> 427; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[SH0]], [[Y:%.*]] 428; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i8> [[R]], <i8 2, i8 0> 429; CHECK-NEXT: ret <2 x i8> [[SH1]] 430; 431 %sh0 = lshr <2 x i8> %x, <i8 3, i8 4> 432 %r = add <2 x i8> %sh0, %y 433 %sh1 = lshr <2 x i8> %r, <i8 2, i8 0> 434 ret <2 x i8> %sh1 435} 436 437define <2 x i64> @lshr_add_poison(<2 x i64> %x, <2 x i64> %py) { 438; CHECK-LABEL: @lshr_add_poison( 439; CHECK-NEXT: [[Y:%.*]] = srem <2 x i64> [[PY:%.*]], splat (i64 42) 440; CHECK-NEXT: [[SH0:%.*]] = lshr <2 x i64> [[X:%.*]], <i64 5, i64 poison> 441; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i64> [[Y]], [[SH0]] 442; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i64> [[R]], <i64 7, i64 poison> 443; CHECK-NEXT: ret <2 x i64> [[SH1]] 444; 445 %y = srem <2 x i64> %py, <i64 42, i64 42> ; thwart complexity-based canonicalization 446 %sh0 = lshr <2 x i64> %x, <i64 5, i64 poison> 447 %r = add <2 x i64> %y, %sh0 448 %sh1 = lshr <2 x i64> %r, <i64 7, i64 poison> 449 ret <2 x i64> %sh1 450} 451 452define i8 @shl_sub(i8 %x, i8 %y) { 453; CHECK-LABEL: @shl_sub( 454; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5 455; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[Y:%.*]], 2 456; CHECK-NEXT: [[SH1:%.*]] = sub i8 [[TMP1]], [[TMP2]] 457; CHECK-NEXT: ret i8 [[SH1]] 458; 459 %sh0 = shl i8 %x, 3 460 %r = sub i8 %sh0, %y 461 %sh1 = shl i8 %r, 2 462 ret i8 %sh1 463} 464 465; Make sure we don't commute operands for sub 466define i8 @shl_sub_no_commute(i8 %x, i8 %y) { 467; CHECK-LABEL: @shl_sub_no_commute( 468; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[Y:%.*]], 5 469; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[X:%.*]], 2 470; CHECK-NEXT: [[SH1:%.*]] = sub i8 [[TMP2]], [[TMP1]] 471; CHECK-NEXT: ret i8 [[SH1]] 472; 473 %sh0 = shl i8 %y, 3 474 %r = sub i8 %x, %sh0 475 %sh1 = shl i8 %r, 2 476 ret i8 %sh1 477} 478 479define <2 x i8> @shl_sub_nonuniform(<2 x i8> %x, <2 x i8> %y) { 480; CHECK-LABEL: @shl_sub_nonuniform( 481; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 5, i8 4> 482; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[Y:%.*]], <i8 2, i8 0> 483; CHECK-NEXT: [[SH1:%.*]] = sub <2 x i8> [[TMP1]], [[TMP2]] 484; CHECK-NEXT: ret <2 x i8> [[SH1]] 485; 486 %sh0 = shl <2 x i8> %x, <i8 3, i8 4> 487 %r = sub <2 x i8> %sh0, %y 488 %sh1 = shl <2 x i8> %r, <i8 2, i8 0> 489 ret <2 x i8> %sh1 490} 491 492 493define <2 x i64> @shl_sub_poison(<2 x i64> %x, <2 x i64> %py) { 494; CHECK-LABEL: @shl_sub_poison( 495; CHECK-NEXT: [[Y:%.*]] = srem <2 x i64> [[PY:%.*]], splat (i64 42) 496; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i64> [[X:%.*]], <i64 12, i64 poison> 497; CHECK-NEXT: [[TMP2:%.*]] = shl nsw <2 x i64> [[Y]], <i64 7, i64 poison> 498; CHECK-NEXT: [[SH1:%.*]] = sub <2 x i64> [[TMP2]], [[TMP1]] 499; CHECK-NEXT: ret <2 x i64> [[SH1]] 500; 501 %y = srem <2 x i64> %py, <i64 42, i64 42> ; thwart complexity-based canonicalization 502 %sh0 = shl <2 x i64> %x, <i64 5, i64 poison> 503 %r = sub <2 x i64> %y, %sh0 504 %sh1 = shl <2 x i64> %r, <i64 7, i64 poison> 505 ret <2 x i64> %sh1 506} 507 508 509define i8 @lshr_sub(i8 %x, i8 %y) { 510; CHECK-LABEL: @lshr_sub( 511; CHECK-NEXT: [[SH0:%.*]] = lshr i8 [[X:%.*]], 3 512; CHECK-NEXT: [[R:%.*]] = sub i8 [[SH0]], [[Y:%.*]] 513; CHECK-NEXT: [[SH1:%.*]] = lshr i8 [[R]], 2 514; CHECK-NEXT: ret i8 [[SH1]] 515; 516 %sh0 = lshr i8 %x, 3 517 %r = sub i8 %sh0, %y 518 %sh1 = lshr i8 %r, 2 519 ret i8 %sh1 520} 521 522define <2 x i8> @lshr_sub_nonuniform(<2 x i8> %x, <2 x i8> %y) { 523; CHECK-LABEL: @lshr_sub_nonuniform( 524; CHECK-NEXT: [[SH0:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 3, i8 4> 525; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[SH0]], [[Y:%.*]] 526; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i8> [[R]], <i8 2, i8 0> 527; CHECK-NEXT: ret <2 x i8> [[SH1]] 528; 529 %sh0 = lshr <2 x i8> %x, <i8 3, i8 4> 530 %r = sub <2 x i8> %sh0, %y 531 %sh1 = lshr <2 x i8> %r, <i8 2, i8 0> 532 ret <2 x i8> %sh1 533} 534 535define <2 x i64> @lshr_sub_poison(<2 x i64> %x, <2 x i64> %py) { 536; CHECK-LABEL: @lshr_sub_poison( 537; CHECK-NEXT: [[Y:%.*]] = srem <2 x i64> [[PY:%.*]], splat (i64 42) 538; CHECK-NEXT: [[SH0:%.*]] = lshr <2 x i64> [[X:%.*]], <i64 5, i64 poison> 539; CHECK-NEXT: [[R:%.*]] = sub nsw <2 x i64> [[Y]], [[SH0]] 540; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i64> [[R]], <i64 7, i64 poison> 541; CHECK-NEXT: ret <2 x i64> [[SH1]] 542; 543 %y = srem <2 x i64> %py, <i64 42, i64 42> ; thwart complexity-based canonicalization 544 %sh0 = lshr <2 x i64> %x, <i64 5, i64 poison> 545 %r = sub <2 x i64> %y, %sh0 546 %sh1 = lshr <2 x i64> %r, <i64 7, i64 poison> 547 ret <2 x i64> %sh1 548} 549