Skip to content

Commit

Permalink
[ConstraintElim] Bail out on non-dedicated exits when adding exiting …
Browse files Browse the repository at this point in the history
…conditions (llvm#116627)

This patch bails out non-dedicated exits to avoid adding exiting
conditions to invalid context.
Closes llvm#116553.
  • Loading branch information
dtcxzyw authored Nov 18, 2024
1 parent c25e09e commit 52361d0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
13 changes: 8 additions & 5 deletions llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,18 +1034,21 @@ void State::addInfoForInductions(BasicBlock &BB) {
DTN, CmpInst::ICMP_SLT, PN, B,
ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -763,3 +763,47 @@ exit.2:
%t.2 = icmp ult i32 %iv, %N
ret i1 %t.2
}

define i1 @test_non_dedicated_exit(i16 %n) {
; CHECK-LABEL: define i1 @test_non_dedicated_exit(
; CHECK-SAME: i16 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[COND:%.*]] = icmp slt i16 [[N]], 1
; CHECK-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LOOP_PREHEADER:.*]]
; CHECK: [[LOOP_PREHEADER]]:
; CHECK-NEXT: [[SUB:%.*]] = add nsw i16 [[N]], -1
; CHECK-NEXT: [[EXT:%.*]] = zext nneg i16 [[SUB]] to i32
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ [[INDVAR_INC:%.*]], %[[LOOP_LATCH:.*]] ], [ 0, %[[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INDVAR]], [[EXT]]
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT]], label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
; CHECK-NEXT: [[INDVAR_INC]] = add nuw nsw i32 [[INDVAR]], 1
; CHECK-NEXT: br label %[[LOOP]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[N]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
entry:
%cond = icmp slt i16 %n, 1
br i1 %cond, label %exit, label %loop.preheader

loop.preheader:
%sub = add nsw i16 %n, -1
%ext = zext nneg i16 %sub to i32
br label %loop

loop:
%indvar = phi i32 [ %indvar.inc, %loop.latch ], [ 0, %loop.preheader ]
%exitcond = icmp eq i32 %indvar, %ext
br i1 %exitcond, label %exit, label %loop.latch

loop.latch:
%indvar.inc = add nuw nsw i32 %indvar, 1
br label %loop

exit:
%cmp = icmp sgt i16 %n, 0
ret i1 %cmp
}

0 comments on commit 52361d0

Please sign in to comment.