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(i32) 5 6define i32 @test1(i32 %A) { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: ret i32 [[A:%.*]] 9; 10 %B = sdiv i32 %A, 1 11 ret i32 %B 12} 13 14define i32 @test2(i32 %A) { 15; CHECK-LABEL: @test2( 16; CHECK-NEXT: [[B1:%.*]] = lshr i32 [[A:%.*]], 3 17; CHECK-NEXT: ret i32 [[B1]] 18; 19 %B = udiv i32 %A, 8 20 ret i32 %B 21} 22 23define i32 @sdiv_by_minus1(i32 %A) { 24; CHECK-LABEL: @sdiv_by_minus1( 25; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[A:%.*]] 26; CHECK-NEXT: ret i32 [[B]] 27; 28 %B = sdiv i32 %A, -1 29 ret i32 %B 30} 31 32define <2 x i64> @sdiv_by_minus1_vec(<2 x i64> %x) { 33; CHECK-LABEL: @sdiv_by_minus1_vec( 34; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i64> zeroinitializer, [[X:%.*]] 35; CHECK-NEXT: ret <2 x i64> [[DIV]] 36; 37 %div = sdiv <2 x i64> %x, <i64 -1, i64 -1> 38 ret <2 x i64> %div 39} 40 41define <2 x i64> @sdiv_by_minus1_vec_poison_elt(<2 x i64> %x) { 42; CHECK-LABEL: @sdiv_by_minus1_vec_poison_elt( 43; CHECK-NEXT: ret <2 x i64> poison 44; 45 %div = sdiv <2 x i64> %x, <i64 -1, i64 poison> 46 ret <2 x i64> %div 47} 48 49define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) { 50; CHECK-LABEL: @sdiv_by_sext_minus1( 51; CHECK-NEXT: [[DIV:%.*]] = sub i32 0, [[Y:%.*]] 52; CHECK-NEXT: ret i32 [[DIV]] 53; 54 %sext = sext i1 %x to i32 55 %div = sdiv i32 %y, %sext 56 ret i32 %div 57} 58 59define <2 x i32> @sdiv_by_sext_minus1_vec(<2 x i1> %x, <2 x i32> %y) { 60; CHECK-LABEL: @sdiv_by_sext_minus1_vec( 61; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i32> zeroinitializer, [[Y:%.*]] 62; CHECK-NEXT: ret <2 x i32> [[DIV]] 63; 64 %sext = sext <2 x i1> %x to <2 x i32> 65 %div = sdiv <2 x i32> %y, %sext 66 ret <2 x i32> %div 67} 68 69define i8 @udiv_by_negative(i8 %x) { 70; CHECK-LABEL: @udiv_by_negative( 71; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], -7 72; CHECK-NEXT: [[A:%.*]] = zext i1 [[TMP1]] to i8 73; CHECK-NEXT: ret i8 [[A]] 74; 75 %A = udiv i8 %x, 250 76 ret i8 %A 77} 78 79define i32 @udiv_by_minus1(i32 %A) { 80; CHECK-LABEL: @udiv_by_minus1( 81; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -1 82; CHECK-NEXT: [[B:%.*]] = zext i1 [[TMP1]] to i32 83; CHECK-NEXT: ret i32 [[B]] 84; 85 %B = udiv i32 %A, -1 86 ret i32 %B 87} 88 89define <2 x i64> @udiv_by_minus1_vec(<2 x i64> %x) { 90; CHECK-LABEL: @udiv_by_minus1_vec( 91; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], <i64 -1, i64 -1> 92; CHECK-NEXT: [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64> 93; CHECK-NEXT: ret <2 x i64> [[DIV]] 94; 95 %div = udiv <2 x i64> %x, <i64 -1, i64 -1> 96 ret <2 x i64> %div 97} 98 99define i32 @udiv_by_sext_all_ones(i1 %x, i32 %y) { 100; CHECK-LABEL: @udiv_by_sext_all_ones( 101; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[Y:%.*]], -1 102; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[TMP1]] to i32 103; CHECK-NEXT: ret i32 [[DIV]] 104; 105 %sext = sext i1 %x to i32 106 %div = udiv i32 %y, %sext 107 ret i32 %div 108} 109 110define <2 x i32> @udiv_by_sext_all_ones_vec(<2 x i1> %x, <2 x i32> %y) { 111; CHECK-LABEL: @udiv_by_sext_all_ones_vec( 112; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[Y:%.*]], <i32 -1, i32 -1> 113; CHECK-NEXT: [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> 114; CHECK-NEXT: ret <2 x i32> [[DIV]] 115; 116 %sext = sext <2 x i1> %x to <2 x i32> 117 %div = udiv <2 x i32> %y, %sext 118 ret <2 x i32> %div 119} 120 121define i32 @test5(i32 %A) { 122; CHECK-LABEL: @test5( 123; CHECK-NEXT: ret i32 0 124; 125 %B = udiv i32 %A, -16 126 %C = udiv i32 %B, -4 127 ret i32 %C 128} 129 130define i1 @test6(i32 %A) { 131; CHECK-LABEL: @test6( 132; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], 123 133; CHECK-NEXT: ret i1 [[TMP1]] 134; 135 %B = udiv i32 %A, 123 136 ; A < 123 137 %C = icmp eq i32 %B, 0 138 ret i1 %C 139} 140 141define i1 @test7(i32 %A) { 142; CHECK-LABEL: @test7( 143; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -20 144; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A_OFF]], 10 145; CHECK-NEXT: ret i1 [[TMP1]] 146; 147 %B = udiv i32 %A, 10 148 ; A >= 20 && A < 30 149 %C = icmp eq i32 %B, 2 150 ret i1 %C 151} 152 153define <2 x i1> @test7vec(<2 x i32> %A) { 154; CHECK-LABEL: @test7vec( 155; CHECK-NEXT: [[A_OFF:%.*]] = add <2 x i32> [[A:%.*]], <i32 -20, i32 -20> 156; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i32> [[A_OFF]], <i32 10, i32 10> 157; CHECK-NEXT: ret <2 x i1> [[TMP1]] 158; 159 %B = udiv <2 x i32> %A, <i32 10, i32 10> 160 %C = icmp eq <2 x i32> %B, <i32 2, i32 2> 161 ret <2 x i1> %C 162} 163 164define i1 @test8(i8 %A) { 165; CHECK-LABEL: @test8( 166; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[A:%.*]], -11 167; CHECK-NEXT: ret i1 [[C]] 168; 169 %B = udiv i8 %A, 123 170 ; A >= 246 171 %C = icmp eq i8 %B, 2 172 ret i1 %C 173} 174 175define <2 x i1> @test8vec(<2 x i8> %A) { 176; CHECK-LABEL: @test8vec( 177; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> [[A:%.*]], <i8 -11, i8 -11> 178; CHECK-NEXT: ret <2 x i1> [[C]] 179; 180 %B = udiv <2 x i8> %A, <i8 123, i8 123> 181 %C = icmp eq <2 x i8> %B, <i8 2, i8 2> 182 ret <2 x i1> %C 183} 184 185define i1 @test9(i8 %A) { 186; CHECK-LABEL: @test9( 187; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[A:%.*]], -10 188; CHECK-NEXT: ret i1 [[C]] 189; 190 %B = udiv i8 %A, 123 191 ; A < 246 192 %C = icmp ne i8 %B, 2 193 ret i1 %C 194} 195 196define <2 x i1> @test9vec(<2 x i8> %A) { 197; CHECK-LABEL: @test9vec( 198; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> [[A:%.*]], <i8 -10, i8 -10> 199; CHECK-NEXT: ret <2 x i1> [[C]] 200; 201 %B = udiv <2 x i8> %A, <i8 123, i8 123> 202 %C = icmp ne <2 x i8> %B, <i8 2, i8 2> 203 ret <2 x i1> %C 204} 205 206define i32 @test10(i32 %X, i1 %C) { 207; CHECK-LABEL: @test10( 208; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i32 6, i32 3 209; CHECK-NEXT: [[R1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]] 210; CHECK-NEXT: ret i32 [[R1]] 211; 212 %V = select i1 %C, i32 64, i32 8 213 %R = udiv i32 %X, %V 214 ret i32 %R 215} 216 217define i32 @test11(i32 %X, i1 %C) { 218; CHECK-LABEL: @test11( 219; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i32 10, i32 5 220; CHECK-NEXT: [[B1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]] 221; CHECK-NEXT: ret i32 [[B1]] 222; 223 %A = select i1 %C, i32 1024, i32 32 224 %B = udiv i32 %X, %A 225 ret i32 %B 226} 227 228; PR2328 229define i32 @test12(i32 %x) { 230; CHECK-LABEL: @test12( 231; CHECK-NEXT: ret i32 1 232; 233 %tmp3 = udiv i32 %x, %x ; 1 234 ret i32 %tmp3 235} 236 237define i32 @test13(i32 %x) { 238; CHECK-LABEL: @test13( 239; CHECK-NEXT: ret i32 1 240; 241 %tmp3 = sdiv i32 %x, %x ; 1 242 ret i32 %tmp3 243} 244 245define i32 @test14(i8 %x) { 246; CHECK-LABEL: @test14( 247; CHECK-NEXT: ret i32 0 248; 249 %zext = zext i8 %x to i32 250 %div = udiv i32 %zext, 257 ; 0 251 ret i32 %div 252} 253 254; PR9814 255define i32 @test15(i32 %a, i32 %b) { 256; CHECK-LABEL: @test15( 257; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], -2 258; CHECK-NEXT: [[DIV21:%.*]] = lshr i32 [[A:%.*]], [[TMP1]] 259; CHECK-NEXT: ret i32 [[DIV21]] 260; 261 %shl = shl i32 1, %b 262 %div = lshr i32 %shl, 2 263 %div2 = udiv i32 %a, %div 264 ret i32 %div2 265} 266 267define <2 x i64> @test16(<2 x i64> %x) { 268; CHECK-LABEL: @test16( 269; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i64> [[X:%.*]], <i64 192, i64 192> 270; CHECK-NEXT: ret <2 x i64> [[DIV]] 271; 272 %shr = lshr <2 x i64> %x, <i64 5, i64 5> 273 %div = udiv <2 x i64> %shr, <i64 6, i64 6> 274 ret <2 x i64> %div 275} 276 277define i32 @test19(i32 %x) { 278; CHECK-LABEL: @test19( 279; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1 280; CHECK-NEXT: [[A:%.*]] = zext i1 [[TMP1]] to i32 281; CHECK-NEXT: ret i32 [[A]] 282; 283 %A = udiv i32 1, %x 284 ret i32 %A 285} 286 287define <2 x i32> @test19vec(<2 x i32> %x) { 288; CHECK-LABEL: @test19vec( 289; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 1, i32 1> 290; CHECK-NEXT: [[A:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> 291; CHECK-NEXT: ret <2 x i32> [[A]] 292; 293 %A = udiv <2 x i32> <i32 1, i32 1>, %x 294 ret <2 x i32> %A 295} 296 297define i32 @test20(i32 %x) { 298; CHECK-LABEL: @test20( 299; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] 300; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X_FR]], 1 301; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3 302; CHECK-NEXT: [[A:%.*]] = select i1 [[TMP2]], i32 [[X_FR]], i32 0 303; CHECK-NEXT: ret i32 [[A]] 304; 305 %A = sdiv i32 1, %x 306 ret i32 %A 307} 308 309define <2 x i32> @test20vec(<2 x i32> %x) { 310; CHECK-LABEL: @test20vec( 311; CHECK-NEXT: [[X_FR:%.*]] = freeze <2 x i32> [[X:%.*]] 312; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X_FR]], <i32 1, i32 1> 313; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 3, i32 3> 314; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[X_FR]], <2 x i32> zeroinitializer 315; CHECK-NEXT: ret <2 x i32> [[A]] 316; 317 %A = sdiv <2 x i32> <i32 1, i32 1>, %x 318 ret <2 x i32> %A 319} 320 321define i32 @test21(i32 %a) { 322; CHECK-LABEL: @test21( 323; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], 3 324; CHECK-NEXT: ret i32 [[DIV]] 325; 326 %shl = shl nsw i32 %a, 2 327 %div = sdiv i32 %shl, 12 328 ret i32 %div 329} 330 331define i32 @test22(i32 %a) { 332; CHECK-LABEL: @test22( 333; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], 4 334; CHECK-NEXT: ret i32 [[DIV]] 335; 336 %mul = mul nsw i32 %a, 3 337 %div = sdiv i32 %mul, 12 338 ret i32 %div 339} 340 341define i32 @test23(i32 %a) { 342; CHECK-LABEL: @test23( 343; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[A:%.*]], 3 344; CHECK-NEXT: ret i32 [[DIV]] 345; 346 %shl = shl nuw i32 %a, 2 347 %div = udiv i32 %shl, 12 348 ret i32 %div 349} 350 351define i32 @test24(i32 %a) { 352; CHECK-LABEL: @test24( 353; CHECK-NEXT: [[DIV1:%.*]] = lshr i32 [[A:%.*]], 2 354; CHECK-NEXT: ret i32 [[DIV1]] 355; 356 %mul = mul nuw i32 %a, 3 357 %div = udiv i32 %mul, 12 358 ret i32 %div 359} 360 361define i32 @test25(i32 %a) { 362; CHECK-LABEL: @test25( 363; CHECK-NEXT: [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 1 364; CHECK-NEXT: ret i32 [[DIV]] 365; 366 %shl = shl nsw i32 %a, 2 367 %div = sdiv i32 %shl, 2 368 ret i32 %div 369} 370 371define i32 @test26(i32 %a) { 372; CHECK-LABEL: @test26( 373; CHECK-NEXT: [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 2 374; CHECK-NEXT: ret i32 [[DIV]] 375; 376 %mul = mul nsw i32 %a, 12 377 %div = sdiv i32 %mul, 3 378 ret i32 %div 379} 380 381define i32 @test27(i32 %a) { 382; CHECK-LABEL: @test27( 383; CHECK-NEXT: [[DIV:%.*]] = shl nuw i32 [[A:%.*]], 1 384; CHECK-NEXT: ret i32 [[DIV]] 385; 386 %shl = shl nuw i32 %a, 2 387 %div = udiv i32 %shl, 2 388 ret i32 %div 389} 390 391define i32 @test28(i32 %a) { 392; CHECK-LABEL: @test28( 393; CHECK-NEXT: [[DIV:%.*]] = mul nuw i32 [[A:%.*]], 12 394; CHECK-NEXT: ret i32 [[DIV]] 395; 396 %mul = mul nuw i32 %a, 36 397 %div = udiv i32 %mul, 3 398 ret i32 %div 399} 400 401define i32 @test29(i32 %a) { 402; CHECK-LABEL: @test29( 403; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -1 404; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[TMP1]] to i32 405; CHECK-NEXT: ret i32 [[DIV]] 406; 407 %mul = shl nsw i32 %a, 31 408 %div = sdiv i32 %mul, -2147483648 409 ret i32 %div 410} 411 412define i32 @test30(i32 %a) { 413; CHECK-LABEL: @test30( 414; CHECK-NEXT: ret i32 [[A:%.*]] 415; 416 %mul = shl nuw i32 %a, 31 417 %div = udiv i32 %mul, -2147483648 418 ret i32 %div 419} 420 421define <2 x i32> @test31(<2 x i32> %x) { 422; CHECK-LABEL: @test31( 423; CHECK-NEXT: ret <2 x i32> zeroinitializer 424; 425 %shr = lshr <2 x i32> %x, <i32 31, i32 31> 426 %div = udiv <2 x i32> %shr, <i32 2147483647, i32 2147483647> 427 ret <2 x i32> %div 428} 429 430define i32 @test32(i32 %a, i32 %b) { 431; CHECK-LABEL: @test32( 432; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, [[B:%.*]] 433; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL]], 2 434; CHECK-NEXT: [[DIV2:%.*]] = udiv i32 [[A:%.*]], [[DIV]] 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:%.*]], <i64 192, 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:%.*]], <i8 42, 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:%.*]], <i8 42, 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:%.*]], <i8 -128, 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:%.*]], <i32 2147483647, i32 2147483647> 573; CHECK-NEXT: [[MUL:%.*]] = udiv exact <2 x i32> [[AND]], <i32 2147483647, 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: [[MUL1:%.*]] = lshr exact i32 [[AND]], [[A]] 585; CHECK-NEXT: ret i32 [[MUL1]] 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:%.*]], <i32 2147483647, i32 2147483647> 596; CHECK-NEXT: [[MUL1:%.*]] = lshr exact <2 x i32> [[AND]], [[A]] 597; CHECK-NEXT: ret <2 x i32> [[MUL1]] 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(i32* %b, i1 %c1) { 606; CHECK-LABEL: @test37( 607; CHECK-NEXT: entry: 608; CHECK-NEXT: store i32 0, i32* [[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, i32* %b, align 4 617 %0 = load i32, i32* %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:%.*]], <i8 127, i8 127, 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:%.*]], <i8 -128, 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]], <i8 1, i8 1> 745; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i8> [[TMP1]], <i8 3, 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:%.*]], <i8 1, 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:%.*]], <i8 -42, 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:%.*]], <i8 -128, 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:%.*]], <i8 -128, 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:%.*]], <i8 108, 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:%.*]], shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 108, i32 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer) 1066; CHECK-NEXT: ret <vscale x 2 x i8> [[DIV_NEG]] 1067; 1068 %div = sdiv <vscale x 2 x i8> %x, shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 -108, i32 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer) 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:%.*]], <i8 -128, 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:%.*]], shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 -128, i32 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer) 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, shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 -128, i32 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer) 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> <i8 -10, 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: ret <2 x i8> <i8 -10, i8 -10> 1168; 1169 %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4> 1170 %r = sdiv <2 x i8> <i8 42, i8 -42>, %s 1171 ret <2 x i8> %r 1172} 1173 1174; SMIN / -1 element is poison. 1175 1176define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) { 1177; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2( 1178; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 25>, <2 x i8> <i8 -10, i8 poison> 1179; CHECK-NEXT: ret <2 x i8> [[R]] 1180; 1181 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1> 1182 %r = sdiv <2 x i8> <i8 42, i8 -128>, %s 1183 ret <2 x i8> %r 1184} 1185 1186; negative test - must have constant dividend 1187 1188define i32 @sdiv_select_of_constants_divisor(i1 %b, i32 %x) { 1189; CHECK-LABEL: @sdiv_select_of_constants_divisor( 1190; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3 1191; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[X:%.*]], [[S]] 1192; CHECK-NEXT: ret i32 [[R]] 1193; 1194 %s = select i1 %b, i32 12, i32 -3 1195 %r = sdiv i32 %x, %s 1196 ret i32 %r 1197} 1198 1199define i32 @udiv_constant_dividend_select_of_constants_divisor(i1 %b) { 1200; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor( 1201; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 3, i32 0 1202; CHECK-NEXT: ret i32 [[R]] 1203; 1204 %s = select i1 %b, i32 12, i32 -3 1205 %r = udiv i32 42, %s 1206 ret i32 %r 1207} 1208 1209define i32 @udiv_constant_dividend_select_of_constants_divisor_use(i1 %b) { 1210; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_use( 1211; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3 1212; CHECK-NEXT: call void @use(i32 [[S]]) 1213; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i32 3, i32 0 1214; CHECK-NEXT: ret i32 [[R]] 1215; 1216 %s = select i1 %b, i32 12, i32 -3 1217 call void @use(i32 %s) 1218 %r = udiv i32 42, %s 1219 ret i32 %r 1220} 1221 1222; Div-by-0 is immediate UB, so select is simplified. 1223 1224define i32 @udiv_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) { 1225; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_0_arm( 1226; CHECK-NEXT: ret i32 3 1227; 1228 %s = select i1 %b, i32 12, i32 0 1229 %r = udiv i32 42, %s 1230 ret i32 %r 1231} 1232 1233; negative test - not safe to speculate div with variable divisor 1234 1235define i32 @udiv_constant_dividend_select_divisor1(i1 %b, i32 %x) { 1236; CHECK-LABEL: @udiv_constant_dividend_select_divisor1( 1237; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3 1238; CHECK-NEXT: [[R:%.*]] = udiv i32 42, [[S]] 1239; CHECK-NEXT: ret i32 [[R]] 1240; 1241 %s = select i1 %b, i32 %x, i32 -3 1242 %r = udiv i32 42, %s 1243 ret i32 %r 1244} 1245 1246; negative test - not safe to speculate div with variable divisor 1247 1248define i32 @udiv_constant_dividend_select_divisor2(i1 %b, i32 %x) { 1249; CHECK-LABEL: @udiv_constant_dividend_select_divisor2( 1250; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]] 1251; CHECK-NEXT: [[R:%.*]] = udiv i32 42, [[S]] 1252; CHECK-NEXT: ret i32 [[R]] 1253; 1254 %s = select i1 %b, i32 12, i32 %x 1255 %r = udiv i32 42, %s 1256 ret i32 %r 1257} 1258 1259define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec(i1 %b) { 1260; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec( 1261; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> <i8 0, i8 53> 1262; CHECK-NEXT: ret <2 x i8> [[R]] 1263; 1264 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4> 1265 %r = udiv <2 x i8> <i8 42, i8 -42>, %s 1266 ret <2 x i8> %r 1267} 1268 1269; Div-by-0 element is immediate UB, so select is simplified. 1270 1271define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) { 1272; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub1( 1273; CHECK-NEXT: ret <2 x i8> <i8 0, i8 53> 1274; 1275 %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4> 1276 %r = udiv <2 x i8> <i8 42, i8 -42>, %s 1277 ret <2 x i8> %r 1278} 1279 1280; There's no unsigned equivalent to "SMIN / -1", so this is just the usual constant folding. 1281 1282define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) { 1283; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub2( 1284; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> zeroinitializer 1285; CHECK-NEXT: ret <2 x i8> [[R]] 1286; 1287 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1> 1288 %r = udiv <2 x i8> <i8 42, i8 -128>, %s 1289 ret <2 x i8> %r 1290} 1291 1292; negative test - must have constant dividend 1293 1294define i32 @udiv_select_of_constants_divisor(i1 %b, i32 %x) { 1295; CHECK-LABEL: @udiv_select_of_constants_divisor( 1296; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3 1297; CHECK-NEXT: [[R:%.*]] = udiv i32 [[X:%.*]], [[S]] 1298; CHECK-NEXT: ret i32 [[R]] 1299; 1300 %s = select i1 %b, i32 12, i32 -3 1301 %r = udiv i32 %x, %s 1302 ret i32 %r 1303} 1304 1305; PR34063 1306; 1 / X !=/== -1 1307 1308define i1 @sdiv_one_icmpeq_one(i32 %x) { 1309; CHECK-LABEL: @sdiv_one_icmpeq_one( 1310; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] 1311; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X_FR]], 1 1312; CHECK-NEXT: ret i1 [[TMP1]] 1313; 1314 %A = sdiv i32 1, %x 1315 %B = icmp eq i32 %A, 1 1316 ret i1 %B 1317} 1318 1319define i1 @sdiv_one_icmpeq_negone(i32 %x) { 1320; CHECK-LABEL: @sdiv_one_icmpeq_negone( 1321; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] 1322; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X_FR]], -1 1323; CHECK-NEXT: ret i1 [[TMP1]] 1324; 1325 %A = sdiv i32 1, %x 1326 %B = icmp eq i32 %A, -1 1327 ret i1 %B 1328} 1329 1330define i1 @udiv_one_icmpeq_one(i32 %x) { 1331; CHECK-LABEL: @udiv_one_icmpeq_one( 1332; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1 1333; CHECK-NEXT: ret i1 [[TMP1]] 1334; 1335 %A = udiv i32 1, %x 1336 %B = icmp eq i32 %A, 1 1337 ret i1 %B 1338} 1339 1340define i1 @udiv_one_icmpne_one(i32 %x) { 1341; CHECK-LABEL: @udiv_one_icmpne_one( 1342; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 1 1343; CHECK-NEXT: ret i1 [[TMP1]] 1344; 1345 %A = udiv i32 1, %x 1346 %B = icmp ne i32 %A, 1 1347 ret i1 %B 1348} 1349