1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; This test makes sure that div instructions are properly eliminated. 3 4; RUN: opt < %s -instcombine -S | FileCheck %s 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: [[B:%.*]] = lshr i32 [[A:%.*]], 3 17; CHECK-NEXT: ret i32 [[B]] 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_undef_elt(<2 x i64> %x) { 42; CHECK-LABEL: @sdiv_by_minus1_vec_undef_elt( 43; CHECK-NEXT: ret <2 x i64> undef 44; 45 %div = sdiv <2 x i64> %x, <i64 -1, i64 undef> 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: [[R_V:%.*]] = select i1 [[C:%.*]], i32 6, i32 3 209; CHECK-NEXT: [[R:%.*]] = lshr i32 [[X:%.*]], [[R_V]] 210; CHECK-NEXT: ret i32 [[R]] 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: [[B_V:%.*]] = select i1 [[C:%.*]], i32 10, i32 5 220; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], [[B_V]] 221; CHECK-NEXT: ret i32 [[B]] 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: [[DIV2:%.*]] = lshr i32 [[A:%.*]], [[TMP1]] 259; CHECK-NEXT: ret i32 [[DIV2]] 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 <2 x i64> @test17(<2 x i64> %x) { 278; CHECK-LABEL: @test17( 279; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 -3, i64 -4> 280; CHECK-NEXT: ret <2 x i64> [[DIV]] 281; 282 %neg = sub nsw <2 x i64> zeroinitializer, %x 283 %div = sdiv <2 x i64> %neg, <i64 3, i64 4> 284 ret <2 x i64> %div 285} 286 287define i32 @test19(i32 %x) { 288; CHECK-LABEL: @test19( 289; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1 290; CHECK-NEXT: [[A:%.*]] = zext i1 [[TMP1]] to i32 291; CHECK-NEXT: ret i32 [[A]] 292; 293 %A = udiv i32 1, %x 294 ret i32 %A 295} 296 297define <2 x i32> @test19vec(<2 x i32> %x) { 298; CHECK-LABEL: @test19vec( 299; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 1, i32 1> 300; CHECK-NEXT: [[A:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> 301; CHECK-NEXT: ret <2 x i32> [[A]] 302; 303 %A = udiv <2 x i32> <i32 1, i32 1>, %x 304 ret <2 x i32> %A 305} 306 307define i32 @test20(i32 %x) { 308; CHECK-LABEL: @test20( 309; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1 310; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3 311; CHECK-NEXT: [[A:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 0 312; CHECK-NEXT: ret i32 [[A]] 313; 314 %A = sdiv i32 1, %x 315 ret i32 %A 316} 317 318define <2 x i32> @test20vec(<2 x i32> %x) { 319; CHECK-LABEL: @test20vec( 320; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 1, i32 1> 321; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 3, i32 3> 322; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[X]], <2 x i32> zeroinitializer 323; CHECK-NEXT: ret <2 x i32> [[A]] 324; 325 %A = sdiv <2 x i32> <i32 1, i32 1>, %x 326 ret <2 x i32> %A 327} 328 329define i32 @test21(i32 %a) { 330; CHECK-LABEL: @test21( 331; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], 3 332; CHECK-NEXT: ret i32 [[DIV]] 333; 334 %shl = shl nsw i32 %a, 2 335 %div = sdiv i32 %shl, 12 336 ret i32 %div 337} 338 339define i32 @test22(i32 %a) { 340; CHECK-LABEL: @test22( 341; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], 4 342; CHECK-NEXT: ret i32 [[DIV]] 343; 344 %mul = mul nsw i32 %a, 3 345 %div = sdiv i32 %mul, 12 346 ret i32 %div 347} 348 349define i32 @test23(i32 %a) { 350; CHECK-LABEL: @test23( 351; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[A:%.*]], 3 352; CHECK-NEXT: ret i32 [[DIV]] 353; 354 %shl = shl nuw i32 %a, 2 355 %div = udiv i32 %shl, 12 356 ret i32 %div 357} 358 359define i32 @test24(i32 %a) { 360; CHECK-LABEL: @test24( 361; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[A:%.*]], 2 362; CHECK-NEXT: ret i32 [[DIV]] 363; 364 %mul = mul nuw i32 %a, 3 365 %div = udiv i32 %mul, 12 366 ret i32 %div 367} 368 369define i32 @test25(i32 %a) { 370; CHECK-LABEL: @test25( 371; CHECK-NEXT: [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 1 372; CHECK-NEXT: ret i32 [[DIV]] 373; 374 %shl = shl nsw i32 %a, 2 375 %div = sdiv i32 %shl, 2 376 ret i32 %div 377} 378 379define i32 @test26(i32 %a) { 380; CHECK-LABEL: @test26( 381; CHECK-NEXT: [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 2 382; CHECK-NEXT: ret i32 [[DIV]] 383; 384 %mul = mul nsw i32 %a, 12 385 %div = sdiv i32 %mul, 3 386 ret i32 %div 387} 388 389define i32 @test27(i32 %a) { 390; CHECK-LABEL: @test27( 391; CHECK-NEXT: [[DIV:%.*]] = shl nuw i32 [[A:%.*]], 1 392; CHECK-NEXT: ret i32 [[DIV]] 393; 394 %shl = shl nuw i32 %a, 2 395 %div = udiv i32 %shl, 2 396 ret i32 %div 397} 398 399define i32 @test28(i32 %a) { 400; CHECK-LABEL: @test28( 401; CHECK-NEXT: [[DIV:%.*]] = mul nuw i32 [[A:%.*]], 12 402; CHECK-NEXT: ret i32 [[DIV]] 403; 404 %mul = mul nuw i32 %a, 36 405 %div = udiv i32 %mul, 3 406 ret i32 %div 407} 408 409define i32 @test29(i32 %a) { 410; CHECK-LABEL: @test29( 411; CHECK-NEXT: [[MUL_LOBIT:%.*]] = and i32 [[A:%.*]], 1 412; CHECK-NEXT: ret i32 [[MUL_LOBIT]] 413; 414 %mul = shl nsw i32 %a, 31 415 %div = sdiv i32 %mul, -2147483648 416 ret i32 %div 417} 418 419define i32 @test30(i32 %a) { 420; CHECK-LABEL: @test30( 421; CHECK-NEXT: ret i32 [[A:%.*]] 422; 423 %mul = shl nuw i32 %a, 31 424 %div = udiv i32 %mul, -2147483648 425 ret i32 %div 426} 427 428define <2 x i32> @test31(<2 x i32> %x) { 429; CHECK-LABEL: @test31( 430; CHECK-NEXT: ret <2 x i32> zeroinitializer 431; 432 %shr = lshr <2 x i32> %x, <i32 31, i32 31> 433 %div = udiv <2 x i32> %shr, <i32 2147483647, i32 2147483647> 434 ret <2 x i32> %div 435} 436 437define i32 @test32(i32 %a, i32 %b) { 438; CHECK-LABEL: @test32( 439; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, [[B:%.*]] 440; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL]], 2 441; CHECK-NEXT: [[DIV2:%.*]] = udiv i32 [[A:%.*]], [[DIV]] 442; CHECK-NEXT: ret i32 [[DIV2]] 443; 444 %shl = shl i32 2, %b 445 %div = lshr i32 %shl, 2 446 %div2 = udiv i32 %a, %div 447 ret i32 %div2 448} 449 450define <2 x i64> @test33(<2 x i64> %x) { 451; CHECK-LABEL: @test33( 452; CHECK-NEXT: [[DIV:%.*]] = udiv exact <2 x i64> [[X:%.*]], <i64 192, i64 192> 453; CHECK-NEXT: ret <2 x i64> [[DIV]] 454; 455 %shr = lshr exact <2 x i64> %x, <i64 5, i64 5> 456 %div = udiv exact <2 x i64> %shr, <i64 6, i64 6> 457 ret <2 x i64> %div 458} 459 460define <2 x i64> @test34(<2 x i64> %x) { 461; CHECK-LABEL: @test34( 462; CHECK-NEXT: [[DIV:%.*]] = sdiv exact <2 x i64> [[X:%.*]], <i64 -3, i64 -4> 463; CHECK-NEXT: ret <2 x i64> [[DIV]] 464; 465 %neg = sub nsw <2 x i64> zeroinitializer, %x 466 %div = sdiv exact <2 x i64> %neg, <i64 3, i64 4> 467 ret <2 x i64> %div 468} 469 470define i32 @test35(i32 %A) { 471; CHECK-LABEL: @test35( 472; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 2147483647 473; CHECK-NEXT: [[MUL:%.*]] = udiv exact i32 [[AND]], 2147483647 474; CHECK-NEXT: ret i32 [[MUL]] 475; 476 %and = and i32 %A, 2147483647 477 %mul = sdiv exact i32 %and, 2147483647 478 ret i32 %mul 479} 480 481define <2 x i32> @test35vec(<2 x i32> %A) { 482; CHECK-LABEL: @test35vec( 483; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A:%.*]], <i32 2147483647, i32 2147483647> 484; CHECK-NEXT: [[MUL:%.*]] = udiv exact <2 x i32> [[AND]], <i32 2147483647, i32 2147483647> 485; CHECK-NEXT: ret <2 x i32> [[MUL]] 486; 487 %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647> 488 %mul = sdiv exact <2 x i32> %and, <i32 2147483647, i32 2147483647> 489 ret <2 x i32> %mul 490} 491 492define i32 @test36(i32 %A) { 493; CHECK-LABEL: @test36( 494; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 2147483647 495; CHECK-NEXT: [[MUL:%.*]] = lshr exact i32 [[AND]], [[A]] 496; CHECK-NEXT: ret i32 [[MUL]] 497; 498 %and = and i32 %A, 2147483647 499 %shl = shl nsw i32 1, %A 500 %mul = sdiv exact i32 %and, %shl 501 ret i32 %mul 502} 503 504define <2 x i32> @test36vec(<2 x i32> %A) { 505; CHECK-LABEL: @test36vec( 506; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A:%.*]], <i32 2147483647, i32 2147483647> 507; CHECK-NEXT: [[MUL:%.*]] = lshr exact <2 x i32> [[AND]], [[A]] 508; CHECK-NEXT: ret <2 x i32> [[MUL]] 509; 510 %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647> 511 %shl = shl nsw <2 x i32> <i32 1, i32 1>, %A 512 %mul = sdiv exact <2 x i32> %and, %shl 513 ret <2 x i32> %mul 514} 515 516define i32 @test37(i32* %b) { 517; CHECK-LABEL: @test37( 518; CHECK-NEXT: entry: 519; CHECK-NEXT: store i32 0, i32* [[B:%.*]], align 4 520; CHECK-NEXT: br i1 undef, label [[LOR_RHS:%.*]], label [[LOR_END:%.*]] 521; CHECK: lor.rhs: 522; CHECK-NEXT: br label [[LOR_END]] 523; CHECK: lor.end: 524; CHECK-NEXT: ret i32 0 525; 526entry: 527 store i32 0, i32* %b, align 4 528 %0 = load i32, i32* %b, align 4 529 br i1 undef, label %lor.rhs, label %lor.end 530 531lor.rhs: ; preds = %entry 532 %mul = mul nsw i32 undef, %0 533 br label %lor.end 534 535lor.end: ; preds = %lor.rhs, %entry 536 %t.0 = phi i32 [ %0, %entry ], [ %mul, %lor.rhs ] 537 %div = sdiv i32 %t.0, 2 538 ret i32 %div 539} 540 541; We can perform the division in the smaller type. 542 543define i32 @shrink(i8 %x) { 544; CHECK-LABEL: @shrink( 545; CHECK-NEXT: [[TMP1:%.*]] = sdiv i8 [[X:%.*]], 127 546; CHECK-NEXT: [[DIV:%.*]] = sext i8 [[TMP1]] to i32 547; CHECK-NEXT: ret i32 [[DIV]] 548; 549 %conv = sext i8 %x to i32 550 %div = sdiv i32 %conv, 127 551 ret i32 %div 552} 553 554; Division in the smaller type can lead to more optimizations. 555 556define i32 @zap(i8 %x) { 557; CHECK-LABEL: @zap( 558; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128 559; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[TMP1]] to i32 560; CHECK-NEXT: ret i32 [[DIV]] 561; 562 %conv = sext i8 %x to i32 563 %div = sdiv i32 %conv, -128 564 ret i32 %div 565} 566 567; Splat constant divisors should get the same folds. 568 569define <3 x i32> @shrink_vec(<3 x i8> %x) { 570; CHECK-LABEL: @shrink_vec( 571; CHECK-NEXT: [[TMP1:%.*]] = sdiv <3 x i8> [[X:%.*]], <i8 127, i8 127, i8 127> 572; CHECK-NEXT: [[DIV:%.*]] = sext <3 x i8> [[TMP1]] to <3 x i32> 573; CHECK-NEXT: ret <3 x i32> [[DIV]] 574; 575 %conv = sext <3 x i8> %x to <3 x i32> 576 %div = sdiv <3 x i32> %conv, <i32 127, i32 127, i32 127> 577 ret <3 x i32> %div 578} 579 580define <2 x i32> @zap_vec(<2 x i8> %x) { 581; CHECK-LABEL: @zap_vec( 582; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 -128, i8 -128> 583; CHECK-NEXT: [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> 584; CHECK-NEXT: ret <2 x i32> [[DIV]] 585; 586 %conv = sext <2 x i8> %x to <2 x i32> 587 %div = sdiv <2 x i32> %conv, <i32 -128, i32 -128> 588 ret <2 x i32> %div 589} 590 591; But we can't do this if the signed constant won't fit in the original type. 592 593define i32 @shrink_no(i8 %x) { 594; CHECK-LABEL: @shrink_no( 595; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 596; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 128 597; CHECK-NEXT: ret i32 [[DIV]] 598; 599 %conv = sext i8 %x to i32 600 %div = sdiv i32 %conv, 128 601 ret i32 %div 602} 603 604; When the divisor is known larger than the quotient, 605; InstSimplify should kill it before InstCombine sees it. 606 607define i32 @shrink_no2(i8 %x) { 608; CHECK-LABEL: @shrink_no2( 609; CHECK-NEXT: ret i32 0 610; 611 %conv = sext i8 %x to i32 612 %div = sdiv i32 %conv, -129 613 ret i32 %div 614} 615 616define i32 @shrink_no3(i16 %x) { 617; CHECK-LABEL: @shrink_no3( 618; CHECK-NEXT: ret i32 0 619; 620 %conv = sext i16 %x to i32 621 %div = sdiv i32 %conv, 65535 622 ret i32 %div 623} 624 625; This previously crashed when trying to simplify the zext/icmp this becomes. 626define <2 x i8> @PR34841(<2 x i8> %x) { 627; CHECK-LABEL: @PR34841( 628; CHECK-NEXT: ret <2 x i8> zeroinitializer 629; 630 %neg = and <2 x i8> %x, <i8 2, i8 2> 631 %div = udiv <2 x i8> <i8 1, i8 1>, %neg 632 ret <2 x i8> %div 633} 634 635; X / (X * Y) -> 1 / Y if the multiplication does not overflow 636 637define i8 @div_factor_signed(i8 %x, i8 %y) { 638; CHECK-LABEL: @div_factor_signed( 639; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 1 640; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 3 641; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i8 [[Y]], i8 0 642; CHECK-NEXT: ret i8 [[R]] 643; 644 %a = mul nsw i8 %x, %y 645 %r = sdiv i8 %x, %a 646 ret i8 %r 647} 648 649; X / (Y * X) -> 1 / Y if the multiplication does not overflow 650 651define <2 x i8> @div_factor_signed_vec(<2 x i8> %x, <2 x i8> %y) { 652; CHECK-LABEL: @div_factor_signed_vec( 653; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[Y:%.*]], <i8 1, i8 1> 654; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i8> [[TMP1]], <i8 3, i8 3> 655; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i8> [[Y]], <2 x i8> zeroinitializer 656; CHECK-NEXT: ret <2 x i8> [[R]] 657; 658 %a = mul nsw <2 x i8> %y, %x 659 %r = sdiv <2 x i8> %x, %a 660 ret <2 x i8> %r 661} 662 663; X / (Y * X) -> 1 / Y if the multiplication does not overflow 664 665define i8 @div_factor_unsigned(i8 %x, i8 %y) { 666; CHECK-LABEL: @div_factor_unsigned( 667; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 1 668; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i8 669; CHECK-NEXT: ret i8 [[R]] 670; 671 %a = mul nuw i8 %y, %x 672 %r = udiv i8 %x, %a 673 ret i8 %r 674} 675 676; X / (X * Y) -> 1 / Y if the multiplication does not overflow 677 678define <2 x i8> @div_factor_unsigned_vec(<2 x i8> %x, <2 x i8> %y) { 679; CHECK-LABEL: @div_factor_unsigned_vec( 680; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[Y:%.*]], <i8 1, i8 1> 681; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8> 682; CHECK-NEXT: ret <2 x i8> [[R]] 683; 684 %a = mul nuw <2 x i8> %x, %y 685 %r = udiv <2 x i8> %x, %a 686 ret <2 x i8> %r 687} 688 689define i8 @udiv_common_factor(i8 %x, i8 %y, i8 %z) { 690; CHECK-LABEL: @udiv_common_factor( 691; CHECK-NEXT: [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 692; CHECK-NEXT: ret i8 [[C]] 693; 694 %a = mul nuw i8 %z, %x 695 %b = mul nuw i8 %z, %y 696 %c = udiv i8 %a, %b 697 ret i8 %c 698} 699 700define <2 x i8> @udiv_common_factor_commute1_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 701; CHECK-LABEL: @udiv_common_factor_commute1_vec( 702; CHECK-NEXT: [[C:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]] 703; CHECK-NEXT: ret <2 x i8> [[C]] 704; 705 %a = mul nuw <2 x i8> %x, %z 706 %b = mul nuw <2 x i8> %z, %y 707 %c = udiv <2 x i8> %a, %b 708 ret <2 x i8> %c 709} 710 711define i8 @udiv_common_factor_commute2(i8 %x, i8 %y, i8 %z) { 712; CHECK-LABEL: @udiv_common_factor_commute2( 713; CHECK-NEXT: [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 714; CHECK-NEXT: ret i8 [[C]] 715; 716 %a = mul nuw i8 %x, %z 717 %b = mul nuw i8 %y, %z 718 %c = udiv i8 %a, %b 719 ret i8 %c 720} 721 722define i8 @udiv_common_factor_commute3(i8 %x, i8 %y, i8 %z) { 723; CHECK-LABEL: @udiv_common_factor_commute3( 724; CHECK-NEXT: [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 725; CHECK-NEXT: ret i8 [[C]] 726; 727 %a = mul nuw i8 %z, %x 728 %b = mul nuw i8 %y, %z 729 %c = udiv i8 %a, %b 730 ret i8 %c 731} 732 733; Negative test: both mul must be 'nuw'. 734 735define i8 @udiv_common_factor_not_nuw(i8 %x, i8 %y, i8 %z) { 736; CHECK-LABEL: @udiv_common_factor_not_nuw( 737; CHECK-NEXT: [[A:%.*]] = mul i8 [[Z:%.*]], [[X:%.*]] 738; CHECK-NEXT: [[B:%.*]] = mul nuw i8 [[Z]], [[Y:%.*]] 739; CHECK-NEXT: [[C:%.*]] = udiv i8 [[A]], [[B]] 740; CHECK-NEXT: ret i8 [[C]] 741; 742 %a = mul i8 %z, %x 743 %b = mul nuw i8 %z, %y 744 %c = udiv i8 %a, %b 745 ret i8 %c 746} 747 748; Negative test: both mul must be 'nuw'. 749 750define <2 x i8> @udiv_common_factor_not_nuw_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 751; CHECK-LABEL: @udiv_common_factor_not_nuw_vec( 752; CHECK-NEXT: [[A:%.*]] = mul nuw <2 x i8> [[Z:%.*]], [[X:%.*]] 753; CHECK-NEXT: [[B:%.*]] = mul <2 x i8> [[Z]], [[Y:%.*]] 754; CHECK-NEXT: [[C:%.*]] = udiv <2 x i8> [[A]], [[B]] 755; CHECK-NEXT: ret <2 x i8> [[C]] 756; 757 %a = mul nuw <2 x i8> %z, %x 758 %b = mul <2 x i8> %z, %y 759 %c = udiv <2 x i8> %a, %b 760 ret <2 x i8> %c 761} 762 763