From 7bfd688d8d9c6018ca9ae7196cf828ee7713c284 Mon Sep 17 00:00:00 2001 From: Max Kazantsev Date: Tue, 31 Jan 2023 15:37:02 +0700 Subject: [PATCH] Revert "[GuardWidening] Choose right point for generating wide condition for branches. PR60234" This reverts commit 5cb568a37a53a9b0fd8fc9c2c35870cad43623e9. Internal testing found failures, need to investigate. --- llvm/lib/Transforms/Scalar/GuardWidening.cpp | 24 +++------------------- .../basic_widenable_condition_guards.ll | 24 +++++++++++----------- .../loop_invariant_widenable_condition.ll | 20 ++++++++++-------- llvm/test/Transforms/GuardWidening/mixed_guards.ll | 2 +- llvm/test/Transforms/GuardWidening/pr60234.ll | 18 ++++++++-------- 5 files changed, 37 insertions(+), 51 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp index 8755e55..abe0bab 100644 --- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp +++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp @@ -113,23 +113,6 @@ static void eliminateGuard(Instruction *GuardInst, MemorySSAUpdater *MSSAU) { ++GuardsEliminated; } -/// Find a point at which the widened condition of \p Guard should be inserted. -/// When it is represented as intrinsic call, we can do it right before the call -/// instruction. However, when we are dealing with widenable branch, we must -/// account for the following situation: widening should not turn a -/// loop-invariant condition into a loop-variant. It means that if -/// widenable.condition() call is invariant (w.r.t. any loop), the new wide -/// condition should stay invariant. Otherwise there can be a miscompile, like -/// the one described at https://github.com/llvm/llvm-project/issues/60234. The -/// safest way to do it is to expand the new condition at WC's block. -static Instruction *findInsertionPointForWideCondition(Instruction *Guard) { - Value *Condition, *WC; - BasicBlock *IfTrue, *IfFalse; - if (parseWidenableBranch(Guard, Condition, WC, IfTrue, IfFalse)) - return cast(WC); - return Guard; -} - class GuardWideningImpl { DominatorTree &DT; PostDominatorTree *PDT; @@ -280,8 +263,8 @@ class GuardWideningImpl { void widenGuard(Instruction *ToWiden, Value *NewCondition, bool InvertCondition) { Value *Result; - Instruction *InsertPt = findInsertionPointForWideCondition(ToWiden); - widenCondCommon(getCondition(ToWiden), NewCondition, InsertPt, Result, + + widenCondCommon(getCondition(ToWiden), NewCondition, ToWiden, Result, InvertCondition); if (isGuardAsWidenableBranch(ToWiden)) { setWidenableBranchCond(cast(ToWiden), Result); @@ -439,8 +422,7 @@ GuardWideningImpl::computeWideningScore(Instruction *DominatedInstr, HoistingOutOfLoop = true; } - auto *WideningPoint = findInsertionPointForWideCondition(DominatingGuard); - if (!isAvailableAt(getCondition(DominatedInstr), WideningPoint)) + if (!isAvailableAt(getCondition(DominatedInstr), DominatingGuard)) return WS_IllegalOrNegative; // If the guard was conditional executed, it may never be reached diff --git a/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll b/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll index e2a97bc..1c0d429 100644 --- a/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll +++ b/llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll @@ -7,8 +7,8 @@ define void @f_0(i1 %cond_0, i1 %cond_1) { ; CHECK-LABEL: @f_0( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]] ; CHECK: deopt: @@ -50,8 +50,8 @@ guarded1: ; preds = %guarded define void @f_1(i1 %cond_0, i1 %cond_1) { ; CHECK-LABEL: @f_1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -110,9 +110,9 @@ define void @f_2(i32 %a, i32 %b) { ; CHECK-LABEL: @f_2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10 +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]] -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -231,9 +231,9 @@ define void @f_4(i32 %a, i32 %b) { ; CHECK-LABEL: @f_4( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10 +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]] -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -289,8 +289,8 @@ define void @f_5(i32 %a) { ; CHECK-LABEL: @f_5( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[COND_0:%.*]] = icmp ugt i32 [[A:%.*]], 7 -; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[A]], 11 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -397,9 +397,9 @@ define void @f_7(i32 %a, ptr %cond_buf) { ; CHECK-LABEL: @f_7( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[COND_1:%.*]] = load volatile i1, ptr [[COND_BUF:%.*]], align 1 +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i32 [[A:%.*]], 7 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_3]] -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -484,9 +484,9 @@ define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2) { ; CHECK: guarded: ; CHECK-NEXT: br i1 undef, label [[LOOP]], label [[LEAVE:%.*]] ; CHECK: leave: +; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i32 [[A:%.*]], 7 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_2:%.*]], [[COND_3]] -; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND3]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]] ; CHECK: deopt2: @@ -663,8 +663,8 @@ define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] ; CHECK: outer_header: -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -725,6 +725,7 @@ exit: ; preds = %outer_latch define void @f_12(i32 %a0) { ; CHECK-LABEL: @f_12( ; CHECK-NEXT: entry: +; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A0:%.*]], [[A0]] ; CHECK-NEXT: [[A2:%.*]] = mul i32 [[A1]], [[A1]] ; CHECK-NEXT: [[A3:%.*]] = mul i32 [[A2]], [[A2]] @@ -757,7 +758,6 @@ define void @f_12(i32 %a0) { ; CHECK-NEXT: [[A30:%.*]] = mul i32 [[A29]], [[A29]] ; CHECK-NEXT: [[COND:%.*]] = trunc i32 [[A30]] to i1 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]] -; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -830,8 +830,8 @@ define void @f_13(i32 %a) { ; CHECK-LABEL: @f_13( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 14 -; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp ult i32 [[A]], 10 ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -1025,8 +1025,8 @@ guarded1: ; preds = %guarded define void @swapped_wb(i1 %cond_0, i1 %cond_1) { ; CHECK-LABEL: @swapped_wb( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[WIDE_CHK]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: @@ -1067,8 +1067,8 @@ guarded1: ; preds = %guarded define void @trivial_wb(i1 %cond_0) { ; CHECK-LABEL: @trivial_wb( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND_0:%.*]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND_0:%.*]] ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[TMP0]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: diff --git a/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll b/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll index 28a9228..2de5ed8 100644 --- a/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll +++ b/llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll @@ -3,17 +3,17 @@ declare i32 @llvm.experimental.deoptimize.i32(...) -; Make sure the two loop-invariant conditions can be widened together, -; and the widening point is outside the loop. +; FIXME: Make sure the two loop-invariant conditions can be widened together, +; and the widening point is outside the loop. define i32 @test_01(i32 %start, i32 %x) { ; CHECK-LABEL: @test_01( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[START:%.*]], [[X:%.*]] -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]] ; CHECK-NEXT: [[WC1:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]] ; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WC1]] ; CHECK-NEXT: br i1 [[TMP0]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]] ; CHECK: exit_by_wc: @@ -65,7 +65,7 @@ failure: } -; Make sure the loop-variant condition is not widened into loop-invariant. +; FIXME: Make sure the loop-variant condition is not widened into loop-invariant. define i32 @test_02(i32 %start, i32 %x) { ; CHECK-LABEL: @test_02( ; CHECK-NEXT: entry: @@ -73,15 +73,17 @@ define i32 @test_02(i32 %start, i32 %x) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: br i1 [[WC1]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]] +; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], [[X:%.*]] +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]] +; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WC1]] +; CHECK-NEXT: br i1 [[TMP0]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]] ; CHECK: exit_by_wc: ; CHECK-NEXT: [[RVAL1:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[IV]]) ] ; CHECK-NEXT: ret i32 [[RVAL1]] ; CHECK: guard_block: -; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], [[X:%.*]] ; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[GUARD:%.*]] = and i1 [[COND]], [[WC2]] -; CHECK-NEXT: br i1 [[GUARD]], label [[BACKEDGE]], label [[FAILURE:%.*]] +; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAILURE:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @side_effect() ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 @@ -123,16 +125,16 @@ failure: ret i32 %rval2 } -; Same as test_01, but the initial condition is not immediately WC. +; FIXME: Same as test_01, but the initial condition is not immediately WC. define i32 @test_03(i32 %start, i32 %x, i1 %c) { ; CHECK-LABEL: @test_03( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[START:%.*]], [[X:%.*]] -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C:%.*]], [[COND]] ; CHECK-NEXT: [[WC1:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C:%.*]], [[COND]] ; CHECK-NEXT: [[INVARIANT:%.*]] = and i1 [[WIDE_CHK]], [[WC1]] ; CHECK-NEXT: br i1 [[INVARIANT]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]] ; CHECK: exit_by_wc: diff --git a/llvm/test/Transforms/GuardWidening/mixed_guards.ll b/llvm/test/Transforms/GuardWidening/mixed_guards.ll index 92d42b34..db2bcb9 100644 --- a/llvm/test/Transforms/GuardWidening/mixed_guards.ll +++ b/llvm/test/Transforms/GuardWidening/mixed_guards.ll @@ -44,8 +44,8 @@ guarded1: ; preds = %guarded define void @test_02(i1 %cond_0, i1 %cond_1) { ; CHECK-LABEL: @test_02( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK]], [[WIDENABLE_COND]] ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] ; CHECK: deopt: diff --git a/llvm/test/Transforms/GuardWidening/pr60234.ll b/llvm/test/Transforms/GuardWidening/pr60234.ll index aaf076d..f428d04 100644 --- a/llvm/test/Transforms/GuardWidening/pr60234.ll +++ b/llvm/test/Transforms/GuardWidening/pr60234.ll @@ -3,10 +3,10 @@ declare i32 @llvm.experimental.deoptimize.i32(...) -; Make sure that guard widening does not turn loop-invariant condition -; (that then gets optimized basing on this fact) into non-invariant. -; https://github.com/llvm/llvm-project/issues/60234 explains how it causes -; a miscompile. +; FIXME: Make sure that guard widening does not turn loop-invariant condition +; (that then gets optimized basing on this fact) into non-invariant. +; https://github.com/llvm/llvm-project/issues/60234 explains how it causes +; a miscompile. define i32 @test(i32 %start) { ; CHECK-LABEL: @test( ; CHECK-NEXT: entry: @@ -14,17 +14,19 @@ define i32 @test(i32 %start) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: br i1 [[WC1]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]] +; CHECK-NEXT: [[START_PLUS_1:%.*]] = add i32 [[START]], 1 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[START_PLUS_1]], [[IV]] +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 true, [[COND]] +; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[WIDE_CHK]], [[WC1]] +; CHECK-NEXT: br i1 [[TMP0]], label [[GUARD_BLOCK:%.*]], label [[EXIT_BY_WC:%.*]] ; CHECK: exit_by_wc: ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[START]], [[LOOP]] ] ; CHECK-NEXT: [[RVAL1:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[IV_LCSSA]]) ] ; CHECK-NEXT: ret i32 [[RVAL1]] ; CHECK: guard_block: -; CHECK-NEXT: [[START_PLUS_1:%.*]] = add i32 [[START]], 1 -; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[START_PLUS_1]], [[IV]] ; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() ; CHECK-NEXT: [[GUARD:%.*]] = and i1 [[COND]], [[WC2]] -; CHECK-NEXT: br i1 [[GUARD]], label [[BACKEDGE]], label [[FAILURE:%.*]] +; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAILURE:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @side_effect() ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -- 2.7.4