[PATCH] D104689: [LoopDeletion] Benefit from branches by undef conditions when symbolically executing 1st iteration
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 21 23:07:38 PDT 2021
mkazantsev updated this revision to Diff 353556.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D104689/new/
https://reviews.llvm.org/D104689
Files:
llvm/lib/Transforms/Scalar/LoopDeletion.cpp
llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
Index: llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
+++ llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
@@ -881,20 +881,19 @@
unreachable
}
-; TODO: We can break the backedge here by exploiting undef.
define i32 @test_multiple_pred_undef_3() {
; CHECK-LABEL: @test_multiple_pred_undef_3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[SUB:%.*]] = sub i32 4, [[SUM]]
; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sgt i32 [[SUB]], 0
; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
; CHECK-NEXT: br i1 undef, label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
; CHECK: if.true.1:
-; CHECK-NEXT: br label [[BACKEDGE]]
+; CHECK-NEXT: br label [[BACKEDGE:%.*]]
; CHECK: if.true.2:
; CHECK-NEXT: br label [[BACKEDGE]]
; CHECK: if.false:
@@ -905,9 +904,11 @@
; CHECK-NEXT: br label [[BACKEDGE]]
; CHECK: backedge:
; CHECK-NEXT: [[MERGE_PHI:%.*]] = phi i32 [ 0, [[IF_FALSE_1]] ], [ 0, [[IF_FALSE_2]] ], [ undef, [[IF_TRUE_1]] ], [ undef, [[IF_TRUE_2]] ]
-; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[MERGE_PHI]]
+; CHECK-NEXT: [[SUM_NEXT:%.*]] = add i32 [[SUM]], [[MERGE_PHI]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[SUM_NEXT]], 4
-; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
+; CHECK-NEXT: br i1 [[LOOP_COND]], label [[BACKEDGE_LOOP_CRIT_EDGE:%.*]], label [[DONE:%.*]]
+; CHECK: backedge.loop_crit_edge:
+; CHECK-NEXT: unreachable
; CHECK: done:
; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ]
; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]
Index: llvm/lib/Transforms/Scalar/LoopDeletion.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -333,13 +333,35 @@
// Can we prove constant true or false for this condition?
LHS = getValueOnFirstIteration(LHS, FirstIterValue, SQ);
RHS = getValueOnFirstIteration(RHS, FirstIterValue, SQ);
- auto *KnownCondition =
- dyn_cast_or_null<ConstantInt>(SimplifyICmpInst(Pred, LHS, RHS, SQ));
+ auto *KnownCondition = SimplifyICmpInst(Pred, LHS, RHS, SQ);
if (!KnownCondition) {
+ // Failed to simplify.
MarkAllSuccessorsLive(BB);
continue;
}
- if (KnownCondition->isAllOnesValue())
+ if (isa<UndefValue>(KnownCondition)) {
+ // TODO: According to langref, branching by undef is undefined behavior.
+ // It means that, theoretically, we should be able to just continue
+ // without marking any successors as live. However, we are not certain
+ // how correct our compiler is at handling such cases. So we are being
+ // very conservative here.
+ //
+ // If there is a non-loop successor, always assume this branch leaves the
+ // loop. Otherwise, arbitrarily take IfTrue.
+ //
+ // Once we are certain that branching by undef is handled correctly by
+ // other transforms, we should not mark any successors live here.
+ if (L->contains(IfTrue) && L->contains(IfFalse))
+ MarkLiveEdge(BB, IfTrue);
+ continue;
+ }
+ auto *ConstCondition = dyn_cast<ConstantInt>(KnownCondition);
+ if (!ConstCondition) {
+ // Non-constant condition, cannot analyze any further.
+ MarkAllSuccessorsLive(BB);
+ continue;
+ }
+ if (ConstCondition->isAllOnesValue())
MarkLiveEdge(BB, IfTrue);
else
MarkLiveEdge(BB, IfFalse);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104689.353556.patch
Type: text/x-patch
Size: 3925 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210622/9944c9bc/attachment.bin>
More information about the llvm-commits
mailing list