[llvm] 7bfd688 - Revert "[GuardWidening] Choose right point for generating wide condition for branches. PR60234"
Max Kazantsev via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 31 00:38:09 PST 2023
Author: Max Kazantsev
Date: 2023-01-31T15:37:30+07:00
New Revision: 7bfd688d8d9c6018ca9ae7196cf828ee7713c284
URL: https://github.com/llvm/llvm-project/commit/7bfd688d8d9c6018ca9ae7196cf828ee7713c284
DIFF: https://github.com/llvm/llvm-project/commit/7bfd688d8d9c6018ca9ae7196cf828ee7713c284.diff
LOG: Revert "[GuardWidening] Choose right point for generating wide condition for branches. PR60234"
This reverts commit 5cb568a37a53a9b0fd8fc9c2c35870cad43623e9.
Internal testing found failures, need to investigate.
Added:
Modified:
llvm/lib/Transforms/Scalar/GuardWidening.cpp
llvm/test/Transforms/GuardWidening/basic_widenable_condition_guards.ll
llvm/test/Transforms/GuardWidening/loop_invariant_widenable_condition.ll
llvm/test/Transforms/GuardWidening/mixed_guards.ll
llvm/test/Transforms/GuardWidening/pr60234.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
index 8755e55e41b6..abe0babc3f12 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<Instruction>(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<BranchInst>(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 e2a97bc4a313..1c0d42973cd3 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 28a92281703f..2de5ed813c30 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 92d42b346e64..db2bcb9f1d9c 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 aaf076d582e7..f428d04e0ca2 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
More information about the llvm-commits
mailing list