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) 5declare void @use32(i32) 6 7declare i8 @llvm.umin.i8(i8, i8) 8declare i8 @llvm.umax.i8(i8, i8) 9declare i8 @llvm.smin.i8(i8, i8) 10declare i8 @llvm.smax.i8(i8, i8) 11 12define i32 @t1(i16 zeroext %x, i32 %y) { 13; CHECK-LABEL: @t1( 14; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32 15; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 1 16; CHECK-NEXT: [[D1:%.*]] = lshr i32 [[CONV]], [[TMP1]] 17; CHECK-NEXT: ret i32 [[D1]] 18; 19 %conv = zext i16 %x to i32 20 %s = shl i32 2, %y 21 %d = sdiv i32 %conv, %s 22 ret i32 %d 23} 24 25define <2 x i32> @t1vec(<2 x i16> %x, <2 x i32> %y) { 26; CHECK-LABEL: @t1vec( 27; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32> 28; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 1) 29; CHECK-NEXT: [[D1:%.*]] = lshr <2 x i32> [[CONV]], [[TMP1]] 30; CHECK-NEXT: ret <2 x i32> [[D1]] 31; 32 %conv = zext <2 x i16> %x to <2 x i32> 33 %s = shl <2 x i32> <i32 2, i32 2>, %y 34 %d = sdiv <2 x i32> %conv, %s 35 ret <2 x i32> %d 36} 37 38; rdar://11721329 39define i64 @t2(i64 %x, i32 %y) { 40; CHECK-LABEL: @t2( 41; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[Y:%.*]] to i64 42; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[X:%.*]], [[TMP1]] 43; CHECK-NEXT: ret i64 [[TMP2]] 44; 45 %1 = shl i32 1, %y 46 %2 = zext i32 %1 to i64 47 %3 = udiv i64 %x, %2 48 ret i64 %3 49} 50 51; PR13250 52define i64 @t3(i64 %x, i32 %y) { 53; CHECK-LABEL: @t3( 54; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 2 55; CHECK-NEXT: [[TMP2:%.*]] = zext nneg i32 [[TMP1]] to i64 56; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[X:%.*]], [[TMP2]] 57; CHECK-NEXT: ret i64 [[TMP3]] 58; 59 %1 = shl i32 4, %y 60 %2 = zext i32 %1 to i64 61 %3 = udiv i64 %x, %2 62 ret i64 %3 63} 64 65define i32 @t4(i32 %x, i32 %y) { 66; CHECK-LABEL: @t4( 67; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 5) 68; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[X:%.*]], [[TMP1]] 69; CHECK-NEXT: ret i32 [[TMP2]] 70; 71 %1 = shl i32 1, %y 72 %2 = icmp ult i32 %1, 32 73 %3 = select i1 %2, i32 32, i32 %1 74 %4 = udiv i32 %x, %3 75 ret i32 %4 76} 77 78define i32 @t5(i1 %x, i1 %y, i32 %V) { 79; CHECK-LABEL: @t5( 80; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i32 5, i32 6 81; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[Y:%.*]], i32 [[TMP1]], i32 [[V:%.*]] 82; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[V]], [[TMP2]] 83; CHECK-NEXT: ret i32 [[TMP3]] 84; 85 %1 = shl i32 1, %V 86 %2 = select i1 %x, i32 32, i32 64 87 %3 = select i1 %y, i32 %2, i32 %1 88 %4 = udiv i32 %V, %3 89 ret i32 %4 90} 91 92define i32 @t6(i32 %x, i32 %z) { 93; CHECK-LABEL: @t6( 94; CHECK-NEXT: [[DIVISOR:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 1) 95; CHECK-NEXT: [[Y:%.*]] = udiv i32 [[Z:%.*]], [[DIVISOR]] 96; CHECK-NEXT: ret i32 [[Y]] 97; 98 %x_is_zero = icmp eq i32 %x, 0 99 %divisor = select i1 %x_is_zero, i32 1, i32 %x 100 %y = udiv i32 %z, %divisor 101 ret i32 %y 102} 103 104define i8 @udiv_umin(i8 %x, i8 %y, i8 %z) { 105; CHECK-LABEL: @udiv_umin( 106; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[Z:%.*]]) 107; CHECK-NEXT: [[D1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 108; CHECK-NEXT: ret i8 [[D1]] 109; 110 %y2 = shl i8 1, %y 111 %z2 = shl i8 1, %z 112 %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2) 113 %d = udiv i8 %x, %m 114 ret i8 %d 115} 116 117define i8 @udiv_umax(i8 %x, i8 %y, i8 %z) { 118; CHECK-LABEL: @udiv_umax( 119; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[Z:%.*]]) 120; CHECK-NEXT: [[D1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 121; CHECK-NEXT: ret i8 [[D1]] 122; 123 %y2 = shl i8 1, %y 124 %z2 = shl i8 1, %z 125 %m = call i8 @llvm.umax.i8(i8 %y2, i8 %z2) 126 %d = udiv i8 %x, %m 127 ret i8 %d 128} 129 130; Negative test, cannot take exact log2 131define i8 @udiv_umin_(i8 %x, i8 %y, i8 %z) { 132; CHECK-LABEL: @udiv_umin_( 133; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]] 134; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z:%.*]]) 135; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[M]] 136; CHECK-NEXT: ret i8 [[D]] 137; 138 %y2 = shl i8 1, %y 139 %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z) 140 %d = udiv i8 %x, %m 141 ret i8 %d 142} 143 144; Negative test, extra use 145define i8 @udiv_umin_extra_use(i8 %x, i8 %y, i8 %z) { 146; CHECK-LABEL: @udiv_umin_extra_use( 147; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]] 148; CHECK-NEXT: [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]] 149; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z2]]) 150; CHECK-NEXT: call void @use(i8 [[M]]) 151; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[M]], i1 true) 152; CHECK-NEXT: [[D:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 153; CHECK-NEXT: ret i8 [[D]] 154; 155 %y2 = shl i8 1, %y 156 %z2 = shl i8 1, %z 157 %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2) 158 call void @use(i8 %m) 159 %d = udiv i8 %x, %m 160 ret i8 %d 161} 162 163; Negative test, signed min/max 164define i8 @udiv_smin(i8 %x, i8 %y, i8 %z) { 165; CHECK-LABEL: @udiv_smin( 166; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]] 167; CHECK-NEXT: [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]] 168; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[Y2]], i8 [[Z2]]) 169; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[M]], i1 true) 170; CHECK-NEXT: [[D:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 171; CHECK-NEXT: ret i8 [[D]] 172; 173 %y2 = shl i8 1, %y 174 %z2 = shl i8 1, %z 175 %m = call i8 @llvm.smin.i8(i8 %y2, i8 %z2) 176 %d = udiv i8 %x, %m 177 ret i8 %d 178} 179 180; Negative test, signed min/max 181define i8 @udiv_smax(i8 %x, i8 %y, i8 %z) { 182; CHECK-LABEL: @udiv_smax( 183; CHECK-NEXT: [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]] 184; CHECK-NEXT: [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]] 185; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y2]], i8 [[Z2]]) 186; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[M]], i1 true) 187; CHECK-NEXT: [[D:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 188; CHECK-NEXT: ret i8 [[D]] 189; 190 %y2 = shl i8 1, %y 191 %z2 = shl i8 1, %z 192 %m = call i8 @llvm.smax.i8(i8 %y2, i8 %z2) 193 %d = udiv i8 %x, %m 194 ret i8 %d 195} 196 197; (X << C1) / X -> 1 << C1 optimizations 198 199define i32 @t7(i32 %x) { 200; CHECK-LABEL: @t7( 201; CHECK-NEXT: ret i32 4 202; 203 %shl = shl nsw i32 %x, 2 204 %r = sdiv i32 %shl, %x 205 ret i32 %r 206} 207 208; make sure the previous opt doesn't take place for wrapped shifts 209 210define i32 @t8(i32 %x) { 211; CHECK-LABEL: @t8( 212; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 2 213; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[SHL]], [[X]] 214; CHECK-NEXT: ret i32 [[R]] 215; 216 %shl = shl i32 %x, 2 217 %r = sdiv i32 %shl, %x 218 ret i32 %r 219} 220 221define <2 x i32> @t9(<2 x i32> %x) { 222; CHECK-LABEL: @t9( 223; CHECK-NEXT: ret <2 x i32> <i32 4, i32 8> 224; 225 %shl = shl nsw <2 x i32> %x, <i32 2, i32 3> 226 %r = sdiv <2 x i32> %shl, %x 227 ret <2 x i32> %r 228} 229 230define i32 @t10(i32 %x, i32 %y) { 231; CHECK-LABEL: @t10( 232; CHECK-NEXT: [[R:%.*]] = shl nuw nsw i32 1, [[Y:%.*]] 233; CHECK-NEXT: ret i32 [[R]] 234; 235 %shl = shl nsw i32 %x, %y 236 %r = sdiv i32 %shl, %x 237 ret i32 %r 238} 239 240define <2 x i32> @t11(<2 x i32> %x, <2 x i32> %y) { 241; CHECK-LABEL: @t11( 242; CHECK-NEXT: [[R:%.*]] = shl nuw nsw <2 x i32> splat (i32 1), [[Y:%.*]] 243; CHECK-NEXT: ret <2 x i32> [[R]] 244; 245 %shl = shl nsw <2 x i32> %x, %y 246 %r = sdiv <2 x i32> %shl, %x 247 ret <2 x i32> %r 248} 249 250define i32 @t12(i32 %x) { 251; CHECK-LABEL: @t12( 252; CHECK-NEXT: ret i32 4 253; 254 %shl = shl nuw i32 %x, 2 255 %r = udiv i32 %shl, %x 256 ret i32 %r 257} 258 259; make sure the previous opt doesn't take place for wrapped shifts 260 261define i32 @t13(i32 %x) { 262; CHECK-LABEL: @t13( 263; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 2 264; CHECK-NEXT: [[R:%.*]] = udiv i32 [[SHL]], [[X]] 265; CHECK-NEXT: ret i32 [[R]] 266; 267 %shl = shl i32 %x, 2 268 %r = udiv i32 %shl, %x 269 ret i32 %r 270} 271 272define <2 x i32> @t14(<2 x i32> %x) { 273; CHECK-LABEL: @t14( 274; CHECK-NEXT: ret <2 x i32> <i32 4, i32 8> 275; 276 %shl = shl nuw <2 x i32> %x, <i32 2, i32 3> 277 %r = udiv <2 x i32> %shl, %x 278 ret <2 x i32> %r 279} 280 281define i32 @t15(i32 %x, i32 %y) { 282; CHECK-LABEL: @t15( 283; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[Y:%.*]] 284; CHECK-NEXT: ret i32 [[R]] 285; 286 %shl = shl nuw i32 %x, %y 287 %r = udiv i32 %shl, %x 288 ret i32 %r 289} 290 291define <2 x i32> @t16(<2 x i32> %x, <2 x i32> %y) { 292; CHECK-LABEL: @t16( 293; CHECK-NEXT: [[R:%.*]] = shl nuw <2 x i32> splat (i32 1), [[Y:%.*]] 294; CHECK-NEXT: ret <2 x i32> [[R]] 295; 296 %shl = shl nuw <2 x i32> %x, %y 297 %r = udiv <2 x i32> %shl, %x 298 ret <2 x i32> %r 299} 300 301; (X * Y) s/ (X << Z) --> Y s/ (1 << Z) 302 303define i5 @sdiv_mul_shl_nsw(i5 %x, i5 %y, i5 %z) { 304; CHECK-LABEL: @sdiv_mul_shl_nsw( 305; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]] 306; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[Y:%.*]], [[TMP1]] 307; CHECK-NEXT: ret i5 [[D]] 308; 309 %m1 = mul nsw i5 %x, %y 310 %m2 = shl nsw i5 %x, %z 311 %d = sdiv i5 %m1, %m2 312 ret i5 %d 313} 314 315; (Y * Z) s/ (X << Z) --> Y s/ (1 << Z) 316 317define i5 @sdiv_mul_shl_nsw_exact_commute1(i5 %x, i5 %y, i5 %z) { 318; CHECK-LABEL: @sdiv_mul_shl_nsw_exact_commute1( 319; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]] 320; CHECK-NEXT: [[D:%.*]] = sdiv exact i5 [[Y:%.*]], [[TMP1]] 321; CHECK-NEXT: ret i5 [[D]] 322; 323 %m1 = mul nsw i5 %y, %x 324 %m2 = shl nsw i5 %x, %z 325 %d = sdiv exact i5 %m1, %m2 326 ret i5 %d 327} 328 329; negative test - shl is not commutative 330 331define i5 @sdiv_mul_shl_nsw_commute2(i5 %x, i5 %y, i5 %z) { 332; CHECK-LABEL: @sdiv_mul_shl_nsw_commute2( 333; CHECK-NEXT: [[M1:%.*]] = mul nsw i5 [[Y:%.*]], [[X:%.*]] 334; CHECK-NEXT: [[M2:%.*]] = shl nsw i5 [[Z:%.*]], [[X]] 335; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[M1]], [[M2]] 336; CHECK-NEXT: ret i5 [[D]] 337; 338 %m1 = mul nsw i5 %y, %x 339 %m2 = shl nsw i5 %z, %x 340 %d = sdiv i5 %m1, %m2 341 ret i5 %d 342} 343 344; extra use is ok 345 346define i8 @sdiv_mul_shl_nsw_use1(i8 %x, i8 %y, i8 %z) { 347; CHECK-LABEL: @sdiv_mul_shl_nsw_use1( 348; CHECK-NEXT: [[M1:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]] 349; CHECK-NEXT: call void @use(i8 [[M1]]) 350; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i8 1, [[Z:%.*]] 351; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[Y]], [[TMP1]] 352; CHECK-NEXT: ret i8 [[D]] 353; 354 %m1 = mul nsw i8 %x, %y 355 call void @use(i8 %m1) 356 %m2 = shl nsw i8 %x, %z 357 %d = sdiv i8 %m1, %m2 358 ret i8 %d 359} 360 361; extra use is ok 362 363define i8 @sdiv_mul_shl_nsw_use2(i8 %x, i8 %y, i8 %z) { 364; CHECK-LABEL: @sdiv_mul_shl_nsw_use2( 365; CHECK-NEXT: [[M2:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]] 366; CHECK-NEXT: call void @use(i8 [[M2]]) 367; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i8 1, [[Z]] 368; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[Y:%.*]], [[TMP1]] 369; CHECK-NEXT: ret i8 [[D]] 370; 371 %m1 = mul nsw i8 %x, %y 372 %m2 = shl nsw i8 %x, %z 373 call void @use(i8 %m2) 374 %d = sdiv i8 %m1, %m2 375 ret i8 %d 376} 377 378; negative test - both operands can't have extra uses 379 380define i8 @sdiv_mul_shl_nsw_use3(i8 %x, i8 %y, i8 %z) { 381; CHECK-LABEL: @sdiv_mul_shl_nsw_use3( 382; CHECK-NEXT: [[M1:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]] 383; CHECK-NEXT: call void @use(i8 [[M1]]) 384; CHECK-NEXT: [[M2:%.*]] = shl nsw i8 [[X]], [[Z:%.*]] 385; CHECK-NEXT: call void @use(i8 [[M2]]) 386; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[M1]], [[M2]] 387; CHECK-NEXT: ret i8 [[D]] 388; 389 %m1 = mul nsw i8 %x, %y 390 call void @use(i8 %m1) 391 %m2 = shl nsw i8 %x, %z 392 call void @use(i8 %m2) 393 %d = sdiv i8 %m1, %m2 394 ret i8 %d 395} 396 397; negative test - shl must be divisor 398 399define i5 @sdiv_shl_mul_nsw(i5 %x, i5 %y, i5 %z) { 400; CHECK-LABEL: @sdiv_shl_mul_nsw( 401; CHECK-NEXT: [[M1:%.*]] = shl nsw i5 [[Z:%.*]], [[X:%.*]] 402; CHECK-NEXT: [[M2:%.*]] = mul nsw i5 [[X]], [[Y:%.*]] 403; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[M1]], [[M2]] 404; CHECK-NEXT: ret i5 [[D]] 405; 406 %m1 = shl nsw i5 %z, %x 407 %m2 = mul nsw i5 %x, %y 408 %d = sdiv i5 %m1, %m2 409 ret i5 %d 410} 411 412; negative test - wrong no-wrap 413 414define i5 @sdiv_mul_shl_missing_nsw1(i5 %x, i5 %y, i5 %z) { 415; CHECK-LABEL: @sdiv_mul_shl_missing_nsw1( 416; CHECK-NEXT: [[M1:%.*]] = mul nsw i5 [[X:%.*]], [[Y:%.*]] 417; CHECK-NEXT: [[M2:%.*]] = shl nuw i5 [[Y]], [[Z:%.*]] 418; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[M1]], [[M2]] 419; CHECK-NEXT: ret i5 [[D]] 420; 421 %m1 = mul nsw i5 %x, %y 422 %m2 = shl nuw i5 %y, %z 423 %d = sdiv i5 %m1, %m2 424 ret i5 %d 425} 426 427; negative test - wrong no-wrap 428 429define i5 @sdiv_mul_shl_missing_nsw2(i5 %x, i5 %y, i5 %z) { 430; CHECK-LABEL: @sdiv_mul_shl_missing_nsw2( 431; CHECK-NEXT: [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]] 432; CHECK-NEXT: [[M2:%.*]] = shl nsw i5 [[Y]], [[Z:%.*]] 433; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[M1]], [[M2]] 434; CHECK-NEXT: ret i5 [[D]] 435; 436 %m1 = mul nuw i5 %x, %y 437 %m2 = shl nsw i5 %y, %z 438 %d = sdiv i5 %m1, %m2 439 ret i5 %d 440} 441 442; (X * Y) u/ (X << Z) --> Y u>> Z 443 444define i5 @udiv_mul_shl_nuw(i5 %x, i5 %y, i5 %z) { 445; CHECK-LABEL: @udiv_mul_shl_nuw( 446; CHECK-NEXT: [[D:%.*]] = lshr i5 [[Y:%.*]], [[Z:%.*]] 447; CHECK-NEXT: ret i5 [[D]] 448; 449 %m1 = mul nuw i5 %x, %y 450 %m2 = shl nuw i5 %x, %z 451 %d = udiv i5 %m1, %m2 452 ret i5 %d 453} 454 455; (Y * X) u/ (X << Z) --> Y u>> Z 456 457define i5 @udiv_mul_shl_nuw_exact_commute1(i5 %x, i5 %y, i5 %z) { 458; CHECK-LABEL: @udiv_mul_shl_nuw_exact_commute1( 459; CHECK-NEXT: [[D:%.*]] = lshr exact i5 [[Y:%.*]], [[Z:%.*]] 460; CHECK-NEXT: ret i5 [[D]] 461; 462 %m1 = mul nuw i5 %y, %x 463 %m2 = shl nuw i5 %x, %z 464 %d = udiv exact i5 %m1, %m2 465 ret i5 %d 466} 467 468; negative test - shl is not commutative 469 470define i5 @udiv_mul_shl_nuw_commute2(i5 %x, i5 %y, i5 %z) { 471; CHECK-LABEL: @udiv_mul_shl_nuw_commute2( 472; CHECK-NEXT: [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]] 473; CHECK-NEXT: [[M2:%.*]] = shl nuw i5 [[Z:%.*]], [[X]] 474; CHECK-NEXT: [[D:%.*]] = udiv i5 [[M1]], [[M2]] 475; CHECK-NEXT: ret i5 [[D]] 476; 477 %m1 = mul nuw i5 %x, %y 478 %m2 = shl nuw i5 %z, %x 479 %d = udiv i5 %m1, %m2 480 ret i5 %d 481} 482 483; extra uses are ok 484 485define i8 @udiv_mul_shl_nsw_use1(i8 %x, i8 %y, i8 %z) { 486; CHECK-LABEL: @udiv_mul_shl_nsw_use1( 487; CHECK-NEXT: [[M1:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 488; CHECK-NEXT: call void @use(i8 [[M1]]) 489; CHECK-NEXT: [[D:%.*]] = lshr i8 [[Y]], [[Z:%.*]] 490; CHECK-NEXT: ret i8 [[D]] 491; 492 %m1 = mul nuw i8 %x, %y 493 call void @use(i8 %m1) 494 %m2 = shl nuw i8 %x, %z 495 %d = udiv i8 %m1, %m2 496 ret i8 %d 497} 498 499; extra uses are ok 500 501define i8 @udiv_mul_shl_nsw_use2(i8 %x, i8 %y, i8 %z) { 502; CHECK-LABEL: @udiv_mul_shl_nsw_use2( 503; CHECK-NEXT: [[M2:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]] 504; CHECK-NEXT: call void @use(i8 [[M2]]) 505; CHECK-NEXT: [[D:%.*]] = lshr i8 [[Y:%.*]], [[Z]] 506; CHECK-NEXT: ret i8 [[D]] 507; 508 %m1 = mul nuw i8 %x, %y 509 %m2 = shl nuw i8 %x, %z 510 call void @use(i8 %m2) 511 %d = udiv i8 %m1, %m2 512 ret i8 %d 513} 514 515; extra uses are ok 516 517define i8 @udiv_mul_shl_nsw_use3(i8 %x, i8 %y, i8 %z) { 518; CHECK-LABEL: @udiv_mul_shl_nsw_use3( 519; CHECK-NEXT: [[M1:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 520; CHECK-NEXT: call void @use(i8 [[M1]]) 521; CHECK-NEXT: [[M2:%.*]] = shl nuw i8 [[X]], [[Z:%.*]] 522; CHECK-NEXT: call void @use(i8 [[M2]]) 523; CHECK-NEXT: [[D:%.*]] = lshr i8 [[Y]], [[Z]] 524; CHECK-NEXT: ret i8 [[D]] 525; 526 %m1 = mul nuw i8 %x, %y 527 call void @use(i8 %m1) 528 %m2 = shl nuw i8 %x, %z 529 call void @use(i8 %m2) 530 %d = udiv i8 %m1, %m2 531 ret i8 %d 532} 533 534; (X << Z) / (X * Y) -> (1 << Z) / Y 535 536define i5 @udiv_shl_mul_nuw(i5 %x, i5 %y, i5 %z) { 537; CHECK-LABEL: @udiv_shl_mul_nuw( 538; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]] 539; CHECK-NEXT: [[D:%.*]] = udiv i5 [[TMP1]], [[Y:%.*]] 540; CHECK-NEXT: ret i5 [[D]] 541; 542 %m1 = shl nuw i5 %x, %z 543 %m2 = mul nuw i5 %x, %y 544 %d = udiv i5 %m1, %m2 545 ret i5 %d 546} 547 548define i5 @udiv_shl_mul_nuw_swap(i5 %x, i5 %y, i5 %z) { 549; CHECK-LABEL: @udiv_shl_mul_nuw_swap( 550; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]] 551; CHECK-NEXT: [[D:%.*]] = udiv i5 [[TMP1]], [[Y:%.*]] 552; CHECK-NEXT: ret i5 [[D]] 553; 554 %m1 = shl nuw i5 %x, %z 555 %m2 = mul nuw i5 %y, %x 556 %d = udiv i5 %m1, %m2 557 ret i5 %d 558} 559 560define i5 @udiv_shl_mul_nuw_exact(i5 %x, i5 %y, i5 %z) { 561; CHECK-LABEL: @udiv_shl_mul_nuw_exact( 562; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]] 563; CHECK-NEXT: [[D:%.*]] = udiv exact i5 [[TMP1]], [[Y:%.*]] 564; CHECK-NEXT: ret i5 [[D]] 565; 566 %m1 = shl nuw i5 %x, %z 567 %m2 = mul nuw i5 %x, %y 568 %d = udiv exact i5 %m1, %m2 569 ret i5 %d 570} 571 572define <2 x i4> @udiv_shl_mul_nuw_vec(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 573; CHECK-LABEL: @udiv_shl_mul_nuw_vec( 574; CHECK-NEXT: [[TMP1:%.*]] = shl nuw <2 x i4> splat (i4 1), [[Z:%.*]] 575; CHECK-NEXT: [[D:%.*]] = udiv <2 x i4> [[TMP1]], [[Y:%.*]] 576; CHECK-NEXT: ret <2 x i4> [[D]] 577; 578 %m1 = shl nuw <2 x i4> %x, %z 579 %m2 = mul nuw <2 x i4> %y, %x 580 %d = udiv <2 x i4> %m1, %m2 581 ret <2 x i4> %d 582} 583 584define i8 @udiv_shl_mul_nuw_extra_use_of_shl(i8 %x, i8 %y, i8 %z) { 585; CHECK-LABEL: @udiv_shl_mul_nuw_extra_use_of_shl( 586; CHECK-NEXT: [[M1:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]] 587; CHECK-NEXT: call void @use(i8 [[M1]]) 588; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i8 1, [[Z]] 589; CHECK-NEXT: [[D:%.*]] = udiv i8 [[TMP1]], [[Y:%.*]] 590; CHECK-NEXT: ret i8 [[D]] 591; 592 %m1 = shl nuw i8 %x, %z 593 call void @use(i8 %m1) 594 %m2 = mul nuw i8 %y, %x 595 %d = udiv i8 %m1, %m2 596 ret i8 %d 597} 598 599; negative test - extra use 600 601define i8 @udiv_shl_mul_nuw_extra_use_of_mul(i8 %x, i8 %y, i8 %z) { 602; CHECK-LABEL: @udiv_shl_mul_nuw_extra_use_of_mul( 603; CHECK-NEXT: [[M1:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]] 604; CHECK-NEXT: [[M2:%.*]] = mul nuw i8 [[Y:%.*]], [[X]] 605; CHECK-NEXT: call void @use(i8 [[M2]]) 606; CHECK-NEXT: [[D:%.*]] = udiv i8 [[M1]], [[M2]] 607; CHECK-NEXT: ret i8 [[D]] 608; 609 %m1 = shl nuw i8 %x, %z 610 %m2 = mul nuw i8 %y, %x 611 call void @use(i8 %m2) 612 %d = udiv i8 %m1, %m2 613 ret i8 %d 614} 615 616define i8 @udiv_shl_mul_nuw_extra_use(i8 %x, i8 %y, i8 %z) { 617; CHECK-LABEL: @udiv_shl_mul_nuw_extra_use( 618; CHECK-NEXT: [[M1:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]] 619; CHECK-NEXT: call void @use(i8 [[M1]]) 620; CHECK-NEXT: [[M2:%.*]] = mul nuw i8 [[Y:%.*]], [[X]] 621; CHECK-NEXT: call void @use(i8 [[M2]]) 622; CHECK-NEXT: [[D:%.*]] = udiv i8 [[M1]], [[M2]] 623; CHECK-NEXT: ret i8 [[D]] 624; 625 %m1 = shl nuw i8 %x, %z 626 call void @use(i8 %m1) 627 %m2 = mul nuw i8 %y, %x 628 call void @use(i8 %m2) 629 %d = udiv i8 %m1, %m2 630 ret i8 %d 631} 632 633; negative test - sdiv 634 635define i5 @sdiv_shl_mul_nuw(i5 %x, i5 %y, i5 %z) { 636; CHECK-LABEL: @sdiv_shl_mul_nuw( 637; CHECK-NEXT: [[M1:%.*]] = shl nuw i5 [[X:%.*]], [[Z:%.*]] 638; CHECK-NEXT: [[M2:%.*]] = mul nuw i5 [[X]], [[Y:%.*]] 639; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[M1]], [[M2]] 640; CHECK-NEXT: ret i5 [[D]] 641; 642 %m1 = shl nuw i5 %x, %z 643 %m2 = mul nuw i5 %x, %y 644 %d = sdiv i5 %m1, %m2 645 ret i5 %d 646} 647 648; negative test - wrong no-wrap 649 650define i5 @udiv_mul_shl_missing_nsw1(i5 %x, i5 %y, i5 %z) { 651; CHECK-LABEL: @udiv_mul_shl_missing_nsw1( 652; CHECK-NEXT: [[M1:%.*]] = mul nsw i5 [[X:%.*]], [[Y:%.*]] 653; CHECK-NEXT: [[M2:%.*]] = shl nuw i5 [[Y]], [[Z:%.*]] 654; CHECK-NEXT: [[D:%.*]] = udiv i5 [[M1]], [[M2]] 655; CHECK-NEXT: ret i5 [[D]] 656; 657 %m1 = mul nsw i5 %x, %y 658 %m2 = shl nuw i5 %y, %z 659 %d = udiv i5 %m1, %m2 660 ret i5 %d 661} 662 663; negative test - wrong no-wrap 664 665define i5 @udiv_mul_shl_missing_nsw2(i5 %x, i5 %y, i5 %z) { 666; CHECK-LABEL: @udiv_mul_shl_missing_nsw2( 667; CHECK-NEXT: [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]] 668; CHECK-NEXT: [[M2:%.*]] = shl nsw i5 [[Y]], [[Z:%.*]] 669; CHECK-NEXT: [[D:%.*]] = udiv i5 [[M1]], [[M2]] 670; CHECK-NEXT: ret i5 [[D]] 671; 672 %m1 = mul nuw i5 %x, %y 673 %m2 = shl nsw i5 %y, %z 674 %d = udiv i5 %m1, %m2 675 ret i5 %d 676} 677 678define i8 @udiv_shl_nuw(i8 %x, i8 %y, i8 %z) { 679; CHECK-LABEL: @udiv_shl_nuw( 680; CHECK-NEXT: [[S:%.*]] = shl nuw i8 [[Y:%.*]], [[Z:%.*]] 681; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[S]] 682; CHECK-NEXT: ret i8 [[D]] 683; 684 %s = shl nuw i8 %y, %z 685 %d = udiv i8 %x, %s 686 ret i8 %d 687} 688 689define <2 x i4> @udiv_shl_nuw_exact(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 690; CHECK-LABEL: @udiv_shl_nuw_exact( 691; CHECK-NEXT: [[S:%.*]] = shl nuw <2 x i4> [[Y:%.*]], [[Z:%.*]] 692; CHECK-NEXT: [[D:%.*]] = udiv exact <2 x i4> [[X:%.*]], [[S]] 693; CHECK-NEXT: ret <2 x i4> [[D]] 694; 695 %s = shl nuw <2 x i4> %y, %z 696 %d = udiv exact <2 x i4> %x, %s 697 ret <2 x i4> %d 698} 699 700define i8 @udiv_shl(i8 %x, i8 %y, i8 %z) { 701; CHECK-LABEL: @udiv_shl( 702; CHECK-NEXT: [[S:%.*]] = shl i8 [[Y:%.*]], [[Z:%.*]] 703; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[S]] 704; CHECK-NEXT: ret i8 [[D]] 705; 706 %s = shl i8 %y, %z 707 %d = udiv i8 %x, %s 708 ret i8 %d 709} 710 711define i8 @udiv_shl_nuw_use(i8 %x, i8 %y, i8 %z) { 712; CHECK-LABEL: @udiv_shl_nuw_use( 713; CHECK-NEXT: [[S:%.*]] = shl nuw i8 [[Y:%.*]], [[Z:%.*]] 714; CHECK-NEXT: call void @use(i8 [[S]]) 715; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[S]] 716; CHECK-NEXT: ret i8 [[D]] 717; 718 %s = shl nuw i8 %y, %z 719 call void @use(i8 %s) 720 %d = udiv i8 %x, %s 721 ret i8 %d 722} 723 724; ((X * Y) >> Z) / X --> Y >> Z 725 726define i8 @udiv_lshr_mul_nuw(i8 %x, i8 %y, i8 %z) { 727; CHECK-LABEL: @udiv_lshr_mul_nuw( 728; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[Y:%.*]], [[Z:%.*]] 729; CHECK-NEXT: ret i8 [[DIV]] 730; 731 %m = mul nuw i8 %x, %y 732 %s = lshr i8 %m, %z 733 %div = udiv i8 %s, %x 734 ret i8 %div 735} 736 737; ((Y * X) >> Z) / X --> Y >> Z 738 739define <2 x i4> @udiv_lshr_mul_nuw_exact_commute1(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 740; CHECK-LABEL: @udiv_lshr_mul_nuw_exact_commute1( 741; CHECK-NEXT: [[DIV:%.*]] = lshr exact <2 x i4> [[Y:%.*]], [[Z:%.*]] 742; CHECK-NEXT: ret <2 x i4> [[DIV]] 743; 744 %m = mul nuw <2 x i4> %y, %x 745 %s = lshr exact <2 x i4> %m, %z 746 %div = udiv exact <2 x i4> %s, %x 747 ret <2 x i4> %div 748} 749 750; negative test - mul is shifted amount, not shifted value 751 752define i8 @udiv_lshr_mul_nuw_commute2(i8 %x, i8 %y, i8 %z) { 753; CHECK-LABEL: @udiv_lshr_mul_nuw_commute2( 754; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[Y:%.*]], [[X:%.*]] 755; CHECK-NEXT: [[S:%.*]] = lshr i8 [[Z:%.*]], [[M]] 756; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[S]], [[X]] 757; CHECK-NEXT: ret i8 [[DIV]] 758; 759 %m = mul nuw i8 %y, %x 760 %s = lshr i8 %z, %m 761 %div = udiv i8 %s, %x 762 ret i8 %div 763} 764 765; extra uses are ok 766 767define i8 @udiv_lshr_mul_nuw_use1(i8 %x, i8 %y, i8 %z) { 768; CHECK-LABEL: @udiv_lshr_mul_nuw_use1( 769; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 770; CHECK-NEXT: call void @use(i8 [[M]]) 771; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[Y]], [[Z:%.*]] 772; CHECK-NEXT: ret i8 [[DIV]] 773; 774 %m = mul nuw i8 %x, %y 775 call void @use(i8 %m) 776 %s = lshr i8 %m, %z 777 %div = udiv i8 %s, %x 778 ret i8 %div 779} 780 781; extra uses are ok 782 783define i8 @udiv_lshr_mul_nuw_use2(i8 %x, i8 %y, i8 %z) { 784; CHECK-LABEL: @udiv_lshr_mul_nuw_use2( 785; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 786; CHECK-NEXT: [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]] 787; CHECK-NEXT: call void @use(i8 [[S]]) 788; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[Y]], [[Z]] 789; CHECK-NEXT: ret i8 [[DIV]] 790; 791 %m = mul nuw i8 %x, %y 792 %s = lshr i8 %m, %z 793 call void @use(i8 %s) 794 %div = udiv i8 %s, %x 795 ret i8 %div 796} 797 798; extra uses are ok 799 800define i8 @udiv_lshr_mul_nuw_use3(i8 %x, i8 %y, i8 %z) { 801; CHECK-LABEL: @udiv_lshr_mul_nuw_use3( 802; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 803; CHECK-NEXT: call void @use(i8 [[M]]) 804; CHECK-NEXT: [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]] 805; CHECK-NEXT: call void @use(i8 [[S]]) 806; CHECK-NEXT: [[DIV:%.*]] = lshr i8 [[Y]], [[Z]] 807; CHECK-NEXT: ret i8 [[DIV]] 808; 809 %m = mul nuw i8 %x, %y 810 call void @use(i8 %m) 811 %s = lshr i8 %m, %z 812 call void @use(i8 %s) 813 %div = udiv i8 %s, %x 814 ret i8 %div 815} 816 817; negative test - must have nuw 818 819define i8 @udiv_lshr_mul_nsw(i8 %x, i8 %y, i8 %z) { 820; CHECK-LABEL: @udiv_lshr_mul_nsw( 821; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]] 822; CHECK-NEXT: [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]] 823; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[S]], [[X]] 824; CHECK-NEXT: ret i8 [[DIV]] 825; 826 %m = mul nsw i8 %x, %y 827 %s = lshr i8 %m, %z 828 %div = udiv i8 %s, %x 829 ret i8 %div 830} 831 832; negative test - doesn't fold with signed div 833 834define i8 @sdiv_lshr_mul_nsw(i8 %x, i8 %y, i8 %z) { 835; CHECK-LABEL: @sdiv_lshr_mul_nsw( 836; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]] 837; CHECK-NEXT: [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]] 838; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[S]], [[X]] 839; CHECK-NEXT: ret i8 [[DIV]] 840; 841 %m = mul nsw i8 %x, %y 842 %s = lshr i8 %m, %z 843 %div = sdiv i8 %s, %x 844 ret i8 %div 845} 846 847; (X << Z) / (Y << Z) --> X / Y 848 849define i8 @sdiv_shl_shl_nsw2_nuw(i8 %x, i8 %y, i8 %z) { 850; CHECK-LABEL: @sdiv_shl_shl_nsw2_nuw( 851; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]] 852; CHECK-NEXT: ret i8 [[D]] 853; 854 %xz = shl nsw i8 %x, %z 855 %yz = shl nsw nuw i8 %y, %z 856 %d = sdiv i8 %xz, %yz 857 ret i8 %d 858} 859 860; extra uses are ok and 'exact' propagates 861 862define i8 @sdiv_shl_shl_nsw2_nuw_exact_use(i8 %x, i8 %y, i8 %z) { 863; CHECK-LABEL: @sdiv_shl_shl_nsw2_nuw_exact_use( 864; CHECK-NEXT: [[XZ:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]] 865; CHECK-NEXT: call void @use(i8 [[XZ]]) 866; CHECK-NEXT: [[D:%.*]] = sdiv exact i8 [[X]], [[Y:%.*]] 867; CHECK-NEXT: ret i8 [[D]] 868; 869 %xz = shl nsw i8 %x, %z 870 call void @use(i8 %xz) 871 %yz = shl nsw nuw i8 %y, %z 872 %d = sdiv exact i8 %xz, %yz 873 ret i8 %d 874} 875 876; negative test - wrong wrap 877 878define i8 @sdiv_shl_shl_nsw_nuw2(i8 %x, i8 %y, i8 %z) { 879; CHECK-LABEL: @sdiv_shl_shl_nsw_nuw2( 880; CHECK-NEXT: [[XZ:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]] 881; CHECK-NEXT: [[YZ:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z]] 882; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[XZ]], [[YZ]] 883; CHECK-NEXT: ret i8 [[D]] 884; 885 %xz = shl nuw i8 %x, %z 886 %yz = shl nsw nuw i8 %y, %z 887 %d = sdiv i8 %xz, %yz 888 ret i8 %d 889} 890 891; negative test - wrong wrap 892 893define i8 @sdiv_shl_shl_nsw_nuw(i8 %x, i8 %y, i8 %z) { 894; CHECK-LABEL: @sdiv_shl_shl_nsw_nuw( 895; CHECK-NEXT: [[XZ:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]] 896; CHECK-NEXT: [[YZ:%.*]] = shl nuw i8 [[Y:%.*]], [[Z]] 897; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[XZ]], [[YZ]] 898; CHECK-NEXT: ret i8 [[D]] 899; 900 %xz = shl nsw i8 %x, %z 901 %yz = shl nuw i8 %y, %z 902 %d = sdiv i8 %xz, %yz 903 ret i8 %d 904} 905 906; negative test - wrong wrap 907 908define i8 @sdiv_shl_shl_nuw_nsw2(i8 %x, i8 %y, i8 %z) { 909; CHECK-LABEL: @sdiv_shl_shl_nuw_nsw2( 910; CHECK-NEXT: [[XZ:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]] 911; CHECK-NEXT: [[YZ:%.*]] = shl nsw i8 [[Y:%.*]], [[Z]] 912; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[XZ]], [[YZ]] 913; CHECK-NEXT: ret i8 [[D]] 914; 915 %xz = shl nuw nsw i8 %x, %z 916 %yz = shl nsw i8 %y, %z 917 %d = sdiv i8 %xz, %yz 918 ret i8 %d 919} 920 921; (X << Z) / (Y << Z) --> X / Y 922 923define <2 x i8> @udiv_shl_shl_nuw2(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 924; CHECK-LABEL: @udiv_shl_shl_nuw2( 925; CHECK-NEXT: [[D:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]] 926; CHECK-NEXT: ret <2 x i8> [[D]] 927; 928 %xz = shl nuw <2 x i8> %x, %z 929 %yz = shl nuw <2 x i8> %y, %z 930 %d = udiv <2 x i8> %xz, %yz 931 ret <2 x i8> %d 932} 933 934; extra uses are ok and 'exact' propagates 935 936define i8 @udiv_shl_shl_nuw2_exact_use2(i8 %x, i8 %y, i8 %z) { 937; CHECK-LABEL: @udiv_shl_shl_nuw2_exact_use2( 938; CHECK-NEXT: [[XZ:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]] 939; CHECK-NEXT: call void @use(i8 [[XZ]]) 940; CHECK-NEXT: [[YZ:%.*]] = shl nuw i8 [[Y:%.*]], [[Z]] 941; CHECK-NEXT: call void @use(i8 [[YZ]]) 942; CHECK-NEXT: [[D:%.*]] = udiv exact i8 [[X]], [[Y]] 943; CHECK-NEXT: ret i8 [[D]] 944; 945 %xz = shl nuw i8 %x, %z 946 call void @use(i8 %xz) 947 %yz = shl nuw i8 %y, %z 948 call void @use(i8 %yz) 949 %d = udiv exact i8 %xz, %yz 950 ret i8 %d 951} 952 953; negative test - wrong wrap 954 955define i8 @udiv_shl_shl_nuw_nsw(i8 %x, i8 %y, i8 %z) { 956; CHECK-LABEL: @udiv_shl_shl_nuw_nsw( 957; CHECK-NEXT: [[XZ:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]] 958; CHECK-NEXT: [[YZ:%.*]] = shl nsw i8 [[Y:%.*]], [[Z]] 959; CHECK-NEXT: [[D:%.*]] = udiv i8 [[XZ]], [[YZ]] 960; CHECK-NEXT: ret i8 [[D]] 961; 962 %xz = shl nuw i8 %x, %z 963 %yz = shl nsw i8 %y, %z 964 %d = udiv i8 %xz, %yz 965 ret i8 %d 966} 967 968; negative test - wrong wrap 969 970define i8 @udiv_shl_shl_nsw_nuw(i8 %x, i8 %y, i8 %z) { 971; CHECK-LABEL: @udiv_shl_shl_nsw_nuw( 972; CHECK-NEXT: [[XZ:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]] 973; CHECK-NEXT: [[YZ:%.*]] = shl nuw i8 [[Y:%.*]], [[Z]] 974; CHECK-NEXT: [[D:%.*]] = udiv i8 [[XZ]], [[YZ]] 975; CHECK-NEXT: ret i8 [[D]] 976; 977 %xz = shl nsw i8 %x, %z 978 %yz = shl nuw i8 %y, %z 979 %d = udiv i8 %xz, %yz 980 ret i8 %d 981} 982 983define i8 @udiv_shl_shl_nuw_nsw2(i8 %x, i8 %y, i8 %z) { 984; CHECK-LABEL: @udiv_shl_shl_nuw_nsw2( 985; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 986; CHECK-NEXT: ret i8 [[D]] 987; 988 %xz = shl nuw nsw i8 %x, %z 989 %yz = shl nsw i8 %y, %z 990 %d = udiv i8 %xz, %yz 991 ret i8 %d 992} 993 994; TODO: X / (Y << Z) --> (X >> Z) / Y 995; https://alive2.llvm.org/ce/z/FjoN_A 996 997define i8 @udiv_shl_nuw_divisor(i8 %x, i8 %y, i8 %z) { 998; CHECK-LABEL: @udiv_shl_nuw_divisor( 999; CHECK-NEXT: [[S:%.*]] = shl nuw i8 [[Y:%.*]], [[Z:%.*]] 1000; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X:%.*]], [[S]] 1001; CHECK-NEXT: ret i8 [[D]] 1002; 1003 %s = shl nuw i8 %y, %z 1004 %d = udiv i8 %x, %s 1005 ret i8 %d 1006} 1007 1008define i8 @udiv_fail_shl_overflow(i8 %x, i8 %y) { 1009; CHECK-LABEL: @udiv_fail_shl_overflow( 1010; CHECK-NEXT: [[SHL:%.*]] = shl i8 2, [[Y:%.*]] 1011; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umax.i8(i8 [[SHL]], i8 1) 1012; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[MIN]], i1 true) 1013; CHECK-NEXT: [[MUL:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 1014; CHECK-NEXT: ret i8 [[MUL]] 1015; 1016 %shl = shl i8 2, %y 1017 %min = call i8 @llvm.umax.i8(i8 %shl, i8 1) 1018 %mul = udiv i8 %x, %min 1019 ret i8 %mul 1020} 1021 1022define i8 @udiv_shl_no_overflow(i8 %x, i8 %y) { 1023; CHECK-LABEL: @udiv_shl_no_overflow( 1024; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 1 1025; CHECK-NEXT: [[MUL1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 1026; CHECK-NEXT: ret i8 [[MUL1]] 1027; 1028 %shl = shl nuw i8 2, %y 1029 %min = call i8 @llvm.umax.i8(i8 %shl, i8 1) 1030 %mul = udiv i8 %x, %min 1031 ret i8 %mul 1032} 1033 1034; (X<<Y) / (X<<Z) -> 1 << Y >> Z 1035 1036define i32 @sdiv_shl_pair_const(i32 %a) { 1037; CHECK-LABEL: @sdiv_shl_pair_const( 1038; CHECK-NEXT: entry: 1039; CHECK-NEXT: ret i32 2 1040; 1041entry: 1042 %lhs = shl nsw i32 %a, 2 1043 %rhs = shl nsw i32 %a, 1 1044 %div = sdiv i32 %lhs, %rhs 1045 ret i32 %div 1046} 1047 1048define i32 @udiv_shl_pair_const(i32 %a) { 1049; CHECK-LABEL: @udiv_shl_pair_const( 1050; CHECK-NEXT: entry: 1051; CHECK-NEXT: ret i32 2 1052; 1053entry: 1054 %lhs = shl nuw i32 %a, 2 1055 %rhs = shl nuw i32 %a, 1 1056 %div = udiv i32 %lhs, %rhs 1057 ret i32 %div 1058} 1059 1060define i32 @sdiv_shl_pair1(i32 %a, i32 %x, i32 %y) { 1061; CHECK-LABEL: @sdiv_shl_pair1( 1062; CHECK-NEXT: entry: 1063; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] 1064; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] 1065; CHECK-NEXT: ret i32 [[DIV]] 1066; 1067entry: 1068 %lhs = shl nsw i32 %a, %x 1069 %rhs = shl nuw nsw i32 %a, %y 1070 %div = sdiv i32 %lhs, %rhs 1071 ret i32 %div 1072} 1073 1074define i32 @sdiv_shl_pair2(i32 %a, i32 %x, i32 %y) { 1075; CHECK-LABEL: @sdiv_shl_pair2( 1076; CHECK-NEXT: entry: 1077; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] 1078; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] 1079; CHECK-NEXT: ret i32 [[DIV]] 1080; 1081entry: 1082 %lhs = shl nuw nsw i32 %a, %x 1083 %rhs = shl nsw i32 %a, %y 1084 %div = sdiv i32 %lhs, %rhs 1085 ret i32 %div 1086} 1087 1088define i32 @sdiv_shl_pair3(i32 %a, i32 %x, i32 %y) { 1089; CHECK-LABEL: @sdiv_shl_pair3( 1090; CHECK-NEXT: entry: 1091; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]] 1092; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] 1093; CHECK-NEXT: ret i32 [[DIV]] 1094; 1095entry: 1096 %lhs = shl nsw i32 %a, %x 1097 %rhs = shl nsw i32 %a, %y 1098 %div = sdiv i32 %lhs, %rhs 1099 ret i32 %div 1100} 1101 1102define i32 @sdiv_shl_no_pair_fail(i32 %a, i32 %b, i32 %x, i32 %y) { 1103; CHECK-LABEL: @sdiv_shl_no_pair_fail( 1104; CHECK-NEXT: entry: 1105; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] 1106; CHECK-NEXT: [[RHS:%.*]] = shl nuw i32 [[B:%.*]], [[Y:%.*]] 1107; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]] 1108; CHECK-NEXT: ret i32 [[DIV]] 1109; 1110entry: 1111 %lhs = shl nuw nsw i32 %a, %x 1112 %rhs = shl nuw i32 %b, %y 1113 %div = sdiv i32 %lhs, %rhs 1114 ret i32 %div 1115} 1116 1117define i32 @udiv_shl_pair1(i32 %a, i32 %x, i32 %y) { 1118; CHECK-LABEL: @udiv_shl_pair1( 1119; CHECK-NEXT: entry: 1120; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]] 1121; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] 1122; CHECK-NEXT: ret i32 [[DIV]] 1123; 1124entry: 1125 %lhs = shl nuw i32 %a, %x 1126 %rhs = shl nuw i32 %a, %y 1127 %div = udiv i32 %lhs, %rhs 1128 ret i32 %div 1129} 1130 1131define i32 @udiv_shl_pair2(i32 %a, i32 %x, i32 %y) { 1132; CHECK-LABEL: @udiv_shl_pair2( 1133; CHECK-NEXT: entry: 1134; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] 1135; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] 1136; CHECK-NEXT: ret i32 [[DIV]] 1137; 1138entry: 1139 %lhs = shl nuw nsw i32 %a, %x 1140 %rhs = shl nuw i32 %a, %y 1141 %div = udiv i32 %lhs, %rhs 1142 ret i32 %div 1143} 1144 1145define i32 @udiv_shl_pair3(i32 %a, i32 %x, i32 %y) { 1146; CHECK-LABEL: @udiv_shl_pair3( 1147; CHECK-NEXT: entry: 1148; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]] 1149; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] 1150; CHECK-NEXT: ret i32 [[DIV]] 1151; 1152entry: 1153 %lhs = shl nuw i32 %a, %x 1154 %rhs = shl nuw nsw i32 %a, %y 1155 %div = udiv i32 %lhs, %rhs 1156 ret i32 %div 1157} 1158 1159define i32 @sdiv_shl_pair_overflow_fail1(i32 %a, i32 %x, i32 %y) { 1160; CHECK-LABEL: @sdiv_shl_pair_overflow_fail1( 1161; CHECK-NEXT: entry: 1162; CHECK-NEXT: [[LHS:%.*]] = shl i32 [[A:%.*]], [[X:%.*]] 1163; CHECK-NEXT: [[RHS:%.*]] = shl nsw i32 [[A]], [[Y:%.*]] 1164; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]] 1165; CHECK-NEXT: ret i32 [[DIV]] 1166; 1167entry: 1168 %lhs = shl i32 %a, %x 1169 %rhs = shl nsw i32 %a, %y 1170 %div = sdiv i32 %lhs, %rhs 1171 ret i32 %div 1172} 1173 1174define i32 @sdiv_shl_pair_overflow_fail2(i32 %a, i32 %x, i32 %y) { 1175; CHECK-LABEL: @sdiv_shl_pair_overflow_fail2( 1176; CHECK-NEXT: entry: 1177; CHECK-NEXT: [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]] 1178; CHECK-NEXT: [[RHS:%.*]] = shl nuw i32 [[A]], [[Y:%.*]] 1179; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]] 1180; CHECK-NEXT: ret i32 [[DIV]] 1181; 1182entry: 1183 %lhs = shl nsw i32 %a, %x 1184 %rhs = shl nuw i32 %a, %y 1185 %div = sdiv i32 %lhs, %rhs 1186 ret i32 %div 1187} 1188 1189define i32 @udiv_shl_pair_overflow_fail1(i32 %a, i32 %x, i32 %y) { 1190; CHECK-LABEL: @udiv_shl_pair_overflow_fail1( 1191; CHECK-NEXT: entry: 1192; CHECK-NEXT: [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]] 1193; CHECK-NEXT: [[RHS:%.*]] = shl nuw i32 [[A]], [[Y:%.*]] 1194; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]] 1195; CHECK-NEXT: ret i32 [[DIV]] 1196; 1197entry: 1198 %lhs = shl nsw i32 %a, %x 1199 %rhs = shl nuw i32 %a, %y 1200 %div = udiv i32 %lhs, %rhs 1201 ret i32 %div 1202} 1203 1204define i32 @udiv_shl_pair_overflow_fail2(i32 %a, i32 %x, i32 %y) { 1205; CHECK-LABEL: @udiv_shl_pair_overflow_fail2( 1206; CHECK-NEXT: entry: 1207; CHECK-NEXT: [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]] 1208; CHECK-NEXT: [[RHS:%.*]] = shl i32 [[A]], [[Y:%.*]] 1209; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]] 1210; CHECK-NEXT: ret i32 [[DIV]] 1211; 1212entry: 1213 %lhs = shl nsw i32 %a, %x 1214 %rhs = shl i32 %a, %y 1215 %div = udiv i32 %lhs, %rhs 1216 ret i32 %div 1217} 1218 1219define i32 @udiv_shl_pair_overflow_fail3(i32 %a, i32 %x, i32 %y) { 1220; CHECK-LABEL: @udiv_shl_pair_overflow_fail3( 1221; CHECK-NEXT: entry: 1222; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] 1223; CHECK-NEXT: [[RHS:%.*]] = shl i32 [[A]], [[Y:%.*]] 1224; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]] 1225; CHECK-NEXT: ret i32 [[DIV]] 1226; 1227entry: 1228 %lhs = shl nuw nsw i32 %a, %x 1229 %rhs = shl i32 %a, %y 1230 %div = udiv i32 %lhs, %rhs 1231 ret i32 %div 1232} 1233 1234define i32 @sdiv_shl_pair_multiuse1(i32 %a, i32 %x, i32 %y) { 1235; CHECK-LABEL: @sdiv_shl_pair_multiuse1( 1236; CHECK-NEXT: entry: 1237; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] 1238; CHECK-NEXT: call void @use32(i32 [[LHS]]) 1239; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X]] 1240; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] 1241; CHECK-NEXT: ret i32 [[DIV]] 1242; 1243entry: 1244 %lhs = shl nuw nsw i32 %a, %x 1245 call void @use32(i32 %lhs) 1246 %rhs = shl nsw i32 %a, %y 1247 %div = sdiv i32 %lhs, %rhs 1248 ret i32 %div 1249} 1250 1251define i32 @sdiv_shl_pair_multiuse2(i32 %a, i32 %x, i32 %y) { 1252; CHECK-LABEL: @sdiv_shl_pair_multiuse2( 1253; CHECK-NEXT: entry: 1254; CHECK-NEXT: [[RHS:%.*]] = shl nsw i32 [[A:%.*]], [[Y:%.*]] 1255; CHECK-NEXT: call void @use32(i32 [[RHS]]) 1256; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] 1257; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y]] 1258; CHECK-NEXT: ret i32 [[DIV]] 1259; 1260entry: 1261 %lhs = shl nuw nsw i32 %a, %x 1262 %rhs = shl nsw i32 %a, %y 1263 call void @use32(i32 %rhs) 1264 %div = sdiv i32 %lhs, %rhs 1265 ret i32 %div 1266} 1267 1268define i32 @sdiv_shl_pair_multiuse3(i32 %a, i32 %x, i32 %y) { 1269; CHECK-LABEL: @sdiv_shl_pair_multiuse3( 1270; CHECK-NEXT: entry: 1271; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] 1272; CHECK-NEXT: [[RHS:%.*]] = shl nsw i32 [[A]], [[Y:%.*]] 1273; CHECK-NEXT: call void @use32(i32 [[LHS]]) 1274; CHECK-NEXT: call void @use32(i32 [[RHS]]) 1275; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X]] 1276; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y]] 1277; CHECK-NEXT: ret i32 [[DIV]] 1278; 1279entry: 1280 %lhs = shl nuw nsw i32 %a, %x 1281 %rhs = shl nsw i32 %a, %y 1282 call void @use32(i32 %lhs) 1283 call void @use32(i32 %rhs) 1284 %div = sdiv i32 %lhs, %rhs 1285 ret i32 %div 1286} 1287 1288@a = external global i32 1289define i32 @pr69291() { 1290; CHECK-LABEL: @pr69291( 1291; CHECK-NEXT: entry: 1292; CHECK-NEXT: ret i32 1 1293; 1294entry: 1295 %conv = load i32, ptr @a, align 1 1296 %add = shl nuw nsw i32 %conv, 1 1297 %add2 = shl nuw nsw i32 %conv, 1 1298 %div = sdiv i32 %add, %add2 1299 ret i32 %div 1300} 1301 1302define i8 @udiv_if_power_of_two(i8 %x, i8 %y) { 1303; CHECK-LABEL: @udiv_if_power_of_two( 1304; CHECK-NEXT: start: 1305; CHECK-NEXT: [[TMP0:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[Y:%.*]]) 1306; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1 1307; CHECK-NEXT: br i1 [[TMP1]], label [[BB1:%.*]], label [[BB3:%.*]] 1308; CHECK: bb1: 1309; CHECK-NEXT: [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[Y]], i1 true) 1310; CHECK-NEXT: [[TMP3:%.*]] = lshr i8 [[X:%.*]], [[TMP2]] 1311; CHECK-NEXT: br label [[BB3]] 1312; CHECK: bb3: 1313; CHECK-NEXT: [[_0_SROA_0_0:%.*]] = phi i8 [ [[TMP3]], [[BB1]] ], [ 0, [[START:%.*]] ] 1314; CHECK-NEXT: ret i8 [[_0_SROA_0_0]] 1315; 1316start: 1317 %ctpop = tail call i8 @llvm.ctpop.i8(i8 %y) 1318 %cmp = icmp eq i8 %ctpop, 1 1319 br i1 %cmp, label %bb1, label %bb3 1320 1321bb1: 1322 %div = udiv i8 %x, %y 1323 br label %bb3 1324 1325bb3: 1326 %result = phi i8 [ %div, %bb1 ], [ 0, %start ] 1327 ret i8 %result 1328} 1329 1330define i8 @udiv_exact_assume_power_of_two(i8 %x, i8 %y) { 1331; CHECK-LABEL: @udiv_exact_assume_power_of_two( 1332; CHECK-NEXT: start: 1333; CHECK-NEXT: [[TMP0:%.*]] = tail call range(i8 1, 9) i8 @llvm.ctpop.i8(i8 [[Y:%.*]]) 1334; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[TMP0]], 1 1335; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]]) 1336; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[Y]], i1 true) 1337; CHECK-NEXT: [[_0:%.*]] = lshr exact i8 [[X:%.*]], [[TMP1]] 1338; CHECK-NEXT: ret i8 [[_0]] 1339; 1340start: 1341 %ctpop = tail call i8 @llvm.ctpop.i8(i8 %y) 1342 %cond = icmp eq i8 %ctpop, 1 1343 tail call void @llvm.assume(i1 %cond) 1344 %div = udiv exact i8 %x, %y 1345 ret i8 %div 1346} 1347 1348define i7 @udiv_assume_power_of_two_illegal_type(i7 %x, i7 %y) { 1349; CHECK-LABEL: @udiv_assume_power_of_two_illegal_type( 1350; CHECK-NEXT: start: 1351; CHECK-NEXT: [[TMP0:%.*]] = tail call range(i7 1, 8) i7 @llvm.ctpop.i7(i7 [[Y:%.*]]) 1352; CHECK-NEXT: [[COND:%.*]] = icmp eq i7 [[TMP0]], 1 1353; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]]) 1354; CHECK-NEXT: [[TMP1:%.*]] = call range(i7 0, 8) i7 @llvm.cttz.i7(i7 [[Y]], i1 true) 1355; CHECK-NEXT: [[_0:%.*]] = lshr i7 [[X:%.*]], [[TMP1]] 1356; CHECK-NEXT: ret i7 [[_0]] 1357; 1358start: 1359 %ctpop = tail call i7 @llvm.ctpop.i7(i7 %y) 1360 %cond = icmp eq i7 %ctpop, 1 1361 tail call void @llvm.assume(i1 %cond) 1362 %div = udiv i7 %x, %y 1363 ret i7 %div 1364} 1365 1366define i8 @udiv_assume_power_of_two_multiuse(i8 %x, i8 %y) { 1367; CHECK-LABEL: @udiv_assume_power_of_two_multiuse( 1368; CHECK-NEXT: start: 1369; CHECK-NEXT: [[TMP0:%.*]] = tail call range(i8 1, 9) i8 @llvm.ctpop.i8(i8 [[Y:%.*]]) 1370; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[TMP0]], 1 1371; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]]) 1372; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[Y]], i1 true) 1373; CHECK-NEXT: [[_0:%.*]] = lshr i8 [[X:%.*]], [[TMP1]] 1374; CHECK-NEXT: call void @use(i8 [[_0]]) 1375; CHECK-NEXT: ret i8 [[_0]] 1376; 1377start: 1378 %ctpop = tail call i8 @llvm.ctpop.i8(i8 %y) 1379 %cond = icmp eq i8 %ctpop, 1 1380 tail call void @llvm.assume(i1 %cond) 1381 %div = udiv i8 %x, %y 1382 call void @use(i8 %div) 1383 ret i8 %div 1384} 1385 1386define i8 @udiv_power_of_two_negative(i8 %x, i8 %y, i8 %z) { 1387; CHECK-LABEL: @udiv_power_of_two_negative( 1388; CHECK-NEXT: start: 1389; CHECK-NEXT: [[CTPOP:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[Z:%.*]]) 1390; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[CTPOP]], 1 1391; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]]) 1392; CHECK-NEXT: [[_0:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 1393; CHECK-NEXT: ret i8 [[_0]] 1394; 1395start: 1396 %ctpop = tail call i8 @llvm.ctpop.i8(i8 %z) 1397 %cond = icmp eq i8 %ctpop, 1 1398 tail call void @llvm.assume(i1 %cond) 1399 %div = udiv i8 %x, %y 1400 ret i8 %div 1401} 1402