780 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i32)5declare void @sideeffect()6 7; negative test (but we could allow this?) - don't hoist to conditional predecessor block8 9define i32 @add_const_incoming0_speculative(i1 %b, i32 %x, i32 %y) {10; CHECK-LABEL: @add_const_incoming0_speculative(11; CHECK-NEXT: entry:12; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]13; CHECK: if:14; CHECK-NEXT: br label [[THEN]]15; CHECK: then:16; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]17; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]18; CHECK-NEXT: [[R:%.*]] = add i32 [[P0]], [[P1]]19; CHECK-NEXT: ret i32 [[R]]20;21entry:22 br i1 %b, label %if, label %then23 24if:25 br label %then26 27then:28 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]29 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]30 %r = add i32 %p0, %p131 ret i32 %r32}33 34define i32 @add_const_incoming0_nonspeculative(i1 %b, i32 %x, i32 %y) {35; CHECK-LABEL: @add_const_incoming0_nonspeculative(36; CHECK-NEXT: entry:37; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]38; CHECK: if:39; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]40; CHECK-NEXT: br label [[THEN]]41; CHECK: then:42; CHECK-NEXT: [[R:%.*]] = phi i32 [ 59, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]43; CHECK-NEXT: ret i32 [[R]]44;45entry:46 br i1 %b, label %if, label %then47 48if:49 br label %then50 51then:52 %p0 = phi i32 [ 42, %entry ], [ %x, %if ]53 %p1 = phi i32 [ 17, %entry ], [ %y, %if ]54 %r = add i32 %p0, %p155 ret i32 %r56}57 58; negative test (but we could allow this?) - don't hoist to conditional predecessor block59 60define i32 @sub_const_incoming0(i1 %b, i32 %x, i32 %y) {61; CHECK-LABEL: @sub_const_incoming0(62; CHECK-NEXT: entry:63; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]64; CHECK: if:65; CHECK-NEXT: br label [[THEN]]66; CHECK: then:67; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]68; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]69; CHECK-NEXT: [[R:%.*]] = sub i32 [[P1]], [[P0]]70; CHECK-NEXT: ret i32 [[R]]71;72entry:73 br i1 %b, label %if, label %then74 75if:76 br label %then77 78then:79 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]80 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]81 %r = sub i32 %p1, %p082 ret i32 %r83}84 85define i32 @sub_const_incoming1(i1 %b, i32 %x, i32 %y) {86; CHECK-LABEL: @sub_const_incoming1(87; CHECK-NEXT: entry:88; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]89; CHECK: if:90; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]91; CHECK-NEXT: br label [[THEN]]92; CHECK: then:93; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[TMP0]], [[IF]] ], [ 25, [[ENTRY:%.*]] ]94; CHECK-NEXT: ret i32 [[R]]95;96entry:97 br i1 %b, label %if, label %then98 99if:100 br label %then101 102then:103 %p0 = phi i32 [ %x, %if ], [ 42, %entry ]104 %p1 = phi i32 [ %y, %if ], [ 17, %entry ]105 %r = sub i32 %p0, %p1106 ret i32 %r107}108 109define i8 @mul_const_incoming1(i1 %b, i8 %x, i8 %y) {110; CHECK-LABEL: @mul_const_incoming1(111; CHECK-NEXT: entry:112; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]113; CHECK: if:114; CHECK-NEXT: [[TMP0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]115; CHECK-NEXT: br label [[THEN]]116; CHECK: then:117; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ -54, [[ENTRY:%.*]] ]118; CHECK-NEXT: ret i8 [[R]]119;120entry:121 br i1 %b, label %if, label %then122 123if:124 br label %then125 126then:127 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]128 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]129 %r = mul i8 %p0, %p1130 ret i8 %r131}132 133define i8 @and_const_incoming1(i1 %b, i8 %x, i8 %y) {134; CHECK-LABEL: @and_const_incoming1(135; CHECK-NEXT: entry:136; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]137; CHECK: if:138; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]139; CHECK-NEXT: br label [[THEN]]140; CHECK: then:141; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 0, [[ENTRY:%.*]] ]142; CHECK-NEXT: ret i8 [[R]]143;144entry:145 br i1 %b, label %if, label %then146 147if:148 br label %then149 150then:151 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]152 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]153 %r = and i8 %p0, %p1154 ret i8 %r155}156 157define i8 @xor_const_incoming1(i1 %b, i8 %x, i8 %y) {158; CHECK-LABEL: @xor_const_incoming1(159; CHECK-NEXT: entry:160; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]161; CHECK: if:162; CHECK-NEXT: [[TMP0:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]163; CHECK-NEXT: br label [[THEN]]164; CHECK: then:165; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 59, [[ENTRY:%.*]] ]166; CHECK-NEXT: ret i8 [[R]]167;168entry:169 br i1 %b, label %if, label %then170 171if:172 br label %then173 174then:175 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]176 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]177 %r = xor i8 %p0, %p1178 ret i8 %r179}180 181define i64 @or_const_incoming1(i1 %b, i64 %x, i64 %y) {182; CHECK-LABEL: @or_const_incoming1(183; CHECK-NEXT: entry:184; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]185; CHECK: if:186; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[X:%.*]], [[Y:%.*]]187; CHECK-NEXT: br label [[THEN]]188; CHECK: then:189; CHECK-NEXT: [[R:%.*]] = phi i64 [ [[TMP0]], [[IF]] ], [ 19, [[ENTRY:%.*]] ]190; CHECK-NEXT: ret i64 [[R]]191;192entry:193 br i1 %b, label %if, label %then194 195if:196 br label %then197 198then:199 %p0 = phi i64 [ %x, %if ], [ 3, %entry ]200 %p1 = phi i64 [ %y, %if ], [ 16, %entry ]201 %r = or i64 %p0, %p1202 ret i64 %r203}204 205define i64 @or_const_incoming01(i1 %b, i64 %x, i64 %y) {206; CHECK-LABEL: @or_const_incoming01(207; CHECK-NEXT: entry:208; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]209; CHECK: if:210; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[X:%.*]], [[Y:%.*]]211; CHECK-NEXT: br label [[THEN]]212; CHECK: then:213; CHECK-NEXT: [[R:%.*]] = phi i64 [ 19, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]214; CHECK-NEXT: ret i64 [[R]]215;216entry:217 br i1 %b, label %if, label %then218 219if:220 br label %then221 222then:223 %p0 = phi i64 [ 3, %entry ], [ %x, %if]224 %p1 = phi i64 [ %y, %if ], [ 16, %entry ]225 %r = or i64 %p0, %p1226 ret i64 %r227}228 229define i64 @or_const_incoming10(i1 %b, i64 %x, i64 %y) {230; CHECK-LABEL: @or_const_incoming10(231; CHECK-NEXT: entry:232; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]233; CHECK: if:234; CHECK-NEXT: [[TMP0:%.*]] = or i64 [[Y:%.*]], [[X:%.*]]235; CHECK-NEXT: br label [[THEN]]236; CHECK: then:237; CHECK-NEXT: [[R:%.*]] = phi i64 [ [[TMP0]], [[IF]] ], [ 19, [[ENTRY:%.*]] ]238; CHECK-NEXT: ret i64 [[R]]239;240entry:241 br i1 %b, label %if, label %then242 243if:244 br label %then245 246then:247 %p0 = phi i64 [ %y, %if ], [ 16, %entry ]248 %p1 = phi i64 [ 3, %entry ], [ %x, %if]249 %r = or i64 %p0, %p1250 ret i64 %r251}252 253; negative test (but we could allow this?) - don't hoist to conditional predecessor block254 255define i8 @ashr_const_incoming0_speculative(i1 %b, i8 %x, i8 %y) {256; CHECK-LABEL: @ashr_const_incoming0_speculative(257; CHECK-NEXT: entry:258; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]259; CHECK: if:260; CHECK-NEXT: br label [[THEN]]261; CHECK: then:262; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]263; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 3, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]264; CHECK-NEXT: [[R:%.*]] = ashr i8 [[P0]], [[P1]]265; CHECK-NEXT: ret i8 [[R]]266;267entry:268 br i1 %b, label %if, label %then269 270if:271 br label %then272 273then:274 %p0 = phi i8 [ 42, %if ], [ %x, %entry ]275 %p1 = phi i8 [ 3, %if ], [ %y, %entry ]276 %r = ashr i8 %p0, %p1277 ret i8 %r278}279 280define i8 @ashr_const_incoming0(i1 %b, i8 %x, i8 %y) {281; CHECK-LABEL: @ashr_const_incoming0(282; CHECK-NEXT: entry:283; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]284; CHECK: if:285; CHECK-NEXT: [[TMP0:%.*]] = ashr i8 [[X:%.*]], [[Y:%.*]]286; CHECK-NEXT: br label [[THEN]]287; CHECK: then:288; CHECK-NEXT: [[R:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]289; CHECK-NEXT: ret i8 [[R]]290;291entry:292 br i1 %b, label %if, label %then293 294if:295 br label %then296 297then:298 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]299 %p1 = phi i8 [ 3, %entry ], [ %y, %if ]300 %r = ashr i8 %p0, %p1301 ret i8 %r302}303 304define i8 @lshr_const_incoming1(i1 %b, i8 %x, i8 %y) {305; CHECK-LABEL: @lshr_const_incoming1(306; CHECK-NEXT: entry:307; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]308; CHECK: if:309; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 [[X:%.*]], [[Y:%.*]]310; CHECK-NEXT: br label [[THEN]]311; CHECK: then:312; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 5, [[ENTRY:%.*]] ]313; CHECK-NEXT: ret i8 [[R]]314;315entry:316 br i1 %b, label %if, label %then317 318if:319 br label %then320 321then:322 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]323 %p1 = phi i8 [ %y, %if ], [ 3, %entry ]324 %r = lshr i8 %p0, %p1325 ret i8 %r326}327 328define i8 @shl_const_incoming1(i1 %b, i8 %x, i8 %y) {329; CHECK-LABEL: @shl_const_incoming1(330; CHECK-NEXT: entry:331; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]332; CHECK: if:333; CHECK-NEXT: [[TMP0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]334; CHECK-NEXT: br label [[THEN]]335; CHECK: then:336; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 80, [[ENTRY:%.*]] ]337; CHECK-NEXT: ret i8 [[R]]338;339entry:340 br i1 %b, label %if, label %then341 342if:343 br label %then344 345then:346 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]347 %p1 = phi i8 [ %y, %if ], [ 3, %entry ]348 %r = shl nsw nuw i8 %p0, %p1349 ret i8 %r350}351 352define i8 @sdiv_not_safe_to_speculate(i1 %b, i8 %x, i8 %y) {353; CHECK-LABEL: @sdiv_not_safe_to_speculate(354; CHECK-NEXT: entry:355; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]356; CHECK: if:357; CHECK-NEXT: br label [[THEN]]358; CHECK: then:359; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]360; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 3, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]361; CHECK-NEXT: [[R:%.*]] = sdiv exact i8 [[P0]], [[P1]]362; CHECK-NEXT: ret i8 [[R]]363;364entry:365 br i1 %b, label %if, label %then366 367if:368 br label %then369 370then:371 %p0 = phi i8 [ 42, %if ], [ %x, %entry ]372 %p1 = phi i8 [ 3, %if ], [ %y, %entry ]373 %r = sdiv exact i8 %p0, %p1374 ret i8 %r375}376 377define i8 @sdiv_const_incoming1(i1 %b, i8 %x, i8 %y) {378; CHECK-LABEL: @sdiv_const_incoming1(379; CHECK-NEXT: entry:380; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]381; CHECK: if:382; CHECK-NEXT: [[TMP0:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]383; CHECK-NEXT: br label [[THEN]]384; CHECK: then:385; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ -2, [[ENTRY:%.*]] ]386; CHECK-NEXT: ret i8 [[R]]387;388entry:389 br i1 %b, label %if, label %then390 391if:392 br label %then393 394then:395 %p0 = phi i8 [ %x, %if ], [ -42, %entry ]396 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]397 %r = sdiv i8 %p0, %p1398 ret i8 %r399}400 401define i8 @udiv_const_incoming1(i1 %b, i8 %x, i8 %y) {402; CHECK-LABEL: @udiv_const_incoming1(403; CHECK-NEXT: entry:404; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]405; CHECK: if:406; CHECK-NEXT: [[TMP0:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]407; CHECK-NEXT: br label [[THEN]]408; CHECK: then:409; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 12, [[ENTRY:%.*]] ]410; CHECK-NEXT: ret i8 [[R]]411;412entry:413 br i1 %b, label %if, label %then414 415if:416 br label %then417 418then:419 %p0 = phi i8 [ %x, %if ], [ -42, %entry ]420 %p1 = phi i8 [ %y, %if ], [ 17, %entry ]421 %r = udiv i8 %p0, %p1422 ret i8 %r423}424 425define i8 @srem_const_incoming1(i1 %b, i8 %x, i8 %y) {426; CHECK-LABEL: @srem_const_incoming1(427; CHECK-NEXT: entry:428; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]429; CHECK: if:430; CHECK-NEXT: [[TMP0:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]]431; CHECK-NEXT: br label [[THEN]]432; CHECK: then:433; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 8, [[ENTRY:%.*]] ]434; CHECK-NEXT: ret i8 [[R]]435;436entry:437 br i1 %b, label %if, label %then438 439if:440 br label %then441 442then:443 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]444 %p1 = phi i8 [ %y, %if ], [ -17, %entry ]445 %r = srem i8 %p0, %p1446 ret i8 %r447}448 449define i8 @urem_const_incoming1(i1 %b, i8 %x, i8 %y) {450; CHECK-LABEL: @urem_const_incoming1(451; CHECK-NEXT: entry:452; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]453; CHECK: if:454; CHECK-NEXT: [[TMP0:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]]455; CHECK-NEXT: br label [[THEN]]456; CHECK: then:457; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[TMP0]], [[IF]] ], [ 42, [[ENTRY:%.*]] ]458; CHECK-NEXT: ret i8 [[R]]459;460entry:461 br i1 %b, label %if, label %then462 463if:464 br label %then465 466then:467 %p0 = phi i8 [ %x, %if ], [ 42, %entry ]468 %p1 = phi i8 [ %y, %if ], [ -17, %entry ]469 %r = urem i8 %p0, %p1470 ret i8 %r471}472 473define float @fmul_const_incoming1(i1 %b, float %x, float %y) {474; CHECK-LABEL: @fmul_const_incoming1(475; CHECK-NEXT: entry:476; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]477; CHECK: if:478; CHECK-NEXT: [[TMP0:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]479; CHECK-NEXT: br label [[THEN]]480; CHECK: then:481; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 7.140000e+02, [[ENTRY:%.*]] ]482; CHECK-NEXT: ret float [[R]]483;484entry:485 br i1 %b, label %if, label %then486 487if:488 br label %then489 490then:491 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]492 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]493 %r = fmul float %p0, %p1494 ret float %r495}496 497define float @fadd_const_incoming1(i1 %b, float %x, float %y) {498; CHECK-LABEL: @fadd_const_incoming1(499; CHECK-NEXT: entry:500; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]501; CHECK: if:502; CHECK-NEXT: [[TMP0:%.*]] = fadd fast float [[X:%.*]], [[Y:%.*]]503; CHECK-NEXT: br label [[THEN]]504; CHECK: then:505; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 5.900000e+01, [[ENTRY:%.*]] ]506; CHECK-NEXT: ret float [[R]]507;508entry:509 br i1 %b, label %if, label %then510 511if:512 br label %then513 514then:515 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]516 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]517 %r = fadd fast float %p0, %p1518 ret float %r519}520 521define float @fsub_const_incoming1(i1 %b, float %x, float %y) {522; CHECK-LABEL: @fsub_const_incoming1(523; CHECK-NEXT: entry:524; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]525; CHECK: if:526; CHECK-NEXT: [[TMP0:%.*]] = fsub nnan ninf float [[X:%.*]], [[Y:%.*]]527; CHECK-NEXT: br label [[THEN]]528; CHECK: then:529; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 2.500000e+01, [[ENTRY:%.*]] ]530; CHECK-NEXT: ret float [[R]]531;532entry:533 br i1 %b, label %if, label %then534 535if:536 br label %then537 538then:539 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]540 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]541 %r = fsub ninf nnan float %p0, %p1542 ret float %r543}544 545define float @frem_const_incoming1(i1 %b, float %x, float %y) {546; CHECK-LABEL: @frem_const_incoming1(547; CHECK-NEXT: entry:548; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]549; CHECK: if:550; CHECK-NEXT: [[TMP0:%.*]] = frem nsz float [[X:%.*]], [[Y:%.*]]551; CHECK-NEXT: br label [[THEN]]552; CHECK: then:553; CHECK-NEXT: [[R:%.*]] = phi float [ [[TMP0]], [[IF]] ], [ 8.000000e+00, [[ENTRY:%.*]] ]554; CHECK-NEXT: ret float [[R]]555;556entry:557 br i1 %b, label %if, label %then558 559if:560 br label %then561 562then:563 %p0 = phi float [ %x, %if ], [ 42.0, %entry ]564 %p1 = phi float [ %y, %if ], [ 17.0, %entry ]565 %r = frem nsz float %p0, %p1566 ret float %r567}568 569define i32 @add_const_incoming0_use1(i1 %b, i32 %x, i32 %y) {570; CHECK-LABEL: @add_const_incoming0_use1(571; CHECK-NEXT: entry:572; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]573; CHECK: if:574; CHECK-NEXT: br label [[THEN]]575; CHECK: then:576; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]577; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]578; CHECK-NEXT: call void @use(i32 [[P0]])579; CHECK-NEXT: [[R:%.*]] = add i32 [[P0]], [[P1]]580; CHECK-NEXT: ret i32 [[R]]581;582entry:583 br i1 %b, label %if, label %then584 585if:586 br label %then587 588then:589 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]590 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]591 call void @use(i32 %p0)592 %r = add i32 %p0, %p1593 ret i32 %r594}595 596define i32 @add_const_incoming0_use2(i1 %b, i32 %x, i32 %y) {597; CHECK-LABEL: @add_const_incoming0_use2(598; CHECK-NEXT: entry:599; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]600; CHECK: if:601; CHECK-NEXT: br label [[THEN]]602; CHECK: then:603; CHECK-NEXT: [[P0:%.*]] = phi i32 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]604; CHECK-NEXT: [[P1:%.*]] = phi i32 [ 17, [[IF]] ], [ [[Y:%.*]], [[ENTRY]] ]605; CHECK-NEXT: call void @use(i32 [[P1]])606; CHECK-NEXT: [[R:%.*]] = add i32 [[P0]], [[P1]]607; CHECK-NEXT: ret i32 [[R]]608;609entry:610 br i1 %b, label %if, label %then611 612if:613 br label %then614 615then:616 %p0 = phi i32 [ 42, %if ], [ %x, %entry ]617 %p1 = phi i32 [ 17, %if ], [ %y, %entry ]618 call void @use(i32 %p1)619 %r = add i32 %p0, %p1620 ret i32 %r621}622 623define i64 @or_notconst_incoming(i1 %b, i64 %x, i64 %y) {624; CHECK-LABEL: @or_notconst_incoming(625; CHECK-NEXT: entry:626; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]627; CHECK: if:628; CHECK-NEXT: br label [[THEN]]629; CHECK: then:630; CHECK-NEXT: [[P0:%.*]] = phi i64 [ 42, [[IF]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]631; CHECK-NEXT: [[P1:%.*]] = phi i64 [ [[Y:%.*]], [[IF]] ], [ 43, [[ENTRY]] ]632; CHECK-NEXT: [[R:%.*]] = or i64 [[P0]], [[P1]]633; CHECK-NEXT: ret i64 [[R]]634;635entry:636 br i1 %b, label %if, label %then637 638if:639 br label %then640 641then:642 %p0 = phi i64 [ 42, %if ], [ %x, %entry ]643 %p1 = phi i64 [ %y, %if ], [ 43, %entry ]644 %r = or i64 %p0, %p1645 ret i64 %r646}647 648; The mul could be hoisted before the call that may not return649; if we are ok with speculating a potentially expensive op.650 651define i8 @mul_const_incoming0_speculatable(i1 %b, i8 %x, i8 %y) {652; CHECK-LABEL: @mul_const_incoming0_speculatable(653; CHECK-NEXT: entry:654; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]655; CHECK: if:656; CHECK-NEXT: [[TMP0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]657; CHECK-NEXT: br label [[THEN]]658; CHECK: then:659; CHECK-NEXT: [[R:%.*]] = phi i8 [ -54, [[ENTRY:%.*]] ], [ [[TMP0]], [[IF]] ]660; CHECK-NEXT: call void @sideeffect()661; CHECK-NEXT: ret i8 [[R]]662;663entry:664 br i1 %b, label %if, label %then665 666if:667 br label %then668 669then:670 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]671 %p1 = phi i8 [ 17, %entry ], [ %y, %if ]672 call void @sideeffect()673 %r = mul i8 %p0, %p1674 ret i8 %r675}676 677; The udiv should never be hoisted before the call that may not return.678 679define i8 @udiv_const_incoming0_not_speculatable(i1 %b, i8 %x, i8 %y) {680; CHECK-LABEL: @udiv_const_incoming0_not_speculatable(681; CHECK-NEXT: entry:682; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]683; CHECK: if:684; CHECK-NEXT: br label [[THEN]]685; CHECK: then:686; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[ENTRY:%.*]] ], [ [[X:%.*]], [[IF]] ]687; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 17, [[ENTRY]] ], [ [[Y:%.*]], [[IF]] ]688; CHECK-NEXT: call void @sideeffect()689; CHECK-NEXT: [[R:%.*]] = udiv i8 [[P0]], [[P1]]690; CHECK-NEXT: ret i8 [[R]]691;692entry:693 br i1 %b, label %if, label %then694 695if:696 br label %then697 698then:699 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]700 %p1 = phi i8 [ 17, %entry ], [ %y, %if ]701 call void @sideeffect()702 %r = udiv i8 %p0, %p1703 ret i8 %r704}705 706; TODO: It is ok to hoist the udiv even though it is not in the same block as the phis.707 708define i8 @udiv_const_incoming0_different_block(i1 %b, i8 %x, i8 %y) {709; CHECK-LABEL: @udiv_const_incoming0_different_block(710; CHECK-NEXT: entry:711; CHECK-NEXT: br i1 [[B:%.*]], label [[IF:%.*]], label [[THEN:%.*]]712; CHECK: if:713; CHECK-NEXT: br label [[THEN]]714; CHECK: then:715; CHECK-NEXT: [[P0:%.*]] = phi i8 [ 42, [[ENTRY:%.*]] ], [ [[X:%.*]], [[IF]] ]716; CHECK-NEXT: [[P1:%.*]] = phi i8 [ 17, [[ENTRY]] ], [ [[Y:%.*]], [[IF]] ]717; CHECK-NEXT: br label [[END:%.*]]718; CHECK: end:719; CHECK-NEXT: [[R:%.*]] = udiv i8 [[P0]], [[P1]]720; CHECK-NEXT: ret i8 [[R]]721;722entry:723 br i1 %b, label %if, label %then724 725if:726 br label %then727 728then:729 %p0 = phi i8 [ 42, %entry ], [ %x, %if ]730 %p1 = phi i8 [ 17, %entry ], [ %y, %if ]731 br label %end732 733end:734 %r = udiv i8 %p0, %p1735 ret i8 %r736}737 738define { i64, i32 } @ParseRetVal(i1 %b, ptr %x) {739; CHECK-LABEL: @ParseRetVal(740; CHECK-NEXT: entry:741; CHECK-NEXT: br i1 [[B:%.*]], label [[T:%.*]], label [[F:%.*]]742; CHECK: t:743; CHECK-NEXT: [[T4:%.*]] = tail call { i64, i32 } [[X:%.*]]()744; CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i32 } [[T4]], 0745; CHECK-NEXT: [[T6:%.*]] = extractvalue { i64, i32 } [[T4]], 1746; CHECK-NEXT: br label [[F]]747; CHECK: f:748; CHECK-NEXT: [[T16:%.*]] = phi i32 [ [[T6]], [[T]] ], [ 0, [[ENTRY:%.*]] ]749; CHECK-NEXT: [[T19:%.*]] = phi i64 [ [[T5]], [[T]] ], [ 0, [[ENTRY]] ]750; CHECK-NEXT: [[T20:%.*]] = insertvalue { i64, i32 } poison, i64 [[T19]], 0751; CHECK-NEXT: [[T21:%.*]] = insertvalue { i64, i32 } [[T20]], i32 [[T16]], 1752; CHECK-NEXT: ret { i64, i32 } [[T21]]753;754entry:755 br i1 %b, label %t, label %f756 757t:758 %t4 = tail call { i64, i32 } %x()759 %t5 = extractvalue { i64, i32 } %t4, 0760 %t6 = extractvalue { i64, i32 } %t4, 1761 %t7 = and i64 %t5, -4294967296762 %t8 = and i64 %t5, 4294901760763 %t9 = and i64 %t5, 65280764 %t10 = and i64 %t5, 255765 br label %f766 767f:768 %t12 = phi i64 [ %t10, %t ], [ 0, %entry ]769 %t13 = phi i64 [ %t9, %t ], [ 0, %entry ]770 %t14 = phi i64 [ %t8, %t ], [ 0, %entry ]771 %t15 = phi i64 [ %t7, %t ], [ 0, %entry ]772 %t16 = phi i32 [ %t6, %t ], [ 0, %entry ]773 %t17 = or i64 %t13, %t12774 %t18 = or i64 %t17, %t14775 %t19 = or i64 %t18, %t15776 %t20 = insertvalue { i64, i32 } poison, i64 %t19, 0777 %t21 = insertvalue { i64, i32 } %t20, i32 %t16, 1778 ret { i64, i32 } %t21779}780