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(i8) 5 6define i8 @lshr_add(i8 %a, i8 %y) { 7; CHECK-LABEL: @lshr_add( 8; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 9; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 5 10; CHECK-NEXT: [[R2:%.*]] = add i8 [[Y:%.*]], [[B1]] 11; CHECK-NEXT: [[L:%.*]] = and i8 [[R2]], -32 12; CHECK-NEXT: ret i8 [[L]] 13; 14 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 15 %r = lshr i8 %y, 5 16 %b = add i8 %r, %x 17 %l = shl i8 %b, 5 18 ret i8 %l 19} 20 21define <2 x i8> @lshr_add_commute_splat(<2 x i8> %a, <2 x i8> %y) { 22; CHECK-LABEL: @lshr_add_commute_splat( 23; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 24; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 5) 25; CHECK-NEXT: [[R2:%.*]] = add <2 x i8> [[Y:%.*]], [[B1]] 26; CHECK-NEXT: [[L:%.*]] = and <2 x i8> [[R2]], splat (i8 -32) 27; CHECK-NEXT: ret <2 x i8> [[L]] 28; 29 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 30 %r = lshr <2 x i8> %y, <i8 5, i8 5> 31 %b = add <2 x i8> %x, %r 32 %l = shl <2 x i8> %b, <i8 5, i8 5> 33 ret <2 x i8> %l 34} 35 36define i8 @lshr_sub(i8 %a, i8 %y) { 37; CHECK-LABEL: @lshr_sub( 38; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 39; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 3 40; CHECK-NEXT: [[B:%.*]] = sub nsw i8 [[X]], [[R]] 41; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 3 42; CHECK-NEXT: ret i8 [[L]] 43; 44 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 45 %r = lshr i8 %y, 3 46 %b = sub i8 %x, %r 47 %l = shl i8 %b, 3 48 ret i8 %l 49} 50 51define <2 x i8> @lshr_sub_commute_splat(<2 x i8> %a, <2 x i8> %y) { 52; CHECK-LABEL: @lshr_sub_commute_splat( 53; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 54; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 3) 55; CHECK-NEXT: [[R2:%.*]] = sub <2 x i8> [[Y:%.*]], [[B1]] 56; CHECK-NEXT: [[L:%.*]] = and <2 x i8> [[R2]], splat (i8 -8) 57; CHECK-NEXT: ret <2 x i8> [[L]] 58; 59 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 60 %r = lshr <2 x i8> %y, <i8 3, i8 3> 61 %b = sub <2 x i8> %r, %x 62 %l = shl <2 x i8> %b, <i8 3, i8 3> 63 ret <2 x i8> %l 64} 65 66define i8 @lshr_and(i8 %a, i8 %y) { 67; CHECK-LABEL: @lshr_and( 68; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 69; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 6 70; CHECK-NEXT: [[R2:%.*]] = and i8 [[Y:%.*]], [[B1]] 71; CHECK-NEXT: ret i8 [[R2]] 72; 73 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 74 %r = lshr i8 %y, 6 75 %b = and i8 %r, %x 76 %l = shl i8 %b, 6 77 ret i8 %l 78} 79 80define <2 x i8> @lshr_and_commute_splat(<2 x i8> %a, <2 x i8> %y) { 81; CHECK-LABEL: @lshr_and_commute_splat( 82; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 83; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 6) 84; CHECK-NEXT: [[R2:%.*]] = and <2 x i8> [[Y:%.*]], [[B1]] 85; CHECK-NEXT: ret <2 x i8> [[R2]] 86; 87 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 88 %r = lshr <2 x i8> %y, <i8 6, i8 6> 89 %b = and <2 x i8> %x, %r 90 %l = shl <2 x i8> %b, <i8 6, i8 6> 91 ret <2 x i8> %l 92} 93 94define i8 @lshr_or(i8 %a, i8 %y) { 95; CHECK-LABEL: @lshr_or( 96; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 97; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 4 98; CHECK-NEXT: [[Y_MASKED:%.*]] = and i8 [[Y:%.*]], -16 99; CHECK-NEXT: [[L:%.*]] = or i8 [[Y_MASKED]], [[B1]] 100; CHECK-NEXT: ret i8 [[L]] 101; 102 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 103 %r = lshr i8 %y, 4 104 %b = or i8 %x, %r 105 %l = shl i8 %b, 4 106 ret i8 %l 107} 108 109define <2 x i8> @lshr_or_commute_splat(<2 x i8> %a, <2 x i8> %y) { 110; CHECK-LABEL: @lshr_or_commute_splat( 111; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 112; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 4) 113; CHECK-NEXT: [[Y_MASKED:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 -16) 114; CHECK-NEXT: [[L:%.*]] = or <2 x i8> [[Y_MASKED]], [[B1]] 115; CHECK-NEXT: ret <2 x i8> [[L]] 116; 117 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 118 %r = lshr <2 x i8> %y, <i8 4, i8 4> 119 %b = or <2 x i8> %r, %x 120 %l = shl <2 x i8> %b, <i8 4, i8 4> 121 ret <2 x i8> %l 122} 123 124define i8 @lshr_xor(i8 %a, i8 %y) { 125; CHECK-LABEL: @lshr_xor( 126; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 127; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 3 128; CHECK-NEXT: [[Y_MASKED:%.*]] = and i8 [[Y:%.*]], -8 129; CHECK-NEXT: [[L:%.*]] = xor i8 [[Y_MASKED]], [[B1]] 130; CHECK-NEXT: ret i8 [[L]] 131; 132 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 133 %r = lshr i8 %y, 3 134 %b = xor i8 %r, %x 135 %l = shl i8 %b, 3 136 ret i8 %l 137} 138 139define <2 x i8> @lshr_xor_commute_splat(<2 x i8> %a, <2 x i8> %y) { 140; CHECK-LABEL: @lshr_xor_commute_splat( 141; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 142; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 3) 143; CHECK-NEXT: [[Y_MASKED:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 -8) 144; CHECK-NEXT: [[L:%.*]] = xor <2 x i8> [[Y_MASKED]], [[B1]] 145; CHECK-NEXT: ret <2 x i8> [[L]] 146; 147 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 148 %r = lshr <2 x i8> %y, <i8 3, i8 3> 149 %b = xor <2 x i8> %x, %r 150 %l = shl <2 x i8> %b, <i8 3, i8 3> 151 ret <2 x i8> %l 152} 153 154define i8 @lshr_add_use1(i8 %x, i8 %y) { 155; CHECK-LABEL: @lshr_add_use1( 156; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 5 157; CHECK-NEXT: call void @use(i8 [[R]]) 158; CHECK-NEXT: [[B:%.*]] = add i8 [[R]], [[X:%.*]] 159; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 5 160; CHECK-NEXT: ret i8 [[L]] 161; 162 %r = lshr i8 %y, 5 163 call void @use(i8 %r) 164 %b = add i8 %r, %x 165 %l = shl i8 %b, 5 166 ret i8 %l 167} 168 169define i8 @lshr_add_use2(i8 %x, i8 %y) { 170; CHECK-LABEL: @lshr_add_use2( 171; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 5 172; CHECK-NEXT: [[B:%.*]] = add i8 [[R]], [[X:%.*]] 173; CHECK-NEXT: call void @use(i8 [[B]]) 174; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 5 175; CHECK-NEXT: ret i8 [[L]] 176; 177 %r = lshr i8 %y, 5 178 %b = add i8 %r, %x 179 call void @use(i8 %b) 180 %l = shl i8 %b, 5 181 ret i8 %l 182} 183 184define i8 @lshr_and_add(i8 %a, i8 %y) { 185; CHECK-LABEL: @lshr_and_add( 186; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 187; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 3 188; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 96 189; CHECK-NEXT: [[L:%.*]] = add i8 [[Y_MASK]], [[B1]] 190; CHECK-NEXT: ret i8 [[L]] 191; 192 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 193 %r = lshr i8 %y, 3 194 %m = and i8 %r, 12 195 %b = add i8 %x, %m 196 %l = shl i8 %b, 3 197 ret i8 %l 198} 199 200define <2 x i8> @lshr_and_add_commute_splat(<2 x i8> %a, <2 x i8> %y) { 201; CHECK-LABEL: @lshr_and_add_commute_splat( 202; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 203; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 3) 204; CHECK-NEXT: [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 96) 205; CHECK-NEXT: [[L:%.*]] = add <2 x i8> [[Y_MASK]], [[B1]] 206; CHECK-NEXT: ret <2 x i8> [[L]] 207; 208 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 209 %r = lshr <2 x i8> %y, <i8 3, i8 3> 210 %m = and <2 x i8> %r, <i8 12, i8 12> 211 %b = add <2 x i8> %m, %x 212 %l = shl <2 x i8> %b, <i8 3, i8 3> 213 ret <2 x i8> %l 214} 215 216define i8 @lshr_and_sub(i8 %a, i8 %y) { 217; CHECK-LABEL: @lshr_and_sub( 218; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 219; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 2 220; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 13 221; CHECK-NEXT: [[B:%.*]] = sub nsw i8 [[X]], [[M]] 222; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 2 223; CHECK-NEXT: ret i8 [[L]] 224; 225 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 226 %r = lshr i8 %y, 2 227 %m = and i8 %r, 13 228 %b = sub i8 %x, %m 229 %l = shl i8 %b, 2 230 ret i8 %l 231} 232 233define <2 x i8> @lshr_and_sub_commute_splat(<2 x i8> %a, <2 x i8> %y) { 234; CHECK-LABEL: @lshr_and_sub_commute_splat( 235; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 236; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2) 237; CHECK-NEXT: [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52) 238; CHECK-NEXT: [[L:%.*]] = sub <2 x i8> [[Y_MASK]], [[B1]] 239; CHECK-NEXT: ret <2 x i8> [[L]] 240; 241 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 242 %r = lshr <2 x i8> %y, <i8 2, i8 2> 243 %m = and <2 x i8> %r, <i8 13, i8 13> 244 %b = sub <2 x i8> %m, %x 245 %l = shl <2 x i8> %b, <i8 2, i8 2> 246 ret <2 x i8> %l 247} 248 249define i8 @lshr_and_and(i8 %a, i8 %y) { 250; CHECK-LABEL: @lshr_and_and( 251; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 252; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 2 253; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52 254; CHECK-NEXT: [[L:%.*]] = and i8 [[Y_MASK]], [[B1]] 255; CHECK-NEXT: ret i8 [[L]] 256; 257 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 258 %r = lshr i8 %y, 2 259 %m = and i8 %r, 13 260 %b = and i8 %m, %x 261 %l = shl i8 %b, 2 262 ret i8 %l 263} 264 265define <2 x i8> @lshr_and_and_commute_splat(<2 x i8> %a, <2 x i8> %y) { 266; CHECK-LABEL: @lshr_and_and_commute_splat( 267; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 268; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2) 269; CHECK-NEXT: [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52) 270; CHECK-NEXT: [[L:%.*]] = and <2 x i8> [[Y_MASK]], [[B1]] 271; CHECK-NEXT: ret <2 x i8> [[L]] 272; 273 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 274 %r = lshr <2 x i8> %y, <i8 2, i8 2> 275 %m = and <2 x i8> %r, <i8 13, i8 13> 276 %b = and <2 x i8> %x, %m 277 %l = shl <2 x i8> %b, <i8 2, i8 2> 278 ret <2 x i8> %l 279} 280 281define i8 @lshr_and_or(i8 %a, i8 %y) { 282; CHECK-LABEL: @lshr_and_or( 283; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 284; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 2 285; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52 286; CHECK-NEXT: [[L:%.*]] = or i8 [[Y_MASK]], [[B1]] 287; CHECK-NEXT: ret i8 [[L]] 288; 289 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 290 %r = lshr i8 %y, 2 291 %m = and i8 %r, 13 292 %b = or i8 %x, %m 293 %l = shl i8 %b, 2 294 ret i8 %l 295} 296 297define i8 @lshr_and_or_disjoint(i8 %a, i8 %y) { 298; CHECK-LABEL: @lshr_and_or_disjoint( 299; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 300; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 2 301; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52 302; CHECK-NEXT: [[L:%.*]] = or disjoint i8 [[Y_MASK]], [[B1]] 303; CHECK-NEXT: ret i8 [[L]] 304; 305 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 306 %r = lshr i8 %y, 2 307 %m = and i8 %r, 13 308 %b = or disjoint i8 %x, %m 309 %l = shl i8 %b, 2 310 ret i8 %l 311} 312 313define i8 @ashr_and_or_disjoint(i8 %a, i8 %y) { 314; CHECK-LABEL: @ashr_and_or_disjoint( 315; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 316; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 2 317; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52 318; CHECK-NEXT: [[L:%.*]] = or disjoint i8 [[Y_MASK]], [[B1]] 319; CHECK-NEXT: ret i8 [[L]] 320; 321 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 322 %r = ashr i8 %y, 2 323 %m = and i8 %r, 13 324 %b = or disjoint i8 %x, %m 325 %l = shl i8 %b, 2 326 ret i8 %l 327} 328 329 330define <2 x i8> @lshr_and_or_commute_splat(<2 x i8> %a, <2 x i8> %y) { 331; CHECK-LABEL: @lshr_and_or_commute_splat( 332; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 333; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2) 334; CHECK-NEXT: [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52) 335; CHECK-NEXT: [[L:%.*]] = or <2 x i8> [[Y_MASK]], [[B1]] 336; CHECK-NEXT: ret <2 x i8> [[L]] 337; 338 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 339 %r = lshr <2 x i8> %y, <i8 2, i8 2> 340 %m = and <2 x i8> %r, <i8 13, i8 13> 341 %b = or <2 x i8> %m, %x 342 %l = shl <2 x i8> %b, <i8 2, i8 2> 343 ret <2 x i8> %l 344} 345 346define i8 @lshr_and_xor(i8 %a, i8 %y) { 347; CHECK-LABEL: @lshr_and_xor( 348; CHECK-NEXT: [[X:%.*]] = srem i8 [[A:%.*]], 42 349; CHECK-NEXT: [[B1:%.*]] = shl i8 [[X]], 2 350; CHECK-NEXT: [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52 351; CHECK-NEXT: [[L:%.*]] = xor i8 [[Y_MASK]], [[B1]] 352; CHECK-NEXT: ret i8 [[L]] 353; 354 %x = srem i8 %a, 42 ; thwart complexity-based canonicalization 355 %r = lshr i8 %y, 2 356 %m = and i8 %r, 13 357 %b = xor i8 %m, %x 358 %l = shl i8 %b, 2 359 ret i8 %l 360} 361 362define <2 x i8> @lshr_and_xor_commute_splat(<2 x i8> %a, <2 x i8> %y) { 363; CHECK-LABEL: @lshr_and_xor_commute_splat( 364; CHECK-NEXT: [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42) 365; CHECK-NEXT: [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2) 366; CHECK-NEXT: [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52) 367; CHECK-NEXT: [[L:%.*]] = xor <2 x i8> [[Y_MASK]], [[B1]] 368; CHECK-NEXT: ret <2 x i8> [[L]] 369; 370 %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization 371 %r = lshr <2 x i8> %y, <i8 2, i8 2> 372 %m = and <2 x i8> %r, <i8 13, i8 13> 373 %b = xor <2 x i8> %x, %m 374 %l = shl <2 x i8> %b, <i8 2, i8 2> 375 ret <2 x i8> %l 376} 377 378define i8 @lshr_and_add_use1(i8 %x, i8 %y) { 379; CHECK-LABEL: @lshr_and_add_use1( 380; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 3 381; CHECK-NEXT: call void @use(i8 [[R]]) 382; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 12 383; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[M]] 384; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 3 385; CHECK-NEXT: ret i8 [[L]] 386; 387 %r = lshr i8 %y, 3 388 call void @use(i8 %r) 389 %m = and i8 %r, 12 390 %b = add i8 %x, %m 391 %l = shl i8 %b, 3 392 ret i8 %l 393} 394 395define i8 @lshr_and_add_use2(i8 %x, i8 %y) { 396; CHECK-LABEL: @lshr_and_add_use2( 397; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 3 398; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 12 399; CHECK-NEXT: call void @use(i8 [[M]]) 400; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[M]] 401; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 3 402; CHECK-NEXT: ret i8 [[L]] 403; 404 %r = lshr i8 %y, 3 405 %m = and i8 %r, 12 406 call void @use(i8 %m) 407 %b = add i8 %x, %m 408 %l = shl i8 %b, 3 409 ret i8 %l 410} 411 412define i8 @lshr_and_add_use3(i8 %x, i8 %y) { 413; CHECK-LABEL: @lshr_and_add_use3( 414; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 3 415; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 12 416; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[M]] 417; CHECK-NEXT: call void @use(i8 [[B]]) 418; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 3 419; CHECK-NEXT: ret i8 [[L]] 420; 421 %r = lshr i8 %y, 3 422 %m = and i8 %r, 12 423 %b = add i8 %x, %m 424 call void @use(i8 %b) 425 %l = shl i8 %b, 3 426 ret i8 %l 427} 428 429define i8 @lshr_and_add_use4(i8 %x, i8 %y) { 430; CHECK-LABEL: @lshr_and_add_use4( 431; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 3 432; CHECK-NEXT: call void @use(i8 [[R]]) 433; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 12 434; CHECK-NEXT: call void @use(i8 [[M]]) 435; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[M]] 436; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 3 437; CHECK-NEXT: ret i8 [[L]] 438; 439 %r = lshr i8 %y, 3 440 call void @use(i8 %r) 441 %m = and i8 %r, 12 442 call void @use(i8 %m) 443 %b = add i8 %x, %m 444 %l = shl i8 %b, 3 445 ret i8 %l 446} 447 448define i8 @lshr_and_add_use5(i8 %x, i8 %y) { 449; CHECK-LABEL: @lshr_and_add_use5( 450; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 3 451; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 12 452; CHECK-NEXT: call void @use(i8 [[M]]) 453; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[M]] 454; CHECK-NEXT: call void @use(i8 [[B]]) 455; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 3 456; CHECK-NEXT: ret i8 [[L]] 457; 458 %r = lshr i8 %y, 3 459 %m = and i8 %r, 12 460 call void @use(i8 %m) 461 %b = add i8 %x, %m 462 call void @use(i8 %b) 463 %l = shl i8 %b, 3 464 ret i8 %l 465} 466 467define i8 @lshr_and_add_use6(i8 %x, i8 %y) { 468; CHECK-LABEL: @lshr_and_add_use6( 469; CHECK-NEXT: [[R:%.*]] = lshr i8 [[Y:%.*]], 3 470; CHECK-NEXT: call void @use(i8 [[R]]) 471; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 12 472; CHECK-NEXT: call void @use(i8 [[M]]) 473; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[M]] 474; CHECK-NEXT: [[L:%.*]] = shl i8 [[B]], 3 475; CHECK-NEXT: ret i8 [[L]] 476; 477 %r = lshr i8 %y, 3 478 call void @use(i8 %r) 479 %m = and i8 %r, 12 480 call void @use(i8 %m) 481 %b = add i8 %x, %m 482 %l = shl i8 %b, 3 483 ret i8 %l 484} 485 486define <2 x i8> @lshr_add_shl_v2i8_undef(<2 x i8> %x, <2 x i8> %y) { 487; CHECK-LABEL: @lshr_add_shl_v2i8_undef( 488; CHECK-NEXT: [[A:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 5, i8 undef> 489; CHECK-NEXT: [[B:%.*]] = add <2 x i8> [[A]], [[X:%.*]] 490; CHECK-NEXT: [[C:%.*]] = shl <2 x i8> [[B]], <i8 undef, i8 5> 491; CHECK-NEXT: ret <2 x i8> [[C]] 492; 493 %a = lshr <2 x i8> %y, <i8 5, i8 undef> 494 %b = add <2 x i8> %a, %x 495 %c = shl <2 x i8> %b, <i8 undef, i8 5> 496 ret <2 x i8> %c 497} 498 499define <2 x i8> @lshr_add_shl_v2i8_nonuniform(<2 x i8> %x, <2 x i8> %y) { 500; CHECK-LABEL: @lshr_add_shl_v2i8_nonuniform( 501; CHECK-NEXT: [[A:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 5, i8 6> 502; CHECK-NEXT: [[B:%.*]] = add <2 x i8> [[A]], [[X:%.*]] 503; CHECK-NEXT: [[C:%.*]] = shl <2 x i8> [[B]], <i8 5, i8 6> 504; CHECK-NEXT: ret <2 x i8> [[C]] 505; 506 %a = lshr <2 x i8> %y, <i8 5, i8 6> 507 %b = add <2 x i8> %a, %x 508 %c = shl <2 x i8> %b, <i8 5, i8 6> 509 ret <2 x i8> %c 510} 511 512define i32 @lshr_add_and_shl(i32 %x, i32 %y) { 513; CHECK-LABEL: @lshr_add_and_shl( 514; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[Y:%.*]], 5 515; CHECK-NEXT: [[X_MASK:%.*]] = and i32 [[X:%.*]], 4064 516; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[X_MASK]], [[TMP1]] 517; CHECK-NEXT: ret i32 [[TMP2]] 518; 519 %1 = lshr i32 %x, 5 520 %2 = and i32 %1, 127 521 %3 = add i32 %y, %2 522 %4 = shl i32 %3, 5 523 ret i32 %4 524} 525 526define <2 x i32> @lshr_add_and_shl_v2i32(<2 x i32> %x, <2 x i32> %y) { 527; CHECK-LABEL: @lshr_add_and_shl_v2i32( 528; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[Y:%.*]], splat (i32 5) 529; CHECK-NEXT: [[X_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 4064) 530; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> [[X_MASK]], [[TMP1]] 531; CHECK-NEXT: ret <2 x i32> [[TMP2]] 532; 533 %1 = lshr <2 x i32> %x, <i32 5, i32 5> 534 %2 = and <2 x i32> %1, <i32 127, i32 127> 535 %3 = add <2 x i32> %y, %2 536 %4 = shl <2 x i32> %3, <i32 5, i32 5> 537 ret <2 x i32> %4 538} 539 540define <2 x i32> @lshr_add_and_shl_v2i32_undef(<2 x i32> %x, <2 x i32> %y) { 541; CHECK-LABEL: @lshr_add_and_shl_v2i32_undef( 542; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 undef, i32 5> 543; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], splat (i32 127) 544; CHECK-NEXT: [[TMP3:%.*]] = add <2 x i32> [[Y:%.*]], [[TMP2]] 545; CHECK-NEXT: [[TMP4:%.*]] = shl <2 x i32> [[TMP3]], <i32 5, i32 undef> 546; CHECK-NEXT: ret <2 x i32> [[TMP4]] 547; 548 %1 = lshr <2 x i32> %x, <i32 undef, i32 5> 549 %2 = and <2 x i32> %1, <i32 127, i32 127> 550 %3 = add <2 x i32> %y, %2 551 %4 = shl <2 x i32> %3, <i32 5, i32 undef> 552 ret <2 x i32> %4 553} 554 555define <2 x i32> @lshr_add_and_shl_v2i32_nonuniform(<2 x i32> %x, <2 x i32> %y) { 556; CHECK-LABEL: @lshr_add_and_shl_v2i32_nonuniform( 557; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 6> 558; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 127, i32 255> 559; CHECK-NEXT: [[TMP3:%.*]] = add <2 x i32> [[Y:%.*]], [[TMP2]] 560; CHECK-NEXT: [[TMP4:%.*]] = shl <2 x i32> [[TMP3]], <i32 5, i32 6> 561; CHECK-NEXT: ret <2 x i32> [[TMP4]] 562; 563 %1 = lshr <2 x i32> %x, <i32 5, i32 6> 564 %2 = and <2 x i32> %1, <i32 127, i32 255> 565 %3 = add <2 x i32> %y, %2 566 %4 = shl <2 x i32> %3, <i32 5, i32 6> 567 ret <2 x i32> %4 568} 569 570define i32 @shl_add_and_lshr(i32 %x, i32 %y) { 571; CHECK-LABEL: @shl_add_and_lshr( 572; CHECK-NEXT: [[C1:%.*]] = shl i32 [[Y:%.*]], 4 573; CHECK-NEXT: [[X_MASK:%.*]] = and i32 [[X:%.*]], 128 574; CHECK-NEXT: [[D:%.*]] = add i32 [[X_MASK]], [[C1]] 575; CHECK-NEXT: ret i32 [[D]] 576; 577 %a = lshr i32 %x, 4 578 %b = and i32 %a, 8 579 %c = add i32 %b, %y 580 %d = shl i32 %c, 4 581 ret i32 %d 582} 583 584define <2 x i32> @shl_add_and_lshr_v2i32(<2 x i32> %x, <2 x i32> %y) { 585; CHECK-LABEL: @shl_add_and_lshr_v2i32( 586; CHECK-NEXT: [[C1:%.*]] = shl <2 x i32> [[Y:%.*]], splat (i32 4) 587; CHECK-NEXT: [[X_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128) 588; CHECK-NEXT: [[D:%.*]] = add <2 x i32> [[X_MASK]], [[C1]] 589; CHECK-NEXT: ret <2 x i32> [[D]] 590; 591 %a = lshr <2 x i32> %x, <i32 4, i32 4> 592 %b = and <2 x i32> %a, <i32 8, i32 8> 593 %c = add <2 x i32> %b, %y 594 %d = shl <2 x i32> %c, <i32 4, i32 4> 595 ret <2 x i32> %d 596} 597 598define <2 x i32> @shl_add_and_lshr_v2i32_undef(<2 x i32> %x, <2 x i32> %y) { 599; CHECK-LABEL: @shl_add_and_lshr_v2i32_undef( 600; CHECK-NEXT: [[A:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 undef> 601; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A]], <i32 8, i32 undef> 602; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]] 603; CHECK-NEXT: [[D:%.*]] = shl <2 x i32> [[C]], <i32 4, i32 undef> 604; CHECK-NEXT: ret <2 x i32> [[D]] 605; 606 %a = lshr <2 x i32> %x, <i32 4, i32 undef> 607 %b = and <2 x i32> %a, <i32 8, i32 undef> 608 %c = add <2 x i32> %b, %y 609 %d = shl <2 x i32> %c, <i32 4, i32 undef> 610 ret <2 x i32> %d 611} 612 613define <2 x i32> @shl_add_and_lshr_v2i32_nonuniform(<2 x i32> %x, <2 x i32> %y) { 614; CHECK-LABEL: @shl_add_and_lshr_v2i32_nonuniform( 615; CHECK-NEXT: [[A:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 5> 616; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A]], <i32 8, i32 9> 617; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]] 618; CHECK-NEXT: [[D:%.*]] = shl <2 x i32> [[C]], <i32 4, i32 5> 619; CHECK-NEXT: ret <2 x i32> [[D]] 620; 621 %a = lshr <2 x i32> %x, <i32 4, i32 5> 622 %b = and <2 x i32> %a, <i32 8, i32 9> 623 %c = add <2 x i32> %b, %y 624 %d = shl <2 x i32> %c, <i32 4, i32 5> 625 ret <2 x i32> %d 626} 627 628define <4 x i32> @test_FoldShiftByConstant_CreateSHL(<4 x i32> %in) { 629; CHECK-LABEL: @test_FoldShiftByConstant_CreateSHL( 630; CHECK-NEXT: [[VSHL_N:%.*]] = mul <4 x i32> [[IN:%.*]], <i32 0, i32 -32, i32 0, i32 -32> 631; CHECK-NEXT: ret <4 x i32> [[VSHL_N]] 632; 633 %mul.i = mul <4 x i32> %in, <i32 0, i32 -1, i32 0, i32 -1> 634 %vshl_n = shl <4 x i32> %mul.i, <i32 5, i32 5, i32 5, i32 5> 635 ret <4 x i32> %vshl_n 636} 637 638define <8 x i16> @test_FoldShiftByConstant_CreateSHL2(<8 x i16> %in) { 639; CHECK-LABEL: @test_FoldShiftByConstant_CreateSHL2( 640; CHECK-NEXT: [[VSHL_N:%.*]] = mul <8 x i16> [[IN:%.*]], <i16 0, i16 -32, i16 0, i16 -32, i16 0, i16 -32, i16 0, i16 -32> 641; CHECK-NEXT: ret <8 x i16> [[VSHL_N]] 642; 643 %mul.i = mul <8 x i16> %in, <i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1> 644 %vshl_n = shl <8 x i16> %mul.i, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5> 645 ret <8 x i16> %vshl_n 646} 647 648define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) { 649; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd( 650; CHECK-NEXT: [[VSRA_N2:%.*]] = mul <16 x i8> [[IN0:%.*]], splat (i8 33) 651; CHECK-NEXT: [[VSHL_N:%.*]] = and <16 x i8> [[VSRA_N2]], splat (i8 -32) 652; CHECK-NEXT: ret <16 x i8> [[VSHL_N]] 653; 654 %vsra_n = ashr <16 x i8> %in0, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5> 655 %tmp = add <16 x i8> %in0, %vsra_n 656 %vshl_n = shl <16 x i8> %tmp, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5> 657 ret <16 x i8> %vshl_n 658} 659