Skip to content

Commit 52361d0

Browse files
authored
[ConstraintElim] Bail out on non-dedicated exits when adding exiting conditions (llvm#116627)
This patch bails out non-dedicated exits to avoid adding exiting conditions to invalid context. Closes llvm#116553.
1 parent c25e09e commit 52361d0

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -1034,18 +1034,21 @@ void State::addInfoForInductions(BasicBlock &BB) {
10341034
DTN, CmpInst::ICMP_SLT, PN, B,
10351035
ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
10361036

1037-
// Try to add condition from header to the exit blocks. When exiting either
1038-
// with EQ or NE in the header, we know that the induction value must be u<=
1039-
// B, as other exits may only exit earlier.
1037+
// Try to add condition from header to the dedicated exit blocks. When exiting
1038+
// either with EQ or NE in the header, we know that the induction value must
1039+
// be u<= B, as other exits may only exit earlier.
10401040
assert(!StepOffset.isNegative() && "induction must be increasing");
10411041
assert((Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) &&
10421042
"unsupported predicate");
10431043
ConditionTy Precond = {CmpInst::ICMP_ULE, StartValue, B};
10441044
SmallVector<BasicBlock *> ExitBBs;
10451045
L->getExitBlocks(ExitBBs);
10461046
for (BasicBlock *EB : ExitBBs) {
1047-
WorkList.emplace_back(FactOrCheck::getConditionFact(
1048-
DT.getNode(EB), CmpInst::ICMP_ULE, A, B, Precond));
1047+
// Bail out on non-dedicated exits.
1048+
if (DT.dominates(&BB, EB)) {
1049+
WorkList.emplace_back(FactOrCheck::getConditionFact(
1050+
DT.getNode(EB), CmpInst::ICMP_ULE, A, B, Precond));
1051+
}
10491052
}
10501053
}
10511054

llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll

+44
Original file line numberDiff line numberDiff line change
@@ -763,3 +763,47 @@ exit.2:
763763
%t.2 = icmp ult i32 %iv, %N
764764
ret i1 %t.2
765765
}
766+
767+
define i1 @test_non_dedicated_exit(i16 %n) {
768+
; CHECK-LABEL: define i1 @test_non_dedicated_exit(
769+
; CHECK-SAME: i16 [[N:%.*]]) {
770+
; CHECK-NEXT: [[ENTRY:.*:]]
771+
; CHECK-NEXT: [[COND:%.*]] = icmp slt i16 [[N]], 1
772+
; CHECK-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LOOP_PREHEADER:.*]]
773+
; CHECK: [[LOOP_PREHEADER]]:
774+
; CHECK-NEXT: [[SUB:%.*]] = add nsw i16 [[N]], -1
775+
; CHECK-NEXT: [[EXT:%.*]] = zext nneg i16 [[SUB]] to i32
776+
; CHECK-NEXT: br label %[[LOOP:.*]]
777+
; CHECK: [[LOOP]]:
778+
; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ [[INDVAR_INC:%.*]], %[[LOOP_LATCH:.*]] ], [ 0, %[[LOOP_PREHEADER]] ]
779+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INDVAR]], [[EXT]]
780+
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT]], label %[[LOOP_LATCH]]
781+
; CHECK: [[LOOP_LATCH]]:
782+
; CHECK-NEXT: [[INDVAR_INC]] = add nuw nsw i32 [[INDVAR]], 1
783+
; CHECK-NEXT: br label %[[LOOP]]
784+
; CHECK: [[EXIT]]:
785+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[N]], 0
786+
; CHECK-NEXT: ret i1 [[CMP]]
787+
;
788+
entry:
789+
%cond = icmp slt i16 %n, 1
790+
br i1 %cond, label %exit, label %loop.preheader
791+
792+
loop.preheader:
793+
%sub = add nsw i16 %n, -1
794+
%ext = zext nneg i16 %sub to i32
795+
br label %loop
796+
797+
loop:
798+
%indvar = phi i32 [ %indvar.inc, %loop.latch ], [ 0, %loop.preheader ]
799+
%exitcond = icmp eq i32 %indvar, %ext
800+
br i1 %exitcond, label %exit, label %loop.latch
801+
802+
loop.latch:
803+
%indvar.inc = add nuw nsw i32 %indvar, 1
804+
br label %loop
805+
806+
exit:
807+
%cmp = icmp sgt i16 %n, 0
808+
ret i1 %cmp
809+
}

0 commit comments

Comments
 (0)