From 4e3f5191928641fdf7298ee21fdf09ab0f17a53e Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 18 Nov 2024 23:41:04 +0800 Subject: [PATCH] [ConstraintElim] Bail out on non-dedicated exits when adding exiting conditions (#116627) This patch bails out non-dedicated exits to avoid adding exiting conditions to invalid context. Closes https://github.com/llvm/llvm-project/issues/116553. (cherry picked from commit 52361d0368b79841be12156bf03cf8c1851e5df7) --- .../Scalar/ConstraintElimination.cpp | 13 +++--- .../induction-condition-in-loop-exit.ll | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 37022104d0a9bd..d1c80aa6712433 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1033,9 +1033,9 @@ 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"); @@ -1043,8 +1043,11 @@ void State::addInfoForInductions(BasicBlock &BB) { SmallVector 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)); + } } } diff --git a/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll b/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll index 15e1d843726278..a04b06e1bf0a52 100644 --- a/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll +++ b/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll @@ -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 +}