[llvm] be37cac - [JumpThreading] Process range comparisions with non-local cmp instructions
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 2 03:22:59 PDT 2022
Author: Sergey Kachkov
Date: 2022-09-02T12:22:45+02:00
New Revision: be37caca0055df77c9e3ca0a63d4b2ccefe94f7d
URL: https://github.com/llvm/llvm-project/commit/be37caca0055df77c9e3ca0a63d4b2ccefe94f7d
DIFF: https://github.com/llvm/llvm-project/commit/be37caca0055df77c9e3ca0a63d4b2ccefe94f7d.diff
LOG: [JumpThreading] Process range comparisions with non-local cmp instructions
Use getPredicateOnEdge method if value is a non-local
compare-with-a-constant instruction, that can give more precise
results than getConstantOnEdge.
Differential Revision: https://reviews.llvm.org/D131956
Added:
Modified:
llvm/lib/Transforms/Scalar/JumpThreading.cpp
llvm/test/Transforms/JumpThreading/range-compare.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index cbf1eb25af6e2..c1d4251b31af9 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -654,22 +654,25 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
Instruction *I = dyn_cast<Instruction>(V);
if (!I || I->getParent() != BB) {
- // Okay, if this is a live-in value, see if it has a known value at the end
- // of any of our predecessors.
- //
- // FIXME: This should be an edge property, not a block end property.
- /// TODO: Per PR2563, we could infer value range information about a
- /// predecessor based on its terminator.
- //
- // FIXME: change this to use the more-rich 'getPredicateOnEdge' method if
- // "I" is a non-local compare-with-a-constant instruction. This would be
- // able to handle value inequalities better, for example if the compare is
- // "X < 4" and "X < 3" is known true but "X < 4" itself is not available.
- // Perhaps getConstantOnEdge should be smart enough to do this?
+ // Okay, if this is a live-in value, see if it has a known value at the any
+ // edge from our predecessors.
for (BasicBlock *P : predecessors(BB)) {
+ using namespace PatternMatch;
// If the value is known by LazyValueInfo to be a constant in a
// predecessor, use that information to try to thread this block.
Constant *PredCst = LVI->getConstantOnEdge(V, P, BB, CxtI);
+ // If I is a non-local compare-with-constant instruction, use more-rich
+ // 'getPredicateOnEdge' method. This would be able to handle value
+ // inequalities better, for example if the compare is "X < 4" and "X < 3"
+ // is known true but "X < 4" itself is not available.
+ CmpInst::Predicate Pred;
+ Value *Val;
+ Constant *Cst;
+ if (!PredCst && match(V, m_Cmp(Pred, m_Value(Val), m_Constant(Cst)))) {
+ auto Res = LVI->getPredicateOnEdge(Pred, Val, Cst, P, BB, CxtI);
+ if (Res != LazyValueInfo::Unknown)
+ PredCst = ConstantInt::getBool(V->getContext(), Res);
+ }
if (Constant *KC = getKnownConstant(PredCst, Preference))
Result.emplace_back(KC, P);
}
diff --git a/llvm/test/Transforms/JumpThreading/range-compare.ll b/llvm/test/Transforms/JumpThreading/range-compare.ll
index 54e94d06649bb..b2136d8476671 100644
--- a/llvm/test/Transforms/JumpThreading/range-compare.ll
+++ b/llvm/test/Transforms/JumpThreading/range-compare.ll
@@ -123,3 +123,42 @@ if.end4: ; preds = %if.then3, %if.end
ret void
}
+; Make sure we thread the false side of the first if to the end of the function
+; (case with non-local comparisions).
+define void @test4(i32 %x) {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 9
+; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], -3
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X_OFF]], 5
+; CHECK-NEXT: br i1 [[CMP1]], label [[IF_END:%.*]], label [[IF_END4:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: call void (...) @bar()
+; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END4]]
+; CHECK: if.then3:
+; CHECK-NEXT: call void (...) @baz()
+; CHECK-NEXT: br label [[IF_END4]]
+; CHECK: if.end4:
+; CHECK-NEXT: ret void
+;
+entry:
+ %cmp1 = icmp slt i32 %x, 9
+ %x.off = add i32 %x, -3
+ %cmp2 = icmp ult i32 %x.off, 5
+ br i1 %cmp1, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ call void (...) @bar()
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ br i1 %cmp2, label %if.then3, label %if.end4
+
+if.then3: ; preds = %if.end
+ call void (...) @baz()
+ br label %if.end4
+
+if.end4: ; preds = %if.then3, %if.end
+ ret void
+}
+
More information about the llvm-commits
mailing list