1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i55 @test6(i55 %A) { 5; CHECK-LABEL: @test6( 6; CHECK-NEXT: [[C:%.*]] = mul i55 [[A:%.*]], 6 7; CHECK-NEXT: ret i55 [[C]] 8; 9 %B = shl i55 %A, 1 10 %C = mul i55 %B, 3 11 ret i55 %C 12} 13 14; (X * C2) << C1 --> X * (C2 << C1) 15 16define i55 @test6a(i55 %A) { 17; CHECK-LABEL: @test6a( 18; CHECK-NEXT: [[C:%.*]] = mul i55 [[A:%.*]], 6 19; CHECK-NEXT: ret i55 [[C]] 20; 21 %B = mul i55 %A, 3 22 %C = shl i55 %B, 1 23 ret i55 %C 24} 25 26declare void @use(i55 %0) 27 28define i55 @test6a_negative_oneuse(i55 %A) { 29; CHECK-LABEL: @test6a_negative_oneuse( 30; CHECK-NEXT: [[B:%.*]] = mul i55 [[A:%.*]], 3 31; CHECK-NEXT: [[C:%.*]] = mul i55 [[A]], 6 32; CHECK-NEXT: call void @use(i55 [[B]]) 33; CHECK-NEXT: ret i55 [[C]] 34; 35 %B = mul i55 %A, 3 36 %C = shl i55 %B, 1 37 call void @use(i55 %B) 38 ret i55 %C 39} 40 41; (X * C2) << C1 --> X * (C2 << C1) 42 43define <2 x i55> @test6a_vec(<2 x i55> %A) { 44; CHECK-LABEL: @test6a_vec( 45; CHECK-NEXT: [[C:%.*]] = mul <2 x i55> [[A:%.*]], <i55 6, i55 48> 46; CHECK-NEXT: ret <2 x i55> [[C]] 47; 48 %B = mul <2 x i55> %A, <i55 3, i55 12> 49 %C = shl <2 x i55> %B, <i55 1, i55 2> 50 ret <2 x i55> %C 51} 52 53define i29 @test7(i8 %X) { 54; CHECK-LABEL: @test7( 55; CHECK-NEXT: ret i29 -1 56; 57 %A = zext i8 %X to i29 58 %B = ashr i29 -1, %A 59 ret i29 %B 60} 61 62define i7 @test8(i7 %A) { 63; CHECK-LABEL: @test8( 64; CHECK-NEXT: ret i7 0 65; 66 %B = shl i7 %A, 4 67 %C = shl i7 %B, 3 68 ret i7 %C 69} 70 71define i17 @test9(i17 %A) { 72; CHECK-LABEL: @test9( 73; CHECK-NEXT: [[B:%.*]] = and i17 [[A:%.*]], 1 74; CHECK-NEXT: ret i17 [[B]] 75; 76 %B = shl i17 %A, 16 77 %C = lshr i17 %B, 16 78 ret i17 %C 79} 80 81; shl (lshr X, C), C --> and X, C' 82 83define i19 @test10(i19 %X) { 84; CHECK-LABEL: @test10( 85; CHECK-NEXT: [[SH1:%.*]] = and i19 [[X:%.*]], -262144 86; CHECK-NEXT: ret i19 [[SH1]] 87; 88 %sh1 = lshr i19 %X, 18 89 %sh2 = shl i19 %sh1, 18 90 ret i19 %sh2 91} 92 93; Two right shifts in the same direction: 94; lshr (lshr X, C1), C2 --> lshr X, C1 + C2 95 96define <2 x i19> @lshr_lshr_splat_vec(<2 x i19> %X) { 97; CHECK-LABEL: @lshr_lshr_splat_vec( 98; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i19> [[X:%.*]], splat (i19 5) 99; CHECK-NEXT: ret <2 x i19> [[SH1]] 100; 101 %sh1 = lshr <2 x i19> %X, <i19 3, i19 3> 102 %sh2 = lshr <2 x i19> %sh1, <i19 2, i19 2> 103 ret <2 x i19> %sh2 104} 105 106define i9 @multiuse_lshr_lshr(i9 %x) { 107; CHECK-LABEL: @multiuse_lshr_lshr( 108; CHECK-NEXT: [[SH1:%.*]] = lshr i9 [[X:%.*]], 2 109; CHECK-NEXT: [[SH2:%.*]] = lshr i9 [[X]], 5 110; CHECK-NEXT: [[MUL:%.*]] = mul i9 [[SH1]], [[SH2]] 111; CHECK-NEXT: ret i9 [[MUL]] 112; 113 %sh1 = lshr i9 %x, 2 114 %sh2 = lshr i9 %sh1, 3 115 %mul = mul i9 %sh1, %sh2 116 ret i9 %mul 117} 118 119define <2 x i9> @multiuse_lshr_lshr_splat(<2 x i9> %x) { 120; CHECK-LABEL: @multiuse_lshr_lshr_splat( 121; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i9> [[X:%.*]], splat (i9 2) 122; CHECK-NEXT: [[SH2:%.*]] = lshr <2 x i9> [[X]], splat (i9 5) 123; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i9> [[SH1]], [[SH2]] 124; CHECK-NEXT: ret <2 x i9> [[MUL]] 125; 126 %sh1 = lshr <2 x i9> %x, <i9 2, i9 2> 127 %sh2 = lshr <2 x i9> %sh1, <i9 3, i9 3> 128 %mul = mul <2 x i9> %sh1, %sh2 129 ret <2 x i9> %mul 130} 131 132; Two left shifts in the same direction: 133; shl (shl X, C1), C2 --> shl X, C1 + C2 134 135define <2 x i19> @shl_shl_splat_vec(<2 x i19> %X) { 136; CHECK-LABEL: @shl_shl_splat_vec( 137; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i19> [[X:%.*]], splat (i19 5) 138; CHECK-NEXT: ret <2 x i19> [[SH1]] 139; 140 %sh1 = shl <2 x i19> %X, <i19 3, i19 3> 141 %sh2 = shl <2 x i19> %sh1, <i19 2, i19 2> 142 ret <2 x i19> %sh2 143} 144 145define i42 @multiuse_shl_shl(i42 %x) { 146; CHECK-LABEL: @multiuse_shl_shl( 147; CHECK-NEXT: [[SH1:%.*]] = shl i42 [[X:%.*]], 8 148; CHECK-NEXT: [[SH2:%.*]] = shl i42 [[X]], 17 149; CHECK-NEXT: [[MUL:%.*]] = mul i42 [[SH1]], [[SH2]] 150; CHECK-NEXT: ret i42 [[MUL]] 151; 152 %sh1 = shl i42 %x, 8 153 %sh2 = shl i42 %sh1, 9 154 %mul = mul i42 %sh1, %sh2 155 ret i42 %mul 156} 157 158define <2 x i42> @multiuse_shl_shl_splat(<2 x i42> %x) { 159; CHECK-LABEL: @multiuse_shl_shl_splat( 160; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i42> [[X:%.*]], splat (i42 8) 161; CHECK-NEXT: [[SH2:%.*]] = shl <2 x i42> [[X]], splat (i42 17) 162; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i42> [[SH1]], [[SH2]] 163; CHECK-NEXT: ret <2 x i42> [[MUL]] 164; 165 %sh1 = shl <2 x i42> %x, <i42 8, i42 8> 166 %sh2 = shl <2 x i42> %sh1, <i42 9, i42 9> 167 %mul = mul <2 x i42> %sh1, %sh2 168 ret <2 x i42> %mul 169} 170 171; Equal shift amounts in opposite directions become bitwise 'and': 172; lshr (shl X, C), C --> and X, C' 173 174define <2 x i19> @eq_shl_lshr_splat_vec(<2 x i19> %X) { 175; CHECK-LABEL: @eq_shl_lshr_splat_vec( 176; CHECK-NEXT: [[SH1:%.*]] = and <2 x i19> [[X:%.*]], splat (i19 65535) 177; CHECK-NEXT: ret <2 x i19> [[SH1]] 178; 179 %sh1 = shl <2 x i19> %X, <i19 3, i19 3> 180 %sh2 = lshr <2 x i19> %sh1, <i19 3, i19 3> 181 ret <2 x i19> %sh2 182} 183 184; Equal shift amounts in opposite directions become bitwise 'and': 185; shl (lshr X, C), C --> and X, C' 186 187define <2 x i19> @eq_lshr_shl_splat_vec(<2 x i19> %X) { 188; CHECK-LABEL: @eq_lshr_shl_splat_vec( 189; CHECK-NEXT: [[SH1:%.*]] = and <2 x i19> [[X:%.*]], splat (i19 -8) 190; CHECK-NEXT: ret <2 x i19> [[SH1]] 191; 192 %sh1 = lshr <2 x i19> %X, <i19 3, i19 3> 193 %sh2 = shl <2 x i19> %sh1, <i19 3, i19 3> 194 ret <2 x i19> %sh2 195} 196 197; In general, we would need an 'and' for this transform, but the masked-off bits are known zero. 198; shl (lshr X, C1), C2 --> lshr X, C1 - C2 199 200define <2 x i7> @lshr_shl_splat_vec(<2 x i7> %X) { 201; CHECK-LABEL: @lshr_shl_splat_vec( 202; CHECK-NEXT: [[DOTNEG:%.*]] = mul <2 x i7> [[X:%.*]], splat (i7 60) 203; CHECK-NEXT: [[SH2:%.*]] = and <2 x i7> [[DOTNEG]], splat (i7 60) 204; CHECK-NEXT: ret <2 x i7> [[SH2]] 205; 206 %mul = mul <2 x i7> %X, <i7 -8, i7 -8> 207 %sh1 = lshr exact <2 x i7> %mul, <i7 3, i7 3> 208 %sh2 = shl nuw nsw <2 x i7> %sh1, <i7 2, i7 2> 209 ret <2 x i7> %sh2 210} 211 212; In general, we would need an 'and' for this transform, but the masked-off bits are known zero. 213; lshr (shl X, C1), C2 --> shl X, C1 - C2 214 215define <2 x i7> @shl_lshr_splat_vec(<2 x i7> %X) { 216; CHECK-LABEL: @shl_lshr_splat_vec( 217; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i7> [[X:%.*]], splat (i7 9) 218; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw <2 x i7> [[DIV]], splat (i7 1) 219; CHECK-NEXT: ret <2 x i7> [[SH1]] 220; 221 %div = udiv <2 x i7> %X, <i7 9, i7 9> 222 %sh1 = shl nuw <2 x i7> %div, <i7 3, i7 3> 223 %sh2 = lshr exact <2 x i7> %sh1, <i7 2, i7 2> 224 ret <2 x i7> %sh2 225} 226 227define i23 @test11(i23 %x) { 228; CHECK-LABEL: @test11( 229; CHECK-NEXT: [[TMP1:%.*]] = mul i23 [[X:%.*]], 6 230; CHECK-NEXT: [[C:%.*]] = and i23 [[TMP1]], -4096 231; CHECK-NEXT: ret i23 [[C]] 232; 233 %a = mul i23 %x, 3 234 %b = lshr i23 %a, 11 235 %c = shl i23 %b, 12 236 ret i23 %c 237} 238 239; shl (ashr X, C), C --> and X, C' 240 241define i47 @test12(i47 %X) { 242; CHECK-LABEL: @test12( 243; CHECK-NEXT: [[SH1:%.*]] = and i47 [[X:%.*]], -256 244; CHECK-NEXT: ret i47 [[SH1]] 245; 246 %sh1 = ashr i47 %X, 8 247 %sh2 = shl i47 %sh1, 8 248 ret i47 %sh2 249} 250 251define <2 x i47> @test12_splat_vec(<2 x i47> %X) { 252; CHECK-LABEL: @test12_splat_vec( 253; CHECK-NEXT: [[SH1:%.*]] = and <2 x i47> [[X:%.*]], splat (i47 -256) 254; CHECK-NEXT: ret <2 x i47> [[SH1]] 255; 256 %sh1 = ashr <2 x i47> %X, <i47 8, i47 8> 257 %sh2 = shl <2 x i47> %sh1, <i47 8, i47 8> 258 ret <2 x i47> %sh2 259} 260 261define i18 @test13(i18 %x) { 262; CHECK-LABEL: @test13( 263; CHECK-NEXT: [[TMP1:%.*]] = mul i18 [[X:%.*]], 6 264; CHECK-NEXT: [[C:%.*]] = and i18 [[TMP1]], -512 265; CHECK-NEXT: ret i18 [[C]] 266; 267 %a = mul i18 %x, 3 268 %b = ashr i18 %a, 8 269 %c = shl i18 %b, 9 270 ret i18 %c 271} 272 273define i35 @test14(i35 %A) { 274; CHECK-LABEL: @test14( 275; CHECK-NEXT: [[B:%.*]] = and i35 [[A:%.*]], -19760 276; CHECK-NEXT: [[C:%.*]] = or disjoint i35 [[B]], 19744 277; CHECK-NEXT: ret i35 [[C]] 278; 279 %B = lshr i35 %A, 4 280 %C = or i35 %B, 1234 281 %D = shl i35 %C, 4 282 ret i35 %D 283} 284 285define i79 @test14a(i79 %A) { 286; CHECK-LABEL: @test14a( 287; CHECK-NEXT: [[C:%.*]] = and i79 [[A:%.*]], 77 288; CHECK-NEXT: ret i79 [[C]] 289; 290 %B = shl i79 %A, 4 291 %C = and i79 %B, 1234 292 %D = lshr i79 %C, 4 293 ret i79 %D 294} 295 296define i45 @test15(i1 %C) { 297; CHECK-LABEL: @test15( 298; CHECK-NEXT: [[A:%.*]] = select i1 [[C:%.*]], i45 12, i45 4 299; CHECK-NEXT: ret i45 [[A]] 300; 301 %A = select i1 %C, i45 3, i45 1 302 %V = shl i45 %A, 2 303 ret i45 %V 304} 305 306define i53 @test15a(i1 %X) { 307; CHECK-LABEL: @test15a( 308; CHECK-NEXT: [[V:%.*]] = select i1 [[X:%.*]], i53 512, i53 128 309; CHECK-NEXT: ret i53 [[V]] 310; 311 %A = select i1 %X, i8 3, i8 1 312 %B = zext i8 %A to i53 313 %V = shl i53 64, %B 314 ret i53 %V 315} 316 317define i1 @test16(i84 %X) { 318; CHECK-LABEL: @test16( 319; CHECK-NEXT: [[TMP1:%.*]] = and i84 [[X:%.*]], 16 320; CHECK-NEXT: [[CMP:%.*]] = icmp ne i84 [[TMP1]], 0 321; CHECK-NEXT: ret i1 [[CMP]] 322; 323 %shr = ashr i84 %X, 4 324 %and = and i84 %shr, 1 325 %cmp = icmp ne i84 %and, 0 326 ret i1 %cmp 327} 328 329define <2 x i1> @test16vec(<2 x i84> %X) { 330; CHECK-LABEL: @test16vec( 331; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i84> [[X:%.*]], splat (i84 16) 332; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i84> [[TMP1]], zeroinitializer 333; CHECK-NEXT: ret <2 x i1> [[CMP]] 334; 335 %shr = ashr <2 x i84> %X, <i84 4, i84 4> 336 %and = and <2 x i84> %shr, <i84 1, i84 1> 337 %cmp = icmp ne <2 x i84> %and, zeroinitializer 338 ret <2 x i1> %cmp 339} 340 341define <2 x i1> @test16vec_nonuniform(<2 x i84> %X) { 342; CHECK-LABEL: @test16vec_nonuniform( 343; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i84> [[X:%.*]], <i84 16, i84 4> 344; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i84> [[TMP1]], zeroinitializer 345; CHECK-NEXT: ret <2 x i1> [[CMP]] 346; 347 %shr = ashr <2 x i84> %X, <i84 4, i84 2> 348 %and = and <2 x i84> %shr, <i84 1, i84 1> 349 %cmp = icmp ne <2 x i84> %and, zeroinitializer 350 ret <2 x i1> %cmp 351} 352 353define <2 x i1> @test16vec_undef(<2 x i84> %X) { 354; CHECK-LABEL: @test16vec_undef( 355; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i84> [[X:%.*]], <i84 16, i84 poison> 356; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i84> [[TMP1]], zeroinitializer 357; CHECK-NEXT: ret <2 x i1> [[CMP]] 358; 359 %shr = ashr <2 x i84> %X, <i84 4, i84 undef> 360 %and = and <2 x i84> %shr, <i84 1, i84 1> 361 %cmp = icmp ne <2 x i84> %and, zeroinitializer 362 ret <2 x i1> %cmp 363} 364 365define i1 @test17(i106 %A) { 366; CHECK-LABEL: @test17( 367; CHECK-NEXT: [[B_MASK:%.*]] = and i106 [[A:%.*]], -8 368; CHECK-NEXT: [[C:%.*]] = icmp eq i106 [[B_MASK]], 9872 369; CHECK-NEXT: ret i1 [[C]] 370; 371 %B = lshr i106 %A, 3 372 %C = icmp eq i106 %B, 1234 373 ret i1 %C 374} 375 376define <2 x i1> @test17vec(<2 x i106> %A) { 377; CHECK-LABEL: @test17vec( 378; CHECK-NEXT: [[B_MASK:%.*]] = and <2 x i106> [[A:%.*]], splat (i106 -8) 379; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i106> [[B_MASK]], splat (i106 9872) 380; CHECK-NEXT: ret <2 x i1> [[C]] 381; 382 %B = lshr <2 x i106> %A, <i106 3, i106 3> 383 %C = icmp eq <2 x i106> %B, <i106 1234, i106 1234> 384 ret <2 x i1> %C 385} 386 387define i1 @test18(i11 %A) { 388; CHECK-LABEL: @test18( 389; CHECK-NEXT: ret i1 false 390; 391 %B = lshr i11 %A, 10 392 %C = icmp eq i11 %B, 123 393 ret i1 %C 394} 395 396define i1 @test19(i37 %A) { 397; CHECK-LABEL: @test19( 398; CHECK-NEXT: [[C:%.*]] = icmp ult i37 [[A:%.*]], 4 399; CHECK-NEXT: ret i1 [[C]] 400; 401 %B = ashr i37 %A, 2 402 %C = icmp eq i37 %B, 0 403 ret i1 %C 404} 405 406define <2 x i1> @test19vec(<2 x i37> %A) { 407; CHECK-LABEL: @test19vec( 408; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i37> [[A:%.*]], splat (i37 4) 409; CHECK-NEXT: ret <2 x i1> [[C]] 410; 411 %B = ashr <2 x i37> %A, <i37 2, i37 2> 412 %C = icmp eq <2 x i37> %B, zeroinitializer 413 ret <2 x i1> %C 414} 415 416define i1 @test19a(i39 %A) { 417; CHECK-LABEL: @test19a( 418; CHECK-NEXT: [[C:%.*]] = icmp ugt i39 [[A:%.*]], -5 419; CHECK-NEXT: ret i1 [[C]] 420; 421 %B = ashr i39 %A, 2 422 %C = icmp eq i39 %B, -1 423 ret i1 %C 424} 425 426define <2 x i1> @test19a_vec(<2 x i39> %A) { 427; CHECK-LABEL: @test19a_vec( 428; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i39> [[A:%.*]], splat (i39 -5) 429; CHECK-NEXT: ret <2 x i1> [[C]] 430; 431 %B = ashr <2 x i39> %A, <i39 2, i39 2> 432 %C = icmp eq <2 x i39> %B, <i39 -1, i39 -1> 433 ret <2 x i1> %C 434} 435 436define i1 @test20(i13 %A) { 437; CHECK-LABEL: @test20( 438; CHECK-NEXT: ret i1 false 439; 440 %B = ashr i13 %A, 12 441 %C = icmp eq i13 %B, 123 442 ret i1 %C 443} 444 445define i1 @test21(i12 %A) { 446; CHECK-LABEL: @test21( 447; CHECK-NEXT: [[B_MASK:%.*]] = and i12 [[A:%.*]], 63 448; CHECK-NEXT: [[C:%.*]] = icmp eq i12 [[B_MASK]], 62 449; CHECK-NEXT: ret i1 [[C]] 450; 451 %B = shl i12 %A, 6 452 %C = icmp eq i12 %B, -128 453 ret i1 %C 454} 455 456define i1 @test22(i14 %A) { 457; CHECK-LABEL: @test22( 458; CHECK-NEXT: [[B_MASK:%.*]] = and i14 [[A:%.*]], 127 459; CHECK-NEXT: [[C:%.*]] = icmp eq i14 [[B_MASK]], 0 460; CHECK-NEXT: ret i1 [[C]] 461; 462 %B = shl i14 %A, 7 463 %C = icmp eq i14 %B, 0 464 ret i1 %C 465} 466 467define i11 @test23(i44 %A) { 468; CHECK-LABEL: @test23( 469; CHECK-NEXT: [[D:%.*]] = trunc i44 [[A:%.*]] to i11 470; CHECK-NEXT: ret i11 [[D]] 471; 472 %B = shl i44 %A, 33 473 %C = ashr i44 %B, 33 474 %D = trunc i44 %C to i11 475 ret i11 %D 476} 477 478; Fold lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl. 479 480define i44 @shl_lshr_eq_amt_multi_use(i44 %A) { 481; CHECK-LABEL: @shl_lshr_eq_amt_multi_use( 482; CHECK-NEXT: [[B:%.*]] = shl i44 [[A:%.*]], 33 483; CHECK-NEXT: [[C:%.*]] = and i44 [[A]], 2047 484; CHECK-NEXT: [[D:%.*]] = or disjoint i44 [[B]], [[C]] 485; CHECK-NEXT: ret i44 [[D]] 486; 487 %B = shl i44 %A, 33 488 %C = lshr i44 %B, 33 489 %D = add i44 %B, %C 490 ret i44 %D 491} 492 493; Fold vector lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl. 494 495define <2 x i44> @shl_lshr_eq_amt_multi_use_splat_vec(<2 x i44> %A) { 496; CHECK-LABEL: @shl_lshr_eq_amt_multi_use_splat_vec( 497; CHECK-NEXT: [[B:%.*]] = shl <2 x i44> [[A:%.*]], splat (i44 33) 498; CHECK-NEXT: [[C:%.*]] = and <2 x i44> [[A]], splat (i44 2047) 499; CHECK-NEXT: [[D:%.*]] = or disjoint <2 x i44> [[B]], [[C]] 500; CHECK-NEXT: ret <2 x i44> [[D]] 501; 502 %B = shl <2 x i44> %A, <i44 33, i44 33> 503 %C = lshr <2 x i44> %B, <i44 33, i44 33> 504 %D = add <2 x i44> %B, %C 505 ret <2 x i44> %D 506} 507 508; Fold shl (lshr X, C), C -> and X, C' regardless of the number of uses of the lshr. 509 510define i43 @lshr_shl_eq_amt_multi_use(i43 %A) { 511; CHECK-LABEL: @lshr_shl_eq_amt_multi_use( 512; CHECK-NEXT: [[B:%.*]] = lshr i43 [[A:%.*]], 23 513; CHECK-NEXT: [[C:%.*]] = and i43 [[A]], -8388608 514; CHECK-NEXT: [[D:%.*]] = mul i43 [[B]], [[C]] 515; CHECK-NEXT: ret i43 [[D]] 516; 517 %B = lshr i43 %A, 23 518 %C = shl i43 %B, 23 519 %D = mul i43 %B, %C 520 ret i43 %D 521} 522 523; Fold vector shl (lshr X, C), C -> and X, C' regardless of the number of uses of the lshr. 524 525define <2 x i43> @lshr_shl_eq_amt_multi_use_splat_vec(<2 x i43> %A) { 526; CHECK-LABEL: @lshr_shl_eq_amt_multi_use_splat_vec( 527; CHECK-NEXT: [[B:%.*]] = lshr <2 x i43> [[A:%.*]], splat (i43 23) 528; CHECK-NEXT: [[C:%.*]] = and <2 x i43> [[A]], splat (i43 -8388608) 529; CHECK-NEXT: [[D:%.*]] = mul <2 x i43> [[B]], [[C]] 530; CHECK-NEXT: ret <2 x i43> [[D]] 531; 532 %B = lshr <2 x i43> %A, <i43 23, i43 23> 533 %C = shl <2 x i43> %B, <i43 23, i43 23> 534 %D = mul <2 x i43> %B, %C 535 ret <2 x i43> %D 536} 537 538define i37 @test25(i37 %AA, i37 %BB) { 539; CHECK-LABEL: @test25( 540; CHECK-NEXT: [[D:%.*]] = and i37 [[AA:%.*]], -131072 541; CHECK-NEXT: [[C2:%.*]] = add i37 [[BB:%.*]], [[D]] 542; CHECK-NEXT: [[F:%.*]] = and i37 [[C2]], -131072 543; CHECK-NEXT: ret i37 [[F]] 544; 545 %C = lshr i37 %BB, 17 546 %D = lshr i37 %AA, 17 547 %E = add i37 %D, %C 548 %F = shl i37 %E, 17 549 ret i37 %F 550} 551 552define i40 @test26(i40 %A) { 553; CHECK-LABEL: @test26( 554; CHECK-NEXT: [[B:%.*]] = and i40 [[A:%.*]], -2 555; CHECK-NEXT: ret i40 [[B]] 556; 557 %B = lshr i40 %A, 1 558 %C = bitcast i40 %B to i40 559 %D = shl i40 %C, 1 560 ret i40 %D 561} 562 563; OSS-Fuzz #9880 564; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9880 565define i177 @ossfuzz_9880(i177 %X) { 566; CHECK-LABEL: @ossfuzz_9880( 567; CHECK-NEXT: ret i177 0 568; 569 %A = alloca i177 570 %L1 = load i177, ptr %A 571 %B = or i177 0, -1 572 %B5 = udiv i177 %L1, %B 573 %B4 = add i177 %B5, %B 574 %B2 = add i177 %B, %B4 575 %B6 = mul i177 %B5, %B2 576 %B20 = shl i177 %L1, %B6 577 %B14 = sub i177 %B20, %B5 578 %B1 = udiv i177 %B14, %B6 579 ret i177 %B1 580} 581