1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3; RUN: opt < %s -passes=instcombine -use-constant-int-for-fixed-length-splat -S | FileCheck %s 4 5declare void @use(i32) 6 7define i32 @test1(i32 %A) { 8; CHECK-LABEL: @test1( 9; CHECK-NEXT: ret i32 [[A:%.*]] 10; 11 %B = sdiv i32 %A, 1 12 ret i32 %B 13} 14 15define i32 @test2(i32 %A) { 16; CHECK-LABEL: @test2( 17; CHECK-NEXT: [[B1:%.*]] = lshr i32 [[A:%.*]], 3 18; CHECK-NEXT: ret i32 [[B1]] 19; 20 %B = udiv i32 %A, 8 21 ret i32 %B 22} 23 24define i32 @sdiv_by_minus1(i32 %A) { 25; CHECK-LABEL: @sdiv_by_minus1( 26; CHECK-NEXT: [[B:%.*]] = sub nsw i32 0, [[A:%.*]] 27; CHECK-NEXT: ret i32 [[B]] 28; 29 %B = sdiv i32 %A, -1 30 ret i32 %B 31} 32 33define <2 x i64> @sdiv_by_minus1_vec(<2 x i64> %x) { 34; CHECK-LABEL: @sdiv_by_minus1_vec( 35; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i64> zeroinitializer, [[X:%.*]] 36; CHECK-NEXT: ret <2 x i64> [[DIV]] 37; 38 %div = sdiv <2 x i64> %x, <i64 -1, i64 -1> 39 ret <2 x i64> %div 40} 41 42define <2 x i64> @sdiv_by_minus1_vec_poison_elt(<2 x i64> %x) { 43; CHECK-LABEL: @sdiv_by_minus1_vec_poison_elt( 44; CHECK-NEXT: ret <2 x i64> poison 45; 46 %div = sdiv <2 x i64> %x, <i64 -1, i64 poison> 47 ret <2 x i64> %div 48} 49 50define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) { 51; CHECK-LABEL: @sdiv_by_sext_minus1( 52; CHECK-NEXT: [[DIV:%.*]] = sub nsw i32 0, [[Y:%.*]] 53; CHECK-NEXT: ret i32 [[DIV]] 54; 55 %sext = sext i1 %x to i32 56 %div = sdiv i32 %y, %sext 57 ret i32 %div 58} 59 60define <2 x i32> @sdiv_by_sext_minus1_vec(<2 x i1> %x, <2 x i32> %y) { 61; CHECK-LABEL: @sdiv_by_sext_minus1_vec( 62; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i32> zeroinitializer, [[Y:%.*]] 63; CHECK-NEXT: ret <2 x i32> [[DIV]] 64; 65 %sext = sext <2 x i1> %x to <2 x i32> 66 %div = sdiv <2 x i32> %y, %sext 67 ret <2 x i32> %div 68} 69 70define i8 @udiv_by_negative(i8 %x) { 71; CHECK-LABEL: @udiv_by_negative( 72; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], -7 73; CHECK-NEXT: [[A:%.*]] = zext i1 [[TMP1]] to i8 74; CHECK-NEXT: ret i8 [[A]] 75; 76 %A = udiv i8 %x, 250 77 ret i8 %A 78} 79 80define i32 @udiv_by_minus1(i32 %A) { 81; CHECK-LABEL: @udiv_by_minus1( 82; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -1 83; CHECK-NEXT: [[B:%.*]] = zext i1 [[TMP1]] to i32 84; CHECK-NEXT: ret i32 [[B]] 85; 86 %B = udiv i32 %A, -1 87 ret i32 %B 88} 89 90define <2 x i64> @udiv_by_minus1_vec(<2 x i64> %x) { 91; CHECK-LABEL: @udiv_by_minus1_vec( 92; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], splat (i64 -1) 93; CHECK-NEXT: [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64> 94; CHECK-NEXT: ret <2 x i64> [[DIV]] 95; 96 %div = udiv <2 x i64> %x, <i64 -1, i64 -1> 97 ret <2 x i64> %div 98} 99 100define i32 @udiv_by_sext_all_ones(i1 %x, i32 %y) { 101; CHECK-LABEL: @udiv_by_sext_all_ones( 102; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[Y:%.*]], -1 103; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[TMP1]] to i32 104; CHECK-NEXT: ret i32 [[DIV]] 105; 106 %sext = sext i1 %x to i32 107 %div = udiv i32 %y, %sext 108 ret i32 %div 109} 110 111define <2 x i32> @udiv_by_sext_all_ones_vec(<2 x i1> %x, <2 x i32> %y) { 112; CHECK-LABEL: @udiv_by_sext_all_ones_vec( 113; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[Y:%.*]], splat (i32 -1) 114; CHECK-NEXT: [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> 115; CHECK-NEXT: ret <2 x i32> [[DIV]] 116; 117 %sext = sext <2 x i1> %x to <2 x i32> 118 %div = udiv <2 x i32> %y, %sext 119 ret <2 x i32> %div 120} 121 122define i32 @test5(i32 %A) { 123; CHECK-LABEL: @test5( 124; CHECK-NEXT: ret i32 0 125; 126 %B = udiv i32 %A, -16 127 %C = udiv i32 %B, -4 128 ret i32 %C 129} 130 131define i1 @test6(i32 %A) { 132; CHECK-LABEL: @test6( 133; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A:%.*]], 123 134; CHECK-NEXT: ret i1 [[C]] 135; 136 %B = udiv i32 %A, 123 137 ; A < 123 138 %C = icmp eq i32 %B, 0 139 ret i1 %C 140} 141 142define i1 @test7(i32 %A) { 143; CHECK-LABEL: @test7( 144; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -20 145; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A_OFF]], 10 146; CHECK-NEXT: ret i1 [[C]] 147; 148 %B = udiv i32 %A, 10 149 ; A >= 20 && A < 30 150 %C = icmp eq i32 %B, 2 151 ret i1 %C 152} 153 154define <2 x i1> @test7vec(<2 x i32> %A) { 155; CHECK-LABEL: @test7vec( 156; CHECK-NEXT: [[A_OFF:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -20) 157; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[A_OFF]], splat (i32 10) 158; CHECK-NEXT: ret <2 x i1> [[C]] 159; 160 %B = udiv <2 x i32> %A, <i32 10, i32 10> 161 %C = icmp eq <2 x i32> %B, <i32 2, i32 2> 162 ret <2 x i1> %C 163} 164 165define i1 @test8(i8 %A) { 166; CHECK-LABEL: @test8( 167; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[A:%.*]], -11 168; CHECK-NEXT: ret i1 [[C]] 169; 170 %B = udiv i8 %A, 123 171 ; A >= 246 172 %C = icmp eq i8 %B, 2 173 ret i1 %C 174} 175 176define <2 x i1> @test8vec(<2 x i8> %A) { 177; CHECK-LABEL: @test8vec( 178; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> [[A:%.*]], splat (i8 -11) 179; CHECK-NEXT: ret <2 x i1> [[C]] 180; 181 %B = udiv <2 x i8> %A, <i8 123, i8 123> 182 %C = icmp eq <2 x i8> %B, <i8 2, i8 2> 183 ret <2 x i1> %C 184} 185 186define i1 @test9(i8 %A) { 187; CHECK-LABEL: @test9( 188; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[A:%.*]], -10 189; CHECK-NEXT: ret i1 [[C]] 190; 191 %B = udiv i8 %A, 123 192 ; A < 246 193 %C = icmp ne i8 %B, 2 194 ret i1 %C 195} 196 197define <2 x i1> @test9vec(<2 x i8> %A) { 198; CHECK-LABEL: @test9vec( 199; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> [[A:%.*]], splat (i8 -10) 200; CHECK-NEXT: ret <2 x i1> [[C]] 201; 202 %B = udiv <2 x i8> %A, <i8 123, i8 123> 203 %C = icmp ne <2 x i8> %B, <i8 2, i8 2> 204 ret <2 x i1> %C 205} 206 207define i32 @test10(i32 %X, i1 %C) { 208; CHECK-LABEL: @test10( 209; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i32 6, i32 3 210; CHECK-NEXT: [[R1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]] 211; CHECK-NEXT: ret i32 [[R1]] 212; 213 %V = select i1 %C, i32 64, i32 8 214 %R = udiv i32 %X, %V 215 ret i32 %R 216} 217 218define i32 @test11(i32 %X, i1 %C) { 219; CHECK-LABEL: @test11( 220; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i32 10, i32 5 221; CHECK-NEXT: [[B1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]] 222; CHECK-NEXT: ret i32 [[B1]] 223; 224 %A = select i1 %C, i32 1024, i32 32 225 %B = udiv i32 %X, %A 226 ret i32 %B 227} 228 229; PR2328 230define i32 @test12(i32 %x) { 231; CHECK-LABEL: @test12( 232; CHECK-NEXT: ret i32 1 233; 234 %tmp3 = udiv i32 %x, %x ; 1 235 ret i32 %tmp3 236} 237 238define i32 @test13(i32 %x) { 239; CHECK-LABEL: @test13( 240; CHECK-NEXT: ret i32 1 241; 242 %tmp3 = sdiv i32 %x, %x ; 1 243 ret i32 %tmp3 244} 245 246define i32 @test14(i8 %x) { 247; CHECK-LABEL: @test14( 248; CHECK-NEXT: ret i32 0 249; 250 %zext = zext i8 %x to i32 251 %div = udiv i32 %zext, 257 ; 0 252 ret i32 %div 253} 254 255; PR9814 256define i32 @test15(i32 %a, i32 %b) { 257; CHECK-LABEL: @test15( 258; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], -2 259; CHECK-NEXT: [[DIV21:%.*]] = lshr i32 [[A:%.*]], [[TMP1]] 260; CHECK-NEXT: ret i32 [[DIV21]] 261; 262 %shl = shl i32 1, %b 263 %div = lshr i32 %shl, 2 264 %div2 = udiv i32 %a, %div 265 ret i32 %div2 266} 267 268define <2 x i64> @test16(<2 x i64> %x) { 269; CHECK-LABEL: @test16( 270; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i64> [[X:%.*]], splat (i64 192) 271; CHECK-NEXT: ret <2 x i64> [[DIV]] 272; 273 %shr = lshr <2 x i64> %x, <i64 5, i64 5> 274 %div = udiv <2 x i64> %shr, <i64 6, i64 6> 275 ret <2 x i64> %div 276} 277 278define i32 @test19(i32 %x) { 279; CHECK-LABEL: @test19( 280; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1 281; CHECK-NEXT: [[A:%.*]] = zext i1 [[TMP1]] to i32 282; CHECK-NEXT: ret i32 [[A]] 283; 284 %A = udiv i32 1, %x 285 ret i32 %A 286} 287 288define <2 x i32> @test19vec(<2 x i32> %x) { 289; CHECK-LABEL: @test19vec( 290; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 1) 291; CHECK-NEXT: [[A:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> 292; CHECK-NEXT: ret <2 x i32> [[A]] 293; 294 %A = udiv <2 x i32> <i32 1, i32 1>, %x 295 ret <2 x i32> %A 296} 297 298define i32 @test20(i32 %x) { 299; CHECK-LABEL: @test20( 300; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] 301; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X_FR]], 1 302; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3 303; CHECK-NEXT: [[A:%.*]] = select i1 [[TMP2]], i32 [[X_FR]], i32 0 304; CHECK-NEXT: ret i32 [[A]] 305; 306 %A = sdiv i32 1, %x 307 ret i32 %A 308} 309 310define <2 x i32> @test20vec(<2 x i32> %x) { 311; CHECK-LABEL: @test20vec( 312; CHECK-NEXT: [[X_FR:%.*]] = freeze <2 x i32> [[X:%.*]] 313; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X_FR]], splat (i32 1) 314; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 3) 315; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[X_FR]], <2 x i32> zeroinitializer 316; CHECK-NEXT: ret <2 x i32> [[A]] 317; 318 %A = sdiv <2 x i32> <i32 1, i32 1>, %x 319 ret <2 x i32> %A 320} 321 322define i32 @test21(i32 %a) { 323; CHECK-LABEL: @test21( 324; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], 3 325; CHECK-NEXT: ret i32 [[DIV]] 326; 327 %shl = shl nsw i32 %a, 2 328 %div = sdiv i32 %shl, 12 329 ret i32 %div 330} 331 332define i32 @test22(i32 %a) { 333; CHECK-LABEL: @test22( 334; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], 4 335; CHECK-NEXT: ret i32 [[DIV]] 336; 337 %mul = mul nsw i32 %a, 3 338 %div = sdiv i32 %mul, 12 339 ret i32 %div 340} 341 342define i32 @test23(i32 %a) { 343; CHECK-LABEL: @test23( 344; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[A:%.*]], 3 345; CHECK-NEXT: ret i32 [[DIV]] 346; 347 %shl = shl nuw i32 %a, 2 348 %div = udiv i32 %shl, 12 349 ret i32 %div 350} 351 352define i32 @test24(i32 %a) { 353; CHECK-LABEL: @test24( 354; CHECK-NEXT: [[DIV1:%.*]] = lshr i32 [[A:%.*]], 2 355; CHECK-NEXT: ret i32 [[DIV1]] 356; 357 %mul = mul nuw i32 %a, 3 358 %div = udiv i32 %mul, 12 359 ret i32 %div 360} 361 362define i32 @test25(i32 %a) { 363; CHECK-LABEL: @test25( 364; CHECK-NEXT: [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 1 365; CHECK-NEXT: ret i32 [[DIV]] 366; 367 %shl = shl nsw i32 %a, 2 368 %div = sdiv i32 %shl, 2 369 ret i32 %div 370} 371 372define i32 @test26(i32 %a) { 373; CHECK-LABEL: @test26( 374; CHECK-NEXT: [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 2 375; CHECK-NEXT: ret i32 [[DIV]] 376; 377 %mul = mul nsw i32 %a, 12 378 %div = sdiv i32 %mul, 3 379 ret i32 %div 380} 381 382define i32 @test27(i32 %a) { 383; CHECK-LABEL: @test27( 384; CHECK-NEXT: [[DIV:%.*]] = shl nuw i32 [[A:%.*]], 1 385; CHECK-NEXT: ret i32 [[DIV]] 386; 387 %shl = shl nuw i32 %a, 2 388 %div = udiv i32 %shl, 2 389 ret i32 %div 390} 391 392define i32 @test28(i32 %a) { 393; CHECK-LABEL: @test28( 394; CHECK-NEXT: [[DIV:%.*]] = mul nuw i32 [[A:%.*]], 12 395; CHECK-NEXT: ret i32 [[DIV]] 396; 397 %mul = mul nuw i32 %a, 36 398 %div = udiv i32 %mul, 3 399 ret i32 %div 400} 401 402define i32 @test29(i32 %a) { 403; CHECK-LABEL: @test29( 404; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], 0 405; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[TMP1]] to i32 406; CHECK-NEXT: ret i32 [[DIV]] 407; 408 %mul = shl nsw i32 %a, 31 409 %div = sdiv i32 %mul, -2147483648 410 ret i32 %div 411} 412 413define i32 @test30(i32 %a) { 414; CHECK-LABEL: @test30( 415; CHECK-NEXT: ret i32 [[A:%.*]] 416; 417 %mul = shl nuw i32 %a, 31 418 %div = udiv i32 %mul, -2147483648 419 ret i32 %div 420} 421 422define <2 x i32> @test31(<2 x i32> %x) { 423; CHECK-LABEL: @test31( 424; CHECK-NEXT: ret <2 x i32> zeroinitializer 425; 426 %shr = lshr <2 x i32> %x, <i32 31, i32 31> 427 %div = udiv <2 x i32> %shr, <i32 2147483647, i32 2147483647> 428 ret <2 x i32> %div 429} 430 431define i32 @test32(i32 %a, i32 %b) { 432; CHECK-LABEL: @test32( 433; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], -1 434; CHECK-NEXT: [[DIV2:%.*]] = lshr i32 [[A:%.*]], [[TMP1]] 435; CHECK-NEXT: ret i32 [[DIV2]] 436; 437 %shl = shl i32 2, %b 438 %div = lshr i32 %shl, 2 439 %div2 = udiv i32 %a, %div 440 ret i32 %div2 441} 442 443define <2 x i64> @test33(<2 x i64> %x) { 444; CHECK-LABEL: @test33( 445; CHECK-NEXT: [[DIV:%.*]] = udiv exact <2 x i64> [[X:%.*]], splat (i64 192) 446; CHECK-NEXT: ret <2 x i64> [[DIV]] 447; 448 %shr = lshr exact <2 x i64> %x, <i64 5, i64 5> 449 %div = udiv exact <2 x i64> %shr, <i64 6, i64 6> 450 ret <2 x i64> %div 451} 452 453; -X / C --> X / -C (if negation does not overflow) 454 455define i8 @sdiv_negated_dividend_constant_divisor(i8 %x) { 456; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor( 457; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], 42 458; CHECK-NEXT: ret i8 [[D]] 459; 460 %neg = sub nsw i8 0, %x 461 %d = sdiv i8 %neg, -42 462 ret i8 %d 463} 464 465define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_splat(<2 x i8> %x) { 466; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_splat( 467; CHECK-NEXT: [[D:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 42) 468; CHECK-NEXT: ret <2 x i8> [[D]] 469; 470 %neg = sub nsw <2 x i8> zeroinitializer, %x 471 %d = sdiv <2 x i8> %neg, <i8 -42, i8 -42> 472 ret <2 x i8> %d 473} 474 475define i8 @sdiv_exact_negated_dividend_constant_divisor(i8 %x) { 476; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor( 477; CHECK-NEXT: [[D:%.*]] = sdiv exact i8 [[X:%.*]], 42 478; CHECK-NEXT: ret i8 [[D]] 479; 480 %neg = sub nsw i8 0, %x 481 %d = sdiv exact i8 %neg, -42 482 ret i8 %d 483} 484 485define <2 x i8> @sdiv_exact_negated_dividend_constant_divisor_vec_splat(<2 x i8> %x) { 486; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec_splat( 487; CHECK-NEXT: [[D:%.*]] = sdiv exact <2 x i8> [[X:%.*]], splat (i8 42) 488; CHECK-NEXT: ret <2 x i8> [[D]] 489; 490 %neg = sub nsw <2 x i8> zeroinitializer, %x 491 %d = sdiv exact <2 x i8> %neg, <i8 -42, i8 -42> 492 ret <2 x i8> %d 493} 494 495define i8 @sdiv_negated_dividend_constant_divisor_smin(i8 %x) { 496; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_smin( 497; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128 498; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i8 499; CHECK-NEXT: ret i8 [[D]] 500; 501 %neg = sub nsw i8 0, %x 502 %d = sdiv i8 %neg, -128 503 ret i8 %d 504} 505 506define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_splat_smin(<2 x i8> %x) { 507; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_splat_smin( 508; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128) 509; CHECK-NEXT: [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> 510; CHECK-NEXT: ret <2 x i8> [[D]] 511; 512 %neg = sub nsw <2 x i8> zeroinitializer, %x 513 %d = sdiv <2 x i8> %neg, <i8 -128, i8 -128> 514 ret <2 x i8> %d 515} 516 517define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_poison(<2 x i8> %x) { 518; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_poison( 519; CHECK-NEXT: ret <2 x i8> poison 520; 521 %neg = sub nsw <2 x i8> zeroinitializer, %x 522 %d = sdiv <2 x i8> %neg, <i8 -128, i8 poison> 523 ret <2 x i8> %d 524} 525 526define <2 x i64> @sdiv_negated_dividend_constant_divisor_vec(<2 x i64> %x) { 527; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec( 528; CHECK-NEXT: [[DIV1_NEG:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 -3, i64 -4> 529; CHECK-NEXT: ret <2 x i64> [[DIV1_NEG]] 530; 531 %neg = sub nsw <2 x i64> zeroinitializer, %x 532 %div = sdiv <2 x i64> %neg, <i64 3, i64 4> 533 ret <2 x i64> %div 534} 535 536define <2 x i64> @sdiv_exact_negated_dividend_constant_divisor_vec(<2 x i64> %x) { 537; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec( 538; CHECK-NEXT: [[DIV1_NEG:%.*]] = sdiv exact <2 x i64> [[X:%.*]], <i64 -3, i64 -4> 539; CHECK-NEXT: ret <2 x i64> [[DIV1_NEG]] 540; 541 %neg = sub nsw <2 x i64> zeroinitializer, %x 542 %div = sdiv exact <2 x i64> %neg, <i64 3, i64 4> 543 ret <2 x i64> %div 544} 545 546; Can't negate signed min vector element. 547 548define <2 x i8> @sdiv_exact_negated_dividend_constant_divisor_vec_overflow(<2 x i8> %x) { 549; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec_overflow( 550; CHECK-NEXT: [[DIV1:%.*]] = sdiv exact <2 x i8> [[X:%.*]], <i8 -128, i8 42> 551; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i8> zeroinitializer, [[DIV1]] 552; CHECK-NEXT: ret <2 x i8> [[DIV]] 553; 554 %neg = sub nsw <2 x i8> zeroinitializer, %x 555 %div = sdiv exact <2 x i8> %neg, <i8 -128, i8 42> 556 ret <2 x i8> %div 557} 558 559define i32 @test35(i32 %A) { 560; CHECK-LABEL: @test35( 561; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 2147483647 562; CHECK-NEXT: [[MUL:%.*]] = udiv exact i32 [[AND]], 2147483647 563; CHECK-NEXT: ret i32 [[MUL]] 564; 565 %and = and i32 %A, 2147483647 566 %mul = sdiv exact i32 %and, 2147483647 567 ret i32 %mul 568} 569 570define <2 x i32> @test35vec(<2 x i32> %A) { 571; CHECK-LABEL: @test35vec( 572; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647) 573; CHECK-NEXT: [[MUL:%.*]] = udiv exact <2 x i32> [[AND]], splat (i32 2147483647) 574; CHECK-NEXT: ret <2 x i32> [[MUL]] 575; 576 %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647> 577 %mul = sdiv exact <2 x i32> %and, <i32 2147483647, i32 2147483647> 578 ret <2 x i32> %mul 579} 580 581define i32 @test36(i32 %A) { 582; CHECK-LABEL: @test36( 583; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 2147483647 584; CHECK-NEXT: [[MUL:%.*]] = lshr exact i32 [[AND]], [[A]] 585; CHECK-NEXT: ret i32 [[MUL]] 586; 587 %and = and i32 %A, 2147483647 588 %shl = shl nsw i32 1, %A 589 %mul = sdiv exact i32 %and, %shl 590 ret i32 %mul 591} 592 593define <2 x i32> @test36vec(<2 x i32> %A) { 594; CHECK-LABEL: @test36vec( 595; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647) 596; CHECK-NEXT: [[MUL:%.*]] = lshr exact <2 x i32> [[AND]], [[A]] 597; CHECK-NEXT: ret <2 x i32> [[MUL]] 598; 599 %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647> 600 %shl = shl nsw <2 x i32> <i32 1, i32 1>, %A 601 %mul = sdiv exact <2 x i32> %and, %shl 602 ret <2 x i32> %mul 603} 604 605define i32 @test37(ptr %b, i1 %c1) { 606; CHECK-LABEL: @test37( 607; CHECK-NEXT: entry: 608; CHECK-NEXT: store i32 0, ptr [[B:%.*]], align 4 609; CHECK-NEXT: br i1 [[C1:%.*]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]] 610; CHECK: lor.rhs: 611; CHECK-NEXT: br label [[LOR_END]] 612; CHECK: lor.end: 613; CHECK-NEXT: ret i32 0 614; 615entry: 616 store i32 0, ptr %b, align 4 617 %0 = load i32, ptr %b, align 4 618 br i1 %c1, label %lor.rhs, label %lor.end 619 620lor.rhs: ; preds = %entry 621 %mul = mul nsw i32 1, %0 622 br label %lor.end 623 624lor.end: ; preds = %lor.rhs, %entry 625 %t.0 = phi i32 [ %0, %entry ], [ %mul, %lor.rhs ] 626 %div = sdiv i32 %t.0, 2 627 ret i32 %div 628} 629 630; We can perform the division in the smaller type. 631 632define i32 @shrink(i8 %x) { 633; CHECK-LABEL: @shrink( 634; CHECK-NEXT: [[TMP1:%.*]] = sdiv i8 [[X:%.*]], 127 635; CHECK-NEXT: [[DIV:%.*]] = sext i8 [[TMP1]] to i32 636; CHECK-NEXT: ret i32 [[DIV]] 637; 638 %conv = sext i8 %x to i32 639 %div = sdiv i32 %conv, 127 640 ret i32 %div 641} 642 643; Division in the smaller type can lead to more optimizations. 644 645define i32 @zap(i8 %x) { 646; CHECK-LABEL: @zap( 647; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128 648; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[TMP1]] to i32 649; CHECK-NEXT: ret i32 [[DIV]] 650; 651 %conv = sext i8 %x to i32 652 %div = sdiv i32 %conv, -128 653 ret i32 %div 654} 655 656; Splat constant divisors should get the same folds. 657 658define <3 x i32> @shrink_vec(<3 x i8> %x) { 659; CHECK-LABEL: @shrink_vec( 660; CHECK-NEXT: [[TMP1:%.*]] = sdiv <3 x i8> [[X:%.*]], splat (i8 127) 661; CHECK-NEXT: [[DIV:%.*]] = sext <3 x i8> [[TMP1]] to <3 x i32> 662; CHECK-NEXT: ret <3 x i32> [[DIV]] 663; 664 %conv = sext <3 x i8> %x to <3 x i32> 665 %div = sdiv <3 x i32> %conv, <i32 127, i32 127, i32 127> 666 ret <3 x i32> %div 667} 668 669define <2 x i32> @zap_vec(<2 x i8> %x) { 670; CHECK-LABEL: @zap_vec( 671; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128) 672; CHECK-NEXT: [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> 673; CHECK-NEXT: ret <2 x i32> [[DIV]] 674; 675 %conv = sext <2 x i8> %x to <2 x i32> 676 %div = sdiv <2 x i32> %conv, <i32 -128, i32 -128> 677 ret <2 x i32> %div 678} 679 680; But we can't do this if the signed constant won't fit in the original type. 681 682define i32 @shrink_no(i8 %x) { 683; CHECK-LABEL: @shrink_no( 684; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 685; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 128 686; CHECK-NEXT: ret i32 [[DIV]] 687; 688 %conv = sext i8 %x to i32 689 %div = sdiv i32 %conv, 128 690 ret i32 %div 691} 692 693; When the divisor is known larger than the quotient, 694; InstSimplify should kill it before InstCombine sees it. 695 696define i32 @shrink_no2(i8 %x) { 697; CHECK-LABEL: @shrink_no2( 698; CHECK-NEXT: ret i32 0 699; 700 %conv = sext i8 %x to i32 701 %div = sdiv i32 %conv, -129 702 ret i32 %div 703} 704 705define i32 @shrink_no3(i16 %x) { 706; CHECK-LABEL: @shrink_no3( 707; CHECK-NEXT: ret i32 0 708; 709 %conv = sext i16 %x to i32 710 %div = sdiv i32 %conv, 65535 711 ret i32 %div 712} 713 714; This previously crashed when trying to simplify the zext/icmp this becomes. 715define <2 x i8> @PR34841(<2 x i8> %x) { 716; CHECK-LABEL: @PR34841( 717; CHECK-NEXT: ret <2 x i8> zeroinitializer 718; 719 %neg = and <2 x i8> %x, <i8 2, i8 2> 720 %div = udiv <2 x i8> <i8 1, i8 1>, %neg 721 ret <2 x i8> %div 722} 723 724; X / (X * Y) -> 1 / Y if the multiplication does not overflow 725 726define i8 @div_factor_signed(i8 %x, i8 %y) { 727; CHECK-LABEL: @div_factor_signed( 728; CHECK-NEXT: [[Y_FR:%.*]] = freeze i8 [[Y:%.*]] 729; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y_FR]], 1 730; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 3 731; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i8 [[Y_FR]], i8 0 732; CHECK-NEXT: ret i8 [[R]] 733; 734 %a = mul nsw i8 %x, %y 735 %r = sdiv i8 %x, %a 736 ret i8 %r 737} 738 739; X / (Y * X) -> 1 / Y if the multiplication does not overflow 740 741define <2 x i8> @div_factor_signed_vec(<2 x i8> %x, <2 x i8> %y) { 742; CHECK-LABEL: @div_factor_signed_vec( 743; CHECK-NEXT: [[Y_FR:%.*]] = freeze <2 x i8> [[Y:%.*]] 744; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[Y_FR]], splat (i8 1) 745; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i8> [[TMP1]], splat (i8 3) 746; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i8> [[Y_FR]], <2 x i8> zeroinitializer 747; CHECK-NEXT: ret <2 x i8> [[R]] 748; 749 %a = mul nsw <2 x i8> %y, %x 750 %r = sdiv <2 x i8> %x, %a 751 ret <2 x i8> %r 752} 753 754; X / (Y * X) -> 1 / Y if the multiplication does not overflow 755 756define i8 @div_factor_unsigned(i8 %x, i8 %y) { 757; CHECK-LABEL: @div_factor_unsigned( 758; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 1 759; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i8 760; CHECK-NEXT: ret i8 [[R]] 761; 762 %a = mul nuw i8 %y, %x 763 %r = udiv i8 %x, %a 764 ret i8 %r 765} 766 767; X / (X * Y) -> 1 / Y if the multiplication does not overflow 768 769define <2 x i8> @div_factor_unsigned_vec(<2 x i8> %x, <2 x i8> %y) { 770; CHECK-LABEL: @div_factor_unsigned_vec( 771; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[Y:%.*]], splat (i8 1) 772; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> 773; CHECK-NEXT: ret <2 x i8> [[R]] 774; 775 %a = mul nuw <2 x i8> %x, %y 776 %r = udiv <2 x i8> %x, %a 777 ret <2 x i8> %r 778} 779 780define i8 @udiv_common_factor(i8 %x, i8 %y, i8 %z) { 781; CHECK-LABEL: @udiv_common_factor( 782; CHECK-NEXT: [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 783; CHECK-NEXT: ret i8 [[C]] 784; 785 %a = mul nuw i8 %z, %x 786 %b = mul nuw i8 %z, %y 787 %c = udiv i8 %a, %b 788 ret i8 %c 789} 790 791define <2 x i8> @udiv_common_factor_commute1_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 792; CHECK-LABEL: @udiv_common_factor_commute1_vec( 793; CHECK-NEXT: [[C:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]] 794; CHECK-NEXT: ret <2 x i8> [[C]] 795; 796 %a = mul nuw <2 x i8> %x, %z 797 %b = mul nuw <2 x i8> %z, %y 798 %c = udiv <2 x i8> %a, %b 799 ret <2 x i8> %c 800} 801 802define i8 @udiv_common_factor_commute2(i8 %x, i8 %y, i8 %z) { 803; CHECK-LABEL: @udiv_common_factor_commute2( 804; CHECK-NEXT: [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 805; CHECK-NEXT: ret i8 [[C]] 806; 807 %a = mul nuw i8 %x, %z 808 %b = mul nuw i8 %y, %z 809 %c = udiv i8 %a, %b 810 ret i8 %c 811} 812 813define i8 @udiv_common_factor_commute3(i8 %x, i8 %y, i8 %z) { 814; CHECK-LABEL: @udiv_common_factor_commute3( 815; CHECK-NEXT: [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 816; CHECK-NEXT: ret i8 [[C]] 817; 818 %a = mul nuw i8 %z, %x 819 %b = mul nuw i8 %y, %z 820 %c = udiv i8 %a, %b 821 ret i8 %c 822} 823 824; Negative test: both mul must be 'nuw'. 825 826define i8 @udiv_common_factor_not_nuw(i8 %x, i8 %y, i8 %z) { 827; CHECK-LABEL: @udiv_common_factor_not_nuw( 828; CHECK-NEXT: [[A:%.*]] = mul i8 [[Z:%.*]], [[X:%.*]] 829; CHECK-NEXT: [[B:%.*]] = mul nuw i8 [[Z]], [[Y:%.*]] 830; CHECK-NEXT: [[C:%.*]] = udiv i8 [[A]], [[B]] 831; CHECK-NEXT: ret i8 [[C]] 832; 833 %a = mul i8 %z, %x 834 %b = mul nuw i8 %z, %y 835 %c = udiv i8 %a, %b 836 ret i8 %c 837} 838 839; Negative test: both mul must be 'nuw'. 840 841define <2 x i8> @udiv_common_factor_not_nuw_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 842; CHECK-LABEL: @udiv_common_factor_not_nuw_vec( 843; CHECK-NEXT: [[A:%.*]] = mul nuw <2 x i8> [[Z:%.*]], [[X:%.*]] 844; CHECK-NEXT: [[B:%.*]] = mul <2 x i8> [[Z]], [[Y:%.*]] 845; CHECK-NEXT: [[C:%.*]] = udiv <2 x i8> [[A]], [[B]] 846; CHECK-NEXT: ret <2 x i8> [[C]] 847; 848 %a = mul nuw <2 x i8> %z, %x 849 %b = mul <2 x i8> %z, %y 850 %c = udiv <2 x i8> %a, %b 851 ret <2 x i8> %c 852} 853 854define i32 @test_exact_nsw_exact(i32 %x) { 855; CHECK-LABEL: @test_exact_nsw_exact( 856; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv exact i32 [[X:%.*]], -3 857; CHECK-NEXT: ret i32 [[DIV_NEG]] 858; 859 %div = sdiv exact i32 %x, 3 860 %neg = sub nsw i32 0, %div 861 ret i32 %neg 862} 863 864define <2 x i64> @test_exact_vec(<2 x i64> %x) { 865; CHECK-LABEL: @test_exact_vec( 866; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv exact <2 x i64> [[X:%.*]], <i64 -3, i64 -4> 867; CHECK-NEXT: ret <2 x i64> [[DIV_NEG]] 868; 869 %div = sdiv exact <2 x i64> %x, <i64 3, i64 4> 870 %neg = sub nsw <2 x i64> zeroinitializer, %div 871 ret <2 x i64> %neg 872} 873 874; Constant is safe to negate. 875 876define <2 x i8> @negate_sdiv_vec_splat(<2 x i8> %x) { 877; CHECK-LABEL: @negate_sdiv_vec_splat( 878; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 -42) 879; CHECK-NEXT: ret <2 x i8> [[DIV_NEG]] 880; 881 %div = sdiv <2 x i8> %x, <i8 42, i8 42> 882 %neg = sub <2 x i8> zeroinitializer, %div 883 ret <2 x i8> %neg 884} 885 886; Dividing by poison is UB. 887 888define <2 x i8> @negate_sdiv_vec_poison_elt(<2 x i8> %x) { 889; CHECK-LABEL: @negate_sdiv_vec_poison_elt( 890; CHECK-NEXT: ret <2 x i8> poison 891; 892 %div = sdiv <2 x i8> %x, <i8 poison, i8 42> 893 %neg = sub <2 x i8> zeroinitializer, %div 894 ret <2 x i8> %neg 895} 896 897; Division by -1 may be UB (if numerator is the signed min val), but div-by-1 can be simplified. 898 899define <2 x i8> @negate_sdiv_vec_splat_one(<2 x i8> %x) { 900; CHECK-LABEL: @negate_sdiv_vec_splat_one( 901; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]] 902; CHECK-NEXT: ret <2 x i8> [[NEG]] 903; 904 %div = sdiv <2 x i8> %x, <i8 1, i8 1> 905 %neg = sub <2 x i8> zeroinitializer, %div 906 ret <2 x i8> %neg 907} 908 909; Can't negate signed-min constant, but can convert to a compare.. 910 911define <2 x i8> @negate_sdiv_vec_splat_signed_min(<2 x i8> %x) { 912; CHECK-LABEL: @negate_sdiv_vec_splat_signed_min( 913; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128) 914; CHECK-NEXT: [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 915; CHECK-NEXT: ret <2 x i8> [[DIV_NEG]] 916; 917 %div = sdiv <2 x i8> %x, <i8 -128, i8 -128> 918 %neg = sub <2 x i8> zeroinitializer, %div 919 ret <2 x i8> %neg 920} 921 922; Division by -1 may be UB for any element of a vector. 923 924define <2 x i8> @negate_sdiv_vec_one_element(<2 x i8> %x) { 925; CHECK-LABEL: @negate_sdiv_vec_one_element( 926; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 -1, i8 1> 927; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]] 928; CHECK-NEXT: ret <2 x i8> [[NEG]] 929; 930 %div = sdiv <2 x i8> %x, <i8 -1, i8 1> 931 %neg = sub <2 x i8> zeroinitializer, %div 932 ret <2 x i8> %neg 933} 934 935; Can't negate signed-min constant for any element of a vector. 936 937define <2 x i8> @negate_sdiv_vec_signed_min_elt(<2 x i8> %x) { 938; CHECK-LABEL: @negate_sdiv_vec_signed_min_elt( 939; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 -1, i8 -128> 940; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]] 941; CHECK-NEXT: ret <2 x i8> [[NEG]] 942; 943 %div = sdiv <2 x i8> %x, <i8 -1, i8 -128> 944 %neg = sub <2 x i8> zeroinitializer, %div 945 ret <2 x i8> %neg 946} 947 948; Division by -1 may be UB and can't negate signed-min. 949 950define <2 x i8> @negate_sdiv_vec_signed_min_and_one_elt(<2 x i8> %x) { 951; CHECK-LABEL: @negate_sdiv_vec_signed_min_and_one_elt( 952; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 1, i8 -128> 953; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]] 954; CHECK-NEXT: ret <2 x i8> [[NEG]] 955; 956 %div = sdiv <2 x i8> %x, <i8 1, i8 -128> 957 %neg = sub <2 x i8> zeroinitializer, %div 958 ret <2 x i8> %neg 959} 960 961define i32 @test_exact_nonsw_exact(i32 %x) { 962; CHECK-LABEL: @test_exact_nonsw_exact( 963; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv exact i32 [[X:%.*]], -3 964; CHECK-NEXT: ret i32 [[DIV_NEG]] 965; 966 %div = sdiv exact i32 %x, 3 967 %neg = sub i32 0, %div 968 ret i32 %neg 969} 970 971define i32 @test_exact_nsw_noexact(i32 %x) { 972; CHECK-LABEL: @test_exact_nsw_noexact( 973; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv i32 [[X:%.*]], -3 974; CHECK-NEXT: ret i32 [[DIV_NEG]] 975; 976 %div = sdiv i32 %x, 3 977 %neg = sub nsw i32 0, %div 978 ret i32 %neg 979} 980 981define i32 @test_exact_nonsw_noexact(i32 %x) { 982; CHECK-LABEL: @test_exact_nonsw_noexact( 983; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv i32 [[X:%.*]], -3 984; CHECK-NEXT: ret i32 [[DIV_NEG]] 985; 986 %div = sdiv i32 %x, 3 987 %neg = sub i32 0, %div 988 ret i32 %neg 989} 990 991define i32 @test_exact_div_nonconst(i32 %x, i32 %y) { 992; CHECK-LABEL: @test_exact_div_nonconst( 993; CHECK-NEXT: [[DIV:%.*]] = sdiv exact i32 [[X:%.*]], [[Y:%.*]] 994; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[DIV]] 995; CHECK-NEXT: ret i32 [[NEG]] 996; 997 %div = sdiv exact i32 %x, %y 998 %neg = sub nsw i32 0, %div 999 ret i32 %neg 1000} 1001 1002define i32 @test_exact_div_one(i32 %x) { 1003; CHECK-LABEL: @test_exact_div_one( 1004; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]] 1005; CHECK-NEXT: ret i32 [[NEG]] 1006; 1007 %div = sdiv exact i32 %x, 1 1008 %neg = sub nsw i32 0, %div 1009 ret i32 %neg 1010} 1011 1012define i8 @test_exact_div_minSigned(i8 %x) { 1013; CHECK-LABEL: @test_exact_div_minSigned( 1014; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128 1015; CHECK-NEXT: [[DIV_NEG:%.*]] = sext i1 [[TMP1]] to i8 1016; CHECK-NEXT: ret i8 [[DIV_NEG]] 1017; 1018 %div = sdiv exact i8 %x, -128 1019 %neg = sub nsw i8 0, %div 1020 ret i8 %neg 1021} 1022 1023; X / INT_MIN --> X == INT_MIN 1024 1025define i8 @sdiv_by_int_min(i8 %x) { 1026; CHECK-LABEL: @sdiv_by_int_min( 1027; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128 1028; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i8 1029; CHECK-NEXT: ret i8 [[D]] 1030; 1031 %d = sdiv i8 %x, -128 1032 ret i8 %d 1033} 1034 1035define <2 x i8> @sdiv_by_int_min_vec_splat(<2 x i8> %x) { 1036; CHECK-LABEL: @sdiv_by_int_min_vec_splat( 1037; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128) 1038; CHECK-NEXT: [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> 1039; CHECK-NEXT: ret <2 x i8> [[D]] 1040; 1041 %d = sdiv <2 x i8> %x, <i8 -128, i8 -128> 1042 ret <2 x i8> %d 1043} 1044 1045define <2 x i8> @sdiv_by_int_min_vec_splat_poison(<2 x i8> %x) { 1046; CHECK-LABEL: @sdiv_by_int_min_vec_splat_poison( 1047; CHECK-NEXT: ret <2 x i8> poison 1048; 1049 %d = sdiv <2 x i8> %x, <i8 -128, i8 poison> 1050 ret <2 x i8> %d 1051} 1052 1053define <2 x i8> @sdiv_by_negconst_v2i8(<2 x i8> %x) { 1054; CHECK-LABEL: @sdiv_by_negconst_v2i8( 1055; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 108) 1056; CHECK-NEXT: ret <2 x i8> [[DIV_NEG]] 1057; 1058 %div = sdiv <2 x i8> %x, <i8 -108, i8 -108> 1059 %sub = sub <2 x i8> zeroinitializer, %div 1060 ret <2 x i8> %sub 1061} 1062 1063define <vscale x 2 x i8> @sdiv_by_negconst_nxv2i8(<vscale x 2 x i8> %x) { 1064; CHECK-LABEL: @sdiv_by_negconst_nxv2i8( 1065; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv <vscale x 2 x i8> [[X:%.*]], splat (i8 108) 1066; CHECK-NEXT: ret <vscale x 2 x i8> [[DIV_NEG]] 1067; 1068 %div = sdiv <vscale x 2 x i8> %x, splat (i8 -108) 1069 %sub = sub <vscale x 2 x i8> zeroinitializer, %div 1070 ret <vscale x 2 x i8> %sub 1071} 1072 1073define <2 x i8> @sdiv_by_minSigned_v2i8(<2 x i8> %x) { 1074; CHECK-LABEL: @sdiv_by_minSigned_v2i8( 1075; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128) 1076; CHECK-NEXT: [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 1077; CHECK-NEXT: ret <2 x i8> [[DIV_NEG]] 1078; 1079 %div = sdiv <2 x i8> %x, <i8 -128, i8 -128> 1080 %sub = sub <2 x i8> zeroinitializer, %div 1081 ret <2 x i8> %sub 1082} 1083 1084define <vscale x 2 x i8> @sdiv_by_minSigned_nxv2i8(<vscale x 2 x i8> %x) { 1085; CHECK-LABEL: @sdiv_by_minSigned_nxv2i8( 1086; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <vscale x 2 x i8> [[X:%.*]], splat (i8 -128) 1087; CHECK-NEXT: [[DIV_NEG:%.*]] = sext <vscale x 2 x i1> [[TMP1]] to <vscale x 2 x i8> 1088; CHECK-NEXT: ret <vscale x 2 x i8> [[DIV_NEG]] 1089; 1090 %div = sdiv <vscale x 2 x i8> %x, splat (i8 -128) 1091 %sub = sub <vscale x 2 x i8> zeroinitializer, %div 1092 ret <vscale x 2 x i8> %sub 1093} 1094 1095define i32 @sdiv_constant_dividend_select_of_constants_divisor(i1 %b) { 1096; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor( 1097; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 3, i32 -14 1098; CHECK-NEXT: ret i32 [[R]] 1099; 1100 %s = select i1 %b, i32 12, i32 -3 1101 %r = sdiv i32 42, %s 1102 ret i32 %r 1103} 1104 1105define i32 @sdiv_constant_dividend_select_of_constants_divisor_use(i1 %b) { 1106; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_use( 1107; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3 1108; CHECK-NEXT: call void @use(i32 [[S]]) 1109; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i32 3, i32 -14 1110; CHECK-NEXT: ret i32 [[R]] 1111; 1112 %s = select i1 %b, i32 12, i32 -3 1113 call void @use(i32 %s) 1114 %r = sdiv i32 42, %s 1115 ret i32 %r 1116} 1117 1118define i32 @sdiv_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) { 1119; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_0_arm( 1120; CHECK-NEXT: ret i32 3 1121; 1122 %s = select i1 %b, i32 12, i32 0 1123 %r = sdiv i32 42, %s 1124 ret i32 %r 1125} 1126 1127; negative test - not safe to speculate div with variable divisor 1128 1129define i32 @sdiv_constant_dividend_select_divisor1(i1 %b, i32 %x) { 1130; CHECK-LABEL: @sdiv_constant_dividend_select_divisor1( 1131; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3 1132; CHECK-NEXT: [[R:%.*]] = sdiv i32 42, [[S]] 1133; CHECK-NEXT: ret i32 [[R]] 1134; 1135 %s = select i1 %b, i32 %x, i32 -3 1136 %r = sdiv i32 42, %s 1137 ret i32 %r 1138} 1139 1140; negative test - not safe to speculate div with variable divisor 1141 1142define i32 @sdiv_constant_dividend_select_divisor2(i1 %b, i32 %x) { 1143; CHECK-LABEL: @sdiv_constant_dividend_select_divisor2( 1144; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]] 1145; CHECK-NEXT: [[R:%.*]] = sdiv i32 42, [[S]] 1146; CHECK-NEXT: ret i32 [[R]] 1147; 1148 %s = select i1 %b, i32 12, i32 %x 1149 %r = sdiv i32 42, %s 1150 ret i32 %r 1151} 1152 1153define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec(i1 %b) { 1154; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec( 1155; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 8>, <2 x i8> splat (i8 -10) 1156; CHECK-NEXT: ret <2 x i8> [[R]] 1157; 1158 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4> 1159 %r = sdiv <2 x i8> <i8 42, i8 -42>, %s 1160 ret <2 x i8> %r 1161} 1162 1163; Div-by-0 element is immediate UB, so select is simplified. 1164 1165define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) { 1166; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec_ub1( 1167; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 poison, i8 8>, <2 x i8> splat (i8 -10) 1168; CHECK-NEXT: ret <2 x i8> [[R]] 1169; 1170 %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4> 1171 %r = sdiv <2 x i8> <i8 42, i8 -42>, %s 1172 ret <2 x i8> %r 1173} 1174 1175; SMIN / -1 element is poison. 1176 1177define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) { 1178; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2( 1179; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 25>, <2 x i8> <i8 -10, i8 poison> 1180; CHECK-NEXT: ret <2 x i8> [[R]] 1181; 1182 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1> 1183 %r = sdiv <2 x i8> <i8 42, i8 -128>, %s 1184 ret <2 x i8> %r 1185} 1186 1187; negative test - must have constant dividend 1188 1189define i32 @sdiv_select_of_constants_divisor(i1 %b, i32 %x) { 1190; CHECK-LABEL: @sdiv_select_of_constants_divisor( 1191; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3 1192; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[X:%.*]], [[S]] 1193; CHECK-NEXT: ret i32 [[R]] 1194; 1195 %s = select i1 %b, i32 12, i32 -3 1196 %r = sdiv i32 %x, %s 1197 ret i32 %r 1198} 1199 1200define i32 @udiv_constant_dividend_select_of_constants_divisor(i1 %b) { 1201; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor( 1202; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 3, i32 0 1203; CHECK-NEXT: ret i32 [[R]] 1204; 1205 %s = select i1 %b, i32 12, i32 -3 1206 %r = udiv i32 42, %s 1207 ret i32 %r 1208} 1209 1210define i32 @udiv_constant_dividend_select_of_constants_divisor_use(i1 %b) { 1211; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_use( 1212; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3 1213; CHECK-NEXT: call void @use(i32 [[S]]) 1214; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i32 3, i32 0 1215; CHECK-NEXT: ret i32 [[R]] 1216; 1217 %s = select i1 %b, i32 12, i32 -3 1218 call void @use(i32 %s) 1219 %r = udiv i32 42, %s 1220 ret i32 %r 1221} 1222 1223; Div-by-0 is immediate UB, so select is simplified. 1224 1225define i32 @udiv_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) { 1226; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_0_arm( 1227; CHECK-NEXT: ret i32 3 1228; 1229 %s = select i1 %b, i32 12, i32 0 1230 %r = udiv i32 42, %s 1231 ret i32 %r 1232} 1233 1234; negative test - not safe to speculate div with variable divisor 1235 1236define i32 @udiv_constant_dividend_select_divisor1(i1 %b, i32 %x) { 1237; CHECK-LABEL: @udiv_constant_dividend_select_divisor1( 1238; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3 1239; CHECK-NEXT: [[R:%.*]] = udiv i32 42, [[S]] 1240; CHECK-NEXT: ret i32 [[R]] 1241; 1242 %s = select i1 %b, i32 %x, i32 -3 1243 %r = udiv i32 42, %s 1244 ret i32 %r 1245} 1246 1247; negative test - not safe to speculate div with variable divisor 1248 1249define i32 @udiv_constant_dividend_select_divisor2(i1 %b, i32 %x) { 1250; CHECK-LABEL: @udiv_constant_dividend_select_divisor2( 1251; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]] 1252; CHECK-NEXT: [[R:%.*]] = udiv i32 42, [[S]] 1253; CHECK-NEXT: ret i32 [[R]] 1254; 1255 %s = select i1 %b, i32 12, i32 %x 1256 %r = udiv i32 42, %s 1257 ret i32 %r 1258} 1259 1260define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec(i1 %b) { 1261; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec( 1262; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> <i8 0, i8 53> 1263; CHECK-NEXT: ret <2 x i8> [[R]] 1264; 1265 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4> 1266 %r = udiv <2 x i8> <i8 42, i8 -42>, %s 1267 ret <2 x i8> %r 1268} 1269 1270; Div-by-0 element is immediate UB, so select is simplified. 1271 1272define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) { 1273; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub1( 1274; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 poison, i8 0>, <2 x i8> <i8 0, i8 53> 1275; CHECK-NEXT: ret <2 x i8> [[R]] 1276; 1277 %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4> 1278 %r = udiv <2 x i8> <i8 42, i8 -42>, %s 1279 ret <2 x i8> %r 1280} 1281 1282; There's no unsigned equivalent to "SMIN / -1", so this is just the usual constant folding. 1283 1284define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) { 1285; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub2( 1286; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> zeroinitializer 1287; CHECK-NEXT: ret <2 x i8> [[R]] 1288; 1289 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1> 1290 %r = udiv <2 x i8> <i8 42, i8 -128>, %s 1291 ret <2 x i8> %r 1292} 1293 1294; negative test - must have constant dividend 1295 1296define i32 @udiv_select_of_constants_divisor(i1 %b, i32 %x) { 1297; CHECK-LABEL: @udiv_select_of_constants_divisor( 1298; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3 1299; CHECK-NEXT: [[R:%.*]] = udiv i32 [[X:%.*]], [[S]] 1300; CHECK-NEXT: ret i32 [[R]] 1301; 1302 %s = select i1 %b, i32 12, i32 -3 1303 %r = udiv i32 %x, %s 1304 ret i32 %r 1305} 1306 1307; PR34063 1308; 1 / X !=/== -1 1309 1310define i1 @sdiv_one_icmpeq_one(i32 %x) { 1311; CHECK-LABEL: @sdiv_one_icmpeq_one( 1312; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] 1313; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X_FR]], 1 1314; CHECK-NEXT: ret i1 [[B1]] 1315; 1316 %A = sdiv i32 1, %x 1317 %B = icmp eq i32 %A, 1 1318 ret i1 %B 1319} 1320 1321define i1 @sdiv_one_icmpeq_negone(i32 %x) { 1322; CHECK-LABEL: @sdiv_one_icmpeq_negone( 1323; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] 1324; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X_FR]], -1 1325; CHECK-NEXT: ret i1 [[B1]] 1326; 1327 %A = sdiv i32 1, %x 1328 %B = icmp eq i32 %A, -1 1329 ret i1 %B 1330} 1331 1332define i1 @udiv_one_icmpeq_one(i32 %x) { 1333; CHECK-LABEL: @udiv_one_icmpeq_one( 1334; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1 1335; CHECK-NEXT: ret i1 [[TMP1]] 1336; 1337 %A = udiv i32 1, %x 1338 %B = icmp eq i32 %A, 1 1339 ret i1 %B 1340} 1341 1342define i1 @udiv_one_icmpne_one(i32 %x) { 1343; CHECK-LABEL: @udiv_one_icmpne_one( 1344; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 1 1345; CHECK-NEXT: ret i1 [[TMP1]] 1346; 1347 %A = udiv i32 1, %x 1348 %B = icmp ne i32 %A, 1 1349 ret i1 %B 1350} 1351 1352; ((X * Y) / Z) / X --> Y / Z 1353 1354define i8 @udiv_udiv_mul_nuw(i8 %x, i8 %y, i8 %z) { 1355; CHECK-LABEL: @udiv_udiv_mul_nuw( 1356; CHECK-NEXT: [[R:%.*]] = udiv i8 [[Y:%.*]], [[Z:%.*]] 1357; CHECK-NEXT: ret i8 [[R]] 1358; 1359 %m = mul nuw i8 %x, %y 1360 %d = udiv i8 %m, %z 1361 %r = udiv i8 %d, %x 1362 ret i8 %r 1363} 1364 1365; exact propagates and commute is ok 1366 1367define i8 @udiv_udiv_mul_nuw_exact_exact(i8 %x, i8 %y, i8 %z) { 1368; CHECK-LABEL: @udiv_udiv_mul_nuw_exact_exact( 1369; CHECK-NEXT: [[R:%.*]] = udiv exact i8 [[Y:%.*]], [[Z:%.*]] 1370; CHECK-NEXT: ret i8 [[R]] 1371; 1372 %m = mul nuw i8 %y, %x 1373 %d = udiv exact i8 %m, %z 1374 %r = udiv exact i8 %d, %x 1375 ret i8 %r 1376} 1377 1378; extra uses are ok 1379 1380define i32 @udiv_udiv_mul_nuw_exact_use(i32 %x, i32 %y, i32 %z) { 1381; CHECK-LABEL: @udiv_udiv_mul_nuw_exact_use( 1382; CHECK-NEXT: [[M:%.*]] = mul nuw i32 [[X:%.*]], [[Y:%.*]] 1383; CHECK-NEXT: call void @use(i32 [[M]]) 1384; CHECK-NEXT: [[R:%.*]] = udiv i32 [[Y]], [[Z:%.*]] 1385; CHECK-NEXT: ret i32 [[R]] 1386; 1387 %m = mul nuw i32 %x, %y 1388 call void @use(i32 %m) 1389 %d = udiv exact i32 %m, %z 1390 %r = udiv i32 %d, %x 1391 ret i32 %r 1392} 1393 1394; negative test - must have nuw 1395 1396define i8 @udiv_udiv_mul_nsw(i8 %x, i8 %y, i8 %z) { 1397; CHECK-LABEL: @udiv_udiv_mul_nsw( 1398; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]] 1399; CHECK-NEXT: [[D:%.*]] = udiv i8 [[M]], [[Z:%.*]] 1400; CHECK-NEXT: [[R:%.*]] = udiv i8 [[D]], [[X]] 1401; CHECK-NEXT: ret i8 [[R]] 1402; 1403 %m = mul nsw i8 %x, %y 1404 %d = udiv i8 %m, %z 1405 %r = udiv i8 %d, %x 1406 ret i8 %r 1407} 1408 1409; negative test - opcode mismatch 1410 1411define i8 @udiv_sdiv_mul_nuw(i8 %x, i8 %y, i8 %z) { 1412; CHECK-LABEL: @udiv_sdiv_mul_nuw( 1413; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 1414; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[M]], [[Z:%.*]] 1415; CHECK-NEXT: [[R:%.*]] = udiv i8 [[D]], [[X]] 1416; CHECK-NEXT: ret i8 [[R]] 1417; 1418 %m = mul nuw i8 %x, %y 1419 %d = sdiv i8 %m, %z 1420 %r = udiv i8 %d, %x 1421 ret i8 %r 1422} 1423 1424; ((Y * X) / Z) / X --> Y / Z 1425 1426define <2 x i8> @sdiv_sdiv_mul_nsw(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 1427; CHECK-LABEL: @sdiv_sdiv_mul_nsw( 1428; CHECK-NEXT: [[R:%.*]] = sdiv <2 x i8> [[Y:%.*]], [[Z:%.*]] 1429; CHECK-NEXT: ret <2 x i8> [[R]] 1430; 1431 %m = mul nsw <2 x i8> %y, %x 1432 %d = sdiv <2 x i8> %m, %z 1433 %r = sdiv <2 x i8> %d, %x 1434 ret <2 x i8> %r 1435} 1436 1437; (X * C0) / (X * C1) --> C0 / C1 1438define i8 @sdiv_mul_nsw_mul_nsw(i8 %x,i8 %y,i8 %z) { 1439; CHECK-LABEL: @sdiv_mul_nsw_mul_nsw( 1440; CHECK-NEXT: [[ADD4:%.*]] = mul nsw i8 [[X:%.*]], [[Z:%.*]] 1441; CHECK-NEXT: [[ADD5:%.*]] = mul nsw i8 [[X]], [[Y:%.*]] 1442; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[ADD5]], [[ADD4]] 1443; CHECK-NEXT: ret i8 [[DIV]] 1444; 1445 %add4 = mul nsw i8 %x, %z 1446 %add5 = mul nsw i8 %x, %y 1447 %div = sdiv i8 %add5, %add4 1448 ret i8 %div 1449} 1450 1451define i8 @udiv_mul_nuw_mul_nuw(i8 %x,i8 %y,i8 %z) { 1452; CHECK-LABEL: @udiv_mul_nuw_mul_nuw( 1453; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[Y:%.*]], [[Z:%.*]] 1454; CHECK-NEXT: ret i8 [[DIV]] 1455; 1456 %add4 = mul nuw i8 %x, %z 1457 %add5 = mul nuw i8 %x, %y 1458 %div = udiv i8 %add5, %add4 1459 ret i8 %div 1460} 1461 1462define i8 @sdiv_mul_nsw_constant_mul_nsw_constant(i8 %x) { 1463; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_nsw_constant( 1464; CHECK-NEXT: ret i8 2 1465; 1466 %add4 = mul nsw i8 %x, 5 1467 %add5 = mul nsw i8 %x, 10 1468 %div = sdiv i8 %add5, %add4 1469 ret i8 %div 1470} 1471 1472define i4 @sdiv_mul_nsw_constant_mul_constant(i4 %a) { 1473; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant( 1474; CHECK-NEXT: [[ADD4:%.*]] = mul i4 [[A:%.*]], 3 1475; CHECK-NEXT: [[ADD5:%.*]] = mul nsw i4 [[A]], 6 1476; CHECK-NEXT: [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]] 1477; CHECK-NEXT: ret i4 [[DIV]] 1478; 1479 %add4 = mul i4 %a, 3 1480 %add5 = mul nsw i4 %a, 6 1481 %div = sdiv i4 %add5, %add4 1482 ret i4 %div 1483} 1484define i4 @sdiv_mul_nsw_constant_mul_constant2(i4 %a) { 1485; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant2( 1486; CHECK-NEXT: [[ADD4:%.*]] = sub i4 0, [[A:%.*]] 1487; CHECK-NEXT: [[ADD5:%.*]] = shl i4 [[A]], 3 1488; CHECK-NEXT: [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]] 1489; CHECK-NEXT: ret i4 [[DIV]] 1490; 1491 %add4 = mul i4 %a, 15 1492 %add5 = mul nsw i4 %a, 8 1493 %div = sdiv i4 %add5, %add4 1494 ret i4 %div 1495} 1496 1497define i4 @sdiv_mul_nsw_constant_mul_constant3(i4 %a) { 1498; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant3( 1499; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i4 [[A:%.*]], -8 1500; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], i4 1, i4 -1 1501; CHECK-NEXT: ret i4 [[DIV]] 1502; 1503 %add4 = mul i4 %a, 15 1504 %add5 = mul nsw i4 %a, 1 1505 %div = sdiv i4 %add5, %add4 1506 ret i4 %div 1507} 1508 1509define i4 @sdiv_mul_nsw_mul(i4 %a) { 1510; CHECK-LABEL: @sdiv_mul_nsw_mul( 1511; CHECK-NEXT: [[ADD4:%.*]] = sub i4 0, [[A:%.*]] 1512; CHECK-NEXT: [[ADD5:%.*]] = shl i4 [[A]], 3 1513; CHECK-NEXT: [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]] 1514; CHECK-NEXT: ret i4 [[DIV]] 1515; 1516 %add4 = mul i4 %a, -1 1517 %add5 = mul nsw i4 %a, -8 1518 %div = sdiv i4 %add5, %add4 1519 ret i4 %div 1520} 1521 1522define i4 @udiv_mul_nuw_constant_mul_constant(i4 %a) { 1523; CHECK-LABEL: @udiv_mul_nuw_constant_mul_constant( 1524; CHECK-NEXT: ret i4 2 1525; 1526 %add4 = mul i4 %a, 3 1527 %add5 = mul nuw i4 %a, 6 1528 %div = udiv i4 %add5, %add4 1529 ret i4 %div 1530} 1531 1532define i4 @udiv_mul_nuw_mul_negative(i4 %a) { 1533; CHECK-LABEL: @udiv_mul_nuw_mul_negative( 1534; CHECK-NEXT: [[ADD4:%.*]] = mul i4 [[A:%.*]], -3 1535; CHECK-NEXT: [[ADD5:%.*]] = shl nuw i4 [[A]], 2 1536; CHECK-NEXT: [[DIV:%.*]] = udiv i4 [[ADD5]], [[ADD4]] 1537; CHECK-NEXT: ret i4 [[DIV]] 1538; 1539 %add4 = mul i4 %a, 13 1540 %add5 = mul nuw i4 %a, 4 1541 %div = udiv i4 %add5, %add4 1542 ret i4 %div 1543} 1544 1545define i4 @sdiv_mul_nsw_mul_nsw_allones(i4 %a) { 1546; CHECK-LABEL: @sdiv_mul_nsw_mul_nsw_allones( 1547; CHECK-NEXT: [[ADD4:%.*]] = sub nsw i4 0, [[A:%.*]] 1548; CHECK-NEXT: [[ADD5:%.*]] = shl i4 [[A]], 3 1549; CHECK-NEXT: [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]] 1550; CHECK-NEXT: ret i4 [[DIV]] 1551; 1552 %add4 = mul nsw i4 %a, -1 1553 %add5 = mul nsw i4 %a, -8 1554 %div = sdiv i4 %add5, %add4 1555 ret i4 %div 1556} 1557 1558define i4 @sdiv_mul_nsw_mul_signmask(i4 %a, i4 %c2) { 1559; CHECK-LABEL: @sdiv_mul_nsw_mul_signmask( 1560; CHECK-NEXT: [[ADD4:%.*]] = shl i4 [[A:%.*]], 3 1561; CHECK-NEXT: [[ADD5:%.*]] = mul nsw i4 [[A]], [[C2:%.*]] 1562; CHECK-NEXT: [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]] 1563; CHECK-NEXT: ret i4 [[DIV]] 1564; 1565 %add4 = mul nsw i4 %a, -8 1566 %add5 = mul nsw i4 %a, %c2 1567 %div = sdiv i4 %add5, %add4 1568 ret i4 %div 1569} 1570 1571define i32 @sdiv_sub1(i32 %arg) { 1572; CHECK-LABEL: @sdiv_sub1( 1573; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG:%.*]], -2147483648 1574; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -1 1575; CHECK-NEXT: ret i32 [[DIV]] 1576; 1577 %neg = sub i32 0, %arg 1578 %div = sdiv i32 %neg, %arg 1579 ret i32 %div 1580} 1581 1582define i32 @sdiv_sub2(i32 %arg) { 1583; CHECK-LABEL: @sdiv_sub2( 1584; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG:%.*]], -2147483648 1585; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -1 1586; CHECK-NEXT: ret i32 [[DIV]] 1587; 1588 %neg = sub i32 0, %arg 1589 %div = sdiv i32 %arg, %neg 1590 ret i32 %div 1591} 1592 1593define i32 @sub_sdiv_multiuse(i32 %arg) { 1594; CHECK-LABEL: @sub_sdiv_multiuse( 1595; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[ARG:%.*]] 1596; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[ARG]], -2147483648 1597; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -1 1598; CHECK-NEXT: call void @use(i32 [[NEG]]) 1599; CHECK-NEXT: ret i32 [[DIV]] 1600; 1601 %neg = sub i32 0, %arg 1602 %div = sdiv i32 %arg, %neg 1603 call void @use(i32 %neg) 1604 ret i32 %div 1605} 1606 1607define i32 @sdiv_sub_sub(i32 %x ,i32 %y) { 1608; CHECK-LABEL: @sdiv_sub_sub( 1609; CHECK-NEXT: [[S:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 1610; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[S]], -2147483648 1611; CHECK-NEXT: [[D:%.*]] = select i1 [[TMP1]], i32 1, i32 -1 1612; CHECK-NEXT: ret i32 [[D]] 1613; 1614 %s = sub i32 %x, %y 1615 %u = sub i32 %y, %x 1616 %d = sdiv i32 %s, %u 1617 ret i32 %d 1618} 1619 1620define i32 @sdiv_mul_sub(i32 %x, i32 %y) { 1621; CHECK-LABEL: @sdiv_mul_sub( 1622; CHECK-NEXT: [[M:%.*]] = mul i32 [[Y:%.*]], [[X:%.*]] 1623; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[M]], -2147483648 1624; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 1, i32 -1 1625; CHECK-NEXT: ret i32 [[R]] 1626; 1627 %m = mul i32 %y, %x 1628 %d = sub i32 0, %m 1629 %r = sdiv i32 %d, %m 1630 ret i32 %r 1631} 1632 1633define i32 @sdiv_mul_sub_nsw(i32 %x, i32 %y) { 1634; CHECK-LABEL: @sdiv_mul_sub_nsw( 1635; CHECK-NEXT: ret i32 -1 1636; 1637 %m = mul i32 %y, %x 1638 %n = sub nsw i32 0, %m 1639 %d = sdiv i32 %m, %n 1640 ret i32 %d 1641} 1642 1643define i32 @sdiv_mul_nsw_sub_nsw(i32 %x, i32 %y) { 1644; CHECK-LABEL: @sdiv_mul_nsw_sub_nsw( 1645; CHECK-NEXT: ret i32 -1 1646; 1647 %m = mul nsw i32 %y, %x 1648 %n = sub nsw i32 0, %m 1649 %d = sdiv i32 %m, %n 1650 ret i32 %d 1651} 1652 1653; exact propagates 1654 1655define i8 @sdiv_sdiv_mul_nsw_exact_exact(i8 %x, i8 %y, i8 %z) { 1656; CHECK-LABEL: @sdiv_sdiv_mul_nsw_exact_exact( 1657; CHECK-NEXT: [[R:%.*]] = sdiv exact i8 [[Y:%.*]], [[Z:%.*]] 1658; CHECK-NEXT: ret i8 [[R]] 1659; 1660 %m = mul nsw i8 %x, %y 1661 %d = sdiv exact i8 %m, %z 1662 %r = sdiv exact i8 %d, %x 1663 ret i8 %r 1664} 1665 1666; extra uses are ok 1667 1668define i32 @sdiv_sdiv_mul_nsw_exact_use(i32 %x, i32 %y, i32 %z) { 1669; CHECK-LABEL: @sdiv_sdiv_mul_nsw_exact_use( 1670; CHECK-NEXT: [[M:%.*]] = mul nsw i32 [[X:%.*]], [[Y:%.*]] 1671; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[M]], [[Z:%.*]] 1672; CHECK-NEXT: call void @use(i32 [[D]]) 1673; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[Y]], [[Z]] 1674; CHECK-NEXT: ret i32 [[R]] 1675; 1676 %m = mul nsw i32 %x, %y 1677 %d = sdiv i32 %m, %z 1678 call void @use(i32 %d) 1679 %r = sdiv exact i32 %d, %x 1680 ret i32 %r 1681} 1682 1683; negative test - must have nsw 1684 1685define i8 @sdiv_sdiv_mul_nuw(i8 %x, i8 %y, i8 %z) { 1686; CHECK-LABEL: @sdiv_sdiv_mul_nuw( 1687; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 1688; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[M]], [[Z:%.*]] 1689; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[D]], [[X]] 1690; CHECK-NEXT: ret i8 [[R]] 1691; 1692 %m = mul nuw i8 %x, %y 1693 %d = sdiv i8 %m, %z 1694 %r = sdiv i8 %d, %x 1695 ret i8 %r 1696} 1697 1698; negative test - opcode mismatch 1699 1700define i8 @sdiv_udiv_mul_nsw(i8 %x, i8 %y, i8 %z) { 1701; CHECK-LABEL: @sdiv_udiv_mul_nsw( 1702; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]] 1703; CHECK-NEXT: [[D:%.*]] = udiv i8 [[M]], [[Z:%.*]] 1704; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[D]], [[X]] 1705; CHECK-NEXT: ret i8 [[R]] 1706; 1707 %m = mul nsw i8 %x, %y 1708 %d = udiv i8 %m, %z 1709 %r = sdiv i8 %d, %x 1710 ret i8 %r 1711} 1712 1713; ((X * C2) + C1) / C2 --> X + C1/C2 1714 1715define i6 @sdiv_distribute_mul_nsw_add_nsw(i6 %x) { 1716; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw( 1717; CHECK-NEXT: [[DIV:%.*]] = add nsw i6 [[X:%.*]], -5 1718; CHECK-NEXT: ret i6 [[DIV]] 1719; 1720 %mul = mul nsw i6 %x, 3 1721 %add = add nsw i6 %mul, -15 1722 %div = sdiv i6 %add, 3 1723 ret i6 %div 1724} 1725 1726; extra uses are ok 1727 1728define i32 @sdiv_distribute_mul_nsw_add_nsw_uses(i32 %x) { 1729; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw_uses( 1730; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 42 1731; CHECK-NEXT: call void @use(i32 [[MUL]]) 1732; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[MUL]], 126 1733; CHECK-NEXT: call void @use(i32 [[ADD]]) 1734; CHECK-NEXT: [[DIV:%.*]] = add nsw i32 [[X]], 3 1735; CHECK-NEXT: ret i32 [[DIV]] 1736; 1737 %mul = mul nsw i32 %x, 42 1738 call void @use(i32 %mul) 1739 %add = add nsw i32 %mul, 126 1740 call void @use(i32 %add) 1741 %div = sdiv i32 %add, 42 1742 ret i32 %div 1743} 1744 1745; vector splats work 1746 1747define <2 x i6> @udiv_distribute_mul_nuw_add_nuw(<2 x i6> %x) { 1748; CHECK-LABEL: @udiv_distribute_mul_nuw_add_nuw( 1749; CHECK-NEXT: [[DIV:%.*]] = add nuw <2 x i6> [[X:%.*]], splat (i6 5) 1750; CHECK-NEXT: ret <2 x i6> [[DIV]] 1751; 1752 %mul = mul nuw <2 x i6> %x, <i6 3, i6 3> 1753 %add = add nuw <2 x i6> %mul, <i6 15, i6 15> 1754 %div = udiv <2 x i6> %add, <i6 3, i6 3> 1755 ret <2 x i6> %div 1756} 1757 1758; negative test - constants must be evenly divisible 1759 1760define i6 @sdiv_distribute_mul_nsw_add_nsw_not_multiple_offset(i6 %x) { 1761; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw_not_multiple_offset( 1762; CHECK-NEXT: [[MUL:%.*]] = mul nsw i6 [[X:%.*]], 3 1763; CHECK-NEXT: [[ADD:%.*]] = add nsw i6 [[MUL]], -16 1764; CHECK-NEXT: [[DIV:%.*]] = sdiv i6 [[ADD]], 3 1765; CHECK-NEXT: ret i6 [[DIV]] 1766; 1767 %mul = mul nsw i6 %x, 3 1768 %add = add nsw i6 %mul, -16 1769 %div = sdiv i6 %add, 3 1770 ret i6 %div 1771} 1772 1773; constants do not have to be evenly divisible with unsigned division 1774 1775define i6 @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset(i6 %x) { 1776; CHECK-LABEL: @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset( 1777; CHECK-NEXT: [[DIV:%.*]] = add nuw i6 [[X:%.*]], 2 1778; CHECK-NEXT: ret i6 [[DIV]] 1779; 1780 %mul = mul nuw i6 %x, 3 1781 %add = add nuw i6 %mul, 7 1782 %div = udiv i6 %add, 3 1783 ret i6 %div 1784} 1785 1786; negative test - wrong no-wrap 1787 1788define i6 @sdiv_distribute_mul_nuw_add_nsw(i6 %x) { 1789; CHECK-LABEL: @sdiv_distribute_mul_nuw_add_nsw( 1790; CHECK-NEXT: [[MUL:%.*]] = mul nuw i6 [[X:%.*]], 3 1791; CHECK-NEXT: [[ADD:%.*]] = add nsw i6 [[MUL]], -15 1792; CHECK-NEXT: [[DIV:%.*]] = sdiv i6 [[ADD]], 3 1793; CHECK-NEXT: ret i6 [[DIV]] 1794; 1795 %mul = mul nuw i6 %x, 3 1796 %add = add nsw i6 %mul, -15 1797 %div = sdiv i6 %add, 3 1798 ret i6 %div 1799} 1800 1801; negative test - wrong no-wrap 1802 1803define i6 @udiv_distribute_mul_nsw_add_nuw(i6 %x) { 1804; CHECK-LABEL: @udiv_distribute_mul_nsw_add_nuw( 1805; CHECK-NEXT: [[MUL:%.*]] = mul nsw i6 [[X:%.*]], 3 1806; CHECK-NEXT: [[ADD:%.*]] = add nuw i6 [[MUL]], 9 1807; CHECK-NEXT: [[DIV:%.*]] = udiv i6 [[ADD]], 3 1808; CHECK-NEXT: ret i6 [[DIV]] 1809; 1810 %mul = mul nsw i6 %x, 3 1811 %add = add nuw i6 %mul, 9 1812 %div = udiv i6 %add, 3 1813 ret i6 %div 1814} 1815 1816define i32 @fold_disjoint_or_over_sdiv(i32 %x) { 1817; CHECK-LABEL: @fold_disjoint_or_over_sdiv( 1818; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[X:%.*]], 9 1819; CHECK-NEXT: ret i32 [[R]] 1820; 1821 %mul = mul nsw i32 %x, 9 1822 %or = or disjoint i32 %mul, 81 1823 %r = sdiv i32 %or, 9 1824 ret i32 %r 1825} 1826 1827define i32 @fold_disjoint_or_over_udiv(i32 %x) { 1828; CHECK-LABEL: @fold_disjoint_or_over_udiv( 1829; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], 9 1830; CHECK-NEXT: ret i32 [[R]] 1831; 1832 %mul = mul nuw i32 %x, 9 1833 %or = or disjoint i32 %mul, 81 1834 %r = udiv i32 %or, 9 1835 ret i32 %r 1836} 1837 1838define i8 @udiv_trunc_shl(i32 %x) { 1839; CHECK-LABEL: @udiv_trunc_shl( 1840; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1841; CHECK-NEXT: [[UDIV1:%.*]] = lshr i8 8, [[TMP1]] 1842; CHECK-NEXT: ret i8 [[UDIV1]] 1843; 1844 %lshr = shl i32 1, %x 1845 %trunc = trunc i32 %lshr to i8 1846 %div = udiv i8 8, %trunc 1847 ret i8 %div 1848} 1849 1850define i32 @zext_udiv_trunc_lshr(i32 %x) { 1851; CHECK-LABEL: @zext_udiv_trunc_lshr( 1852; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 1853; CHECK-NEXT: [[TMP2:%.*]] = sub i8 5, [[TMP1]] 1854; CHECK-NEXT: [[UDIV1:%.*]] = lshr i8 8, [[TMP2]] 1855; CHECK-NEXT: [[ZEXT:%.*]] = zext nneg i8 [[UDIV1]] to i32 1856; CHECK-NEXT: ret i32 [[ZEXT]] 1857; 1858 %lshr = lshr i32 32, %x 1859 %trunc = trunc i32 %lshr to i8 1860 %div = udiv i8 8, %trunc 1861 %zext = zext i8 %div to i32 1862 ret i32 %zext 1863} 1864 1865define i32 @udiv_and_shl(i32 %a, i32 %b, i32 %c) { 1866; CHECK-LABEL: @udiv_and_shl( 1867; CHECK-NEXT: [[DIV1:%.*]] = lshr i32 [[C:%.*]], [[A:%.*]] 1868; CHECK-NEXT: ret i32 [[DIV1]] 1869; 1870 %shl = shl i32 1, %a 1871 %and = and i32 %b, %shl 1872 %div = udiv i32 %c, %and 1873 ret i32 %div 1874} 1875