summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2017-11-22 03:04:55 +0000
committerDavide Italiano <davide@freebsd.org>2017-11-22 03:04:55 +0000
commitb480b5c2eebb9f8ea2923b071a1443f0145fa3a8 (patch)
treed4387d92ce283b64aae0494f2e112629dd8000c8
parent5668d83e0e7b1221eb440e0e5aef049306b050a1 (diff)
downloadbcm5719-llvm-b480b5c2eebb9f8ea2923b071a1443f0145fa3a8.tar.gz
bcm5719-llvm-b480b5c2eebb9f8ea2923b071a1443f0145fa3a8.zip
[SCCP] Pick the right lattice value for constants.
After the dataflow algorithm proves that an argument is constant, it replaces it value with the integer constant and drops the lattice value associated to the DEF. e.g. in the example we have @f() that's called twice: call @f(undef, ...) call @f(2, ...) `undef` MEET 2 = 2 so we replace the argument and all its uses with the constant 2. Shortly after, tryToReplaceWithConstantRange() tries to get the lattice value for the argument we just replaced, causing an assertion. This function is a little peculiar as it runs when we're doing replacement and not as part of the solver but still queries the solver. The fix is that of checking whether we replaced the value already and get a temporary lattice value for the constant. Thanks to Zhendong Su for the report! Fixes PR35357. llvm-svn: 318817
-rw-r--r--llvm/lib/Transforms/Scalar/SCCP.cpp11
-rw-r--r--llvm/test/Transforms/SCCP/pr35357.ll24
2 files changed, 33 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index 192ba13c598..e5866b4718d 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -1615,8 +1615,15 @@ static bool tryToReplaceWithConstantRange(SCCPSolver &Solver, Value *V) {
if (!Icmp || !Solver.isBlockExecutable(Icmp->getParent()))
continue;
- auto A = Solver.getLatticeValueFor(Icmp->getOperand(0));
- auto B = Solver.getLatticeValueFor(Icmp->getOperand(1));
+ auto getIcmpLatticeValue = [&](Value *Op) {
+ if (auto *C = dyn_cast<Constant>(Op))
+ return ValueLatticeElement::get(C);
+ return Solver.getLatticeValueFor(Op);
+ };
+
+ ValueLatticeElement A = getIcmpLatticeValue(Icmp->getOperand(0));
+ ValueLatticeElement B = getIcmpLatticeValue(Icmp->getOperand(1));
+
Constant *C = nullptr;
if (A.satisfiesPredicate(Icmp->getPredicate(), B))
C = ConstantInt::getTrue(Icmp->getType());
diff --git a/llvm/test/Transforms/SCCP/pr35357.ll b/llvm/test/Transforms/SCCP/pr35357.ll
new file mode 100644
index 00000000000..fda123b76f7
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/pr35357.ll
@@ -0,0 +1,24 @@
+; RUN: opt -S %s -ipsccp | FileCheck %s
+
+@a = internal global i32 2
+
+define i32 @patatino() {
+; CHECK: @patatino(
+; CHECK: call void @f(i32 undef, i32 1)
+; CHECK-NEXT: call void @f(i32 2, i32 0)
+; CHECK-NEXT: ret i32 0
+entry:
+ call void @f(i32 undef, i32 1)
+ %0 = load i32, i32* @a
+ call void @f(i32 %0, i32 0)
+ ret i32 0
+}
+
+define internal void @f(i32 %c, i32 %d) {
+; CHECK: @f(
+; CHECK: ret void
+;
+entry:
+ %cmp = icmp ne i32 %c, %d
+ ret void
+}
OpenPOWER on IntegriCloud