[llvm] 4ed7355 - [IPSCCP] Use ParamState for arguments at call sites.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 23 13:56:05 PST 2020


Author: Florian Hahn
Date: 2020-01-23T13:55:42-08:00
New Revision: 4ed7355e4485486563ee31da2fb6e0c88d4ed076

URL: https://github.com/llvm/llvm-project/commit/4ed7355e4485486563ee31da2fb6e0c88d4ed076
DIFF: https://github.com/llvm/llvm-project/commit/4ed7355e4485486563ee31da2fb6e0c88d4ed076.diff

LOG: [IPSCCP] Use ParamState for arguments at call sites.

We currently use integer ranges to merge concrete function arguments.
We use the ParamState range for those, but we only look up concrete
values in the regular state. For concrete function arguments that are
themselves arguments of the containing function, we can use the param
state directly and improve the precision in some cases.

Besides improving the results in some cases, this is also a small step towards
switching to ValueLatticeElement, by allowing D60582 to be a NFC.

Reviewers: efriedma, davide

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D71836

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/SCCP.cpp
    llvm/test/Transforms/SCCP/ip-constant-ranges.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index e696ea83a300..34f18ec7c121 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -507,6 +507,24 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
     return LV;
   }
 
+  LatticeVal toLatticeVal(const ValueLatticeElement &V, Type *T) {
+    LatticeVal Res;
+    if (V.isUndefined())
+      return Res;
+
+    if (V.isConstant()) {
+      Res.markConstant(V.getConstant());
+      return Res;
+    }
+    if (V.isConstantRange() && V.getConstantRange().isSingleElement()) {
+      Res.markConstant(
+          ConstantInt::get(T, *V.getConstantRange().getSingleElement()));
+      return Res;
+    }
+    Res.markOverdefined();
+    return Res;
+  }
+
   ValueLatticeElement &getParamState(Value *V) {
     assert(!V->getType()->isStructTy() && "Should use getStructValueState");
 
@@ -1329,10 +1347,12 @@ void SCCPSolver::visitCallSite(CallSite CS) {
       } else {
         // Most other parts of the Solver still only use the simpler value
         // lattice, so we propagate changes for parameters to both lattices.
-        LatticeVal ConcreteArgument = getValueState(*CAI);
-        bool ParamChanged =
-            getParamState(&*AI).mergeIn(ConcreteArgument.toValueLattice(), DL);
-         bool ValueChanged = mergeInValue(&*AI, ConcreteArgument);
+        ValueLatticeElement ConcreteArgument =
+            isa<Argument>(*CAI) ? getParamState(*CAI)
+                                : getValueState(*CAI).toValueLattice();
+        bool ParamChanged = getParamState(&*AI).mergeIn(ConcreteArgument, DL);
+        bool ValueChanged =
+            mergeInValue(&*AI, toLatticeVal(ConcreteArgument, AI->getType()));
         // Add argument to work list, if the state of a parameter changes but
         // ValueState does not change (because it is already overdefined there),
         // We have to take changes in ParamState into account, as it is used

diff  --git a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll
index 704ea97179bb..426e3279661f 100644
--- a/llvm/test/Transforms/SCCP/ip-constant-ranges.ll
+++ b/llvm/test/Transforms/SCCP/ip-constant-ranges.ll
@@ -196,3 +196,41 @@ entry:
   %call = call i32 @recursive_f(i32 42)
   ret i32 %call
 }
+
+define internal i32 @callee6.1(i32 %i) {
+; CHECK-LABEL: define internal i32 @callee6.1(
+; CHECK-NEXT:    %res = call i32 @callee6.2(i32 %i)
+; CHECK-NEXT:    ret i32 undef
+;
+  %res = call i32 @callee6.2(i32 %i)
+  ret i32 %res
+}
+
+define internal i32 @callee6.2(i32 %i) {
+; CHECK-LABEL: define internal i32 @callee6.2(i32 %i) {
+; CHECK-NEXT:    br label %if.then
+
+; CHECK-LABEL: if.then:
+; CHECK-NEXT:    ret i32 undef
+;
+  %cmp = icmp ne i32 %i, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  ret i32 1
+
+if.else:                                          ; preds = %entry
+  ret i32 2
+}
+
+define i32 @caller6() {
+; CHECK-LABEL: define i32 @caller6() {
+; CHECK-NEXT:    %call.1 = call i32 @callee6.1(i32 30)
+; CHECK-NEXT:    %call.2 = call i32 @callee6.1(i32 43)
+; CHECK-NEXT:    ret i32 2
+
+  %call.1 = call i32 @callee6.1(i32 30)
+  %call.2 = call i32 @callee6.1(i32 43)
+  %res = add i32 %call.1, %call.2
+  ret i32 %res
+}


        


More information about the llvm-commits mailing list