Skip to content

Commit 7c73c2e

Browse files
committed
[LoopDeletion] Benefit from branches by undef conditions when symbolically executing 1st iteration
We can exploit branches by `undef` condition. Frankly, the LangRef says that such branches are UB, so we can assume that all outgoing edges of such blocks are dead. However, from practical perspective, we know that this is not supported correctly in some other places. So we are being conservative about it. Branch by undef is treated in the following way: - If it is a loop-exiting branch, we always assume it exits the loop; - If not, we arbitrarily assume it takes `true` value. Differential Revision: https://reviews.llvm.org/D104689 Reviewed By: nikic
1 parent eb237ff commit 7c73c2e

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

llvm/lib/Transforms/Scalar/LoopDeletion.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,35 @@ static bool canProveExitOnFirstIteration(Loop *L, DominatorTree &DT,
333333
// Can we prove constant true or false for this condition?
334334
LHS = getValueOnFirstIteration(LHS, FirstIterValue, SQ);
335335
RHS = getValueOnFirstIteration(RHS, FirstIterValue, SQ);
336-
auto *KnownCondition =
337-
dyn_cast_or_null<ConstantInt>(SimplifyICmpInst(Pred, LHS, RHS, SQ));
336+
auto *KnownCondition = SimplifyICmpInst(Pred, LHS, RHS, SQ);
338337
if (!KnownCondition) {
338+
// Failed to simplify.
339339
MarkAllSuccessorsLive(BB);
340340
continue;
341341
}
342-
if (KnownCondition->isAllOnesValue())
342+
if (isa<UndefValue>(KnownCondition)) {
343+
// TODO: According to langref, branching by undef is undefined behavior.
344+
// It means that, theoretically, we should be able to just continue
345+
// without marking any successors as live. However, we are not certain
346+
// how correct our compiler is at handling such cases. So we are being
347+
// very conservative here.
348+
//
349+
// If there is a non-loop successor, always assume this branch leaves the
350+
// loop. Otherwise, arbitrarily take IfTrue.
351+
//
352+
// Once we are certain that branching by undef is handled correctly by
353+
// other transforms, we should not mark any successors live here.
354+
if (L->contains(IfTrue) && L->contains(IfFalse))
355+
MarkLiveEdge(BB, IfTrue);
356+
continue;
357+
}
358+
auto *ConstCondition = dyn_cast<ConstantInt>(KnownCondition);
359+
if (!ConstCondition) {
360+
// Non-constant condition, cannot analyze any further.
361+
MarkAllSuccessorsLive(BB);
362+
continue;
363+
}
364+
if (ConstCondition->isAllOnesValue())
343365
MarkLiveEdge(BB, IfTrue);
344366
else
345367
MarkLiveEdge(BB, IfFalse);

llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -881,20 +881,19 @@ failure:
881881
unreachable
882882
}
883883

884-
; TODO: We can break the backedge here by exploiting undef.
885884
define i32 @test_multiple_pred_undef_3(i1 %cond, i1 %cond2) {
886885
; CHECK-LABEL: @test_multiple_pred_undef_3(
887886
; CHECK-NEXT: entry:
888887
; CHECK-NEXT: br label [[LOOP:%.*]]
889888
; CHECK: loop:
890-
; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ]
889+
; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
891890
; CHECK-NEXT: [[SUB:%.*]] = sub i32 4, [[SUM]]
892891
; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sgt i32 [[SUB]], 0
893892
; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
894893
; CHECK: if.true:
895894
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
896895
; CHECK: if.true.1:
897-
; CHECK-NEXT: br label [[BACKEDGE]]
896+
; CHECK-NEXT: br label [[BACKEDGE:%.*]]
898897
; CHECK: if.true.2:
899898
; CHECK-NEXT: br label [[BACKEDGE]]
900899
; CHECK: if.false:
@@ -905,9 +904,11 @@ define i32 @test_multiple_pred_undef_3(i1 %cond, i1 %cond2) {
905904
; CHECK-NEXT: br label [[BACKEDGE]]
906905
; CHECK: backedge:
907906
; CHECK-NEXT: [[MERGE_PHI:%.*]] = phi i32 [ 0, [[IF_FALSE_1]] ], [ 0, [[IF_FALSE_2]] ], [ undef, [[IF_TRUE_1]] ], [ undef, [[IF_TRUE_2]] ]
908-
; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[MERGE_PHI]]
907+
; CHECK-NEXT: [[SUM_NEXT:%.*]] = add i32 [[SUM]], [[MERGE_PHI]]
909908
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[SUM_NEXT]], 4
910-
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
909+
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[BACKEDGE_LOOP_CRIT_EDGE:%.*]], label [[DONE:%.*]]
910+
; CHECK: backedge.loop_crit_edge:
911+
; CHECK-NEXT: unreachable
911912
; CHECK: done:
912913
; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ]
913914
; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]

0 commit comments

Comments
 (0)