[llvm] 650f363 - [ValueLattice] Add singlecrfromundef lattice value.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 15 04:37:09 PDT 2020


Author: Florian Hahn
Date: 2020-03-15T11:23:46Z
New Revision: 650f363bd75a2c112e58a9c9efbe8ad52ba943c0

URL: https://github.com/llvm/llvm-project/commit/650f363bd75a2c112e58a9c9efbe8ad52ba943c0
DIFF: https://github.com/llvm/llvm-project/commit/650f363bd75a2c112e58a9c9efbe8ad52ba943c0.diff

LOG: [ValueLattice] Add singlecrfromundef lattice value.

This patch adds a new singlecrfromundef lattice value, indicating a
single element constant range which was merge with undef at some point.
Merging it with another constant range results in overdefined, as we
won't be able to replace all users with a single value.

This patch uses a ConstantRange instead of a Constant*, because regular
integer constants are represented as single element constant ranges as
well and this allows the existing code working without additional
changes.

Reviewers: efriedma, nikic, reames, davide

Reviewed By: efriedma

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

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/ValueLattice.h
    llvm/lib/Analysis/ValueLattice.cpp
    llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/ValueLattice.h b/llvm/include/llvm/Analysis/ValueLattice.h
index a467a715fca8..225d5acb19d5 100644
--- a/llvm/include/llvm/Analysis/ValueLattice.h
+++ b/llvm/include/llvm/Analysis/ValueLattice.h
@@ -29,27 +29,48 @@ class ValueLatticeElement {
     /// producing instruction is dead.  Caution: We use this as the starting
     /// state in our local meet rules.  In this usage, it's taken to mean
     /// "nothing known yet".
+    /// Transition to any other state allowed.
     unknown,
 
     /// This Value is an UndefValue constant or produces undef. Undefined values
     /// can be merged with constants (or single element constant ranges),
     /// assuming all uses of the result will be replaced.
+    /// Transition allowed to the following states:
+    ///  constant
+    ///  singlecrfromundef
+    ///  overdefined
     undef,
 
-    /// This Value has a specific constant value.  (For constant integers,
-    /// constantrange is used instead.  Integer typed constantexprs can appear
-    /// as constant.)
+    /// This Value has a specific constant value.  The constant cannot be undef.
+    /// (For constant integers, constantrange is used instead. Integer typed
+    /// constantexprs can appear as constant.)
+    /// Transition allowed to the following states:
+    ///  overdefined
     constant,
 
-    /// This Value is known to not have the specified value.  (For constant
+    /// This Value is known to not have the specified value. (For constant
     /// integers, constantrange is used instead.  As above, integer typed
     /// constantexprs can appear here.)
+    /// Transition allowed to the following states:
+    ///  overdefined
     notconstant,
 
     /// The Value falls within this range. (Used only for integer typed values.)
+    /// Transition allowed to the following states:
+    ///  constantrange (new range must be a superset of the existing range)
+    ///  singlecrfromundef (range must stay a single element range)
+    ///  overdefined
     constantrange,
 
+    /// This Value contains a single element constant range that was merged with
+    /// an Undef value. Merging it with other constant ranges results in
+    /// overdefined, unless they match the single element constant range.
+    /// Transition allowed to the following states:
+    ///  overdefined
+    singlecrfromundef,
+
     /// We can not precisely model the dynamic values this value might take.
+    /// No transitions are allowed after reaching overdefined.
     overdefined
   };
 
@@ -75,6 +96,7 @@ class ValueLatticeElement {
     case unknown:
     case undef:
     case constant:
+    case singlecrfromundef:
     case notconstant:
       break;
     case constantrange:
@@ -105,6 +127,7 @@ class ValueLatticeElement {
 
     switch (Other.Tag) {
     case constantrange:
+    case singlecrfromundef:
       if (!isConstantRange())
         new (&Range) ConstantRange(Other.Range);
       else
@@ -155,8 +178,11 @@ class ValueLatticeElement {
   bool isUnknown() const { return Tag == unknown; }
   bool isUnknownOrUndef() const { return Tag == unknown || Tag == undef; }
   bool isConstant() const { return Tag == constant; }
+  bool isSingleCRFromUndef() const { return Tag == singlecrfromundef; }
   bool isNotConstant() const { return Tag == notconstant; }
-  bool isConstantRange() const { return Tag == constantrange; }
+  bool isConstantRange() const {
+    return Tag == constantrange || Tag == singlecrfromundef;
+  }
   bool isOverdefined() const { return Tag == overdefined; }
 
   Constant *getConstant() const {
@@ -251,6 +277,8 @@ class ValueLatticeElement {
       if (getConstantRange() == NewR)
         return false;
 
+      assert(!isSingleCRFromUndef());
+
       if (NewR.isEmptySet())
         return markOverdefined();
 
@@ -260,11 +288,11 @@ class ValueLatticeElement {
       return true;
     }
 
-    assert(isUnknown() || isUndef());
+    assert(isUnknown() || (isUndef() && NewR.isSingleElement()));
     if (NewR.isEmptySet())
       return markOverdefined();
 
-    Tag = constantrange;
+    Tag = isUnknown() ? constantrange : singlecrfromundef;
     new (&Range) ConstantRange(std::move(NewR));
     return true;
   }
@@ -322,7 +350,17 @@ class ValueLatticeElement {
       markOverdefined();
       return true;
     }
+
     ConstantRange NewR = getConstantRange().unionWith(RHS.getConstantRange());
+
+    if (isSingleCRFromUndef() || RHS.isSingleCRFromUndef()) {
+      if (NewR.isSingleElement()) {
+        assert(getConstantRange() == NewR);
+        return false;
+      }
+      markOverdefined();
+      return true;
+    }
     if (NewR.isFullSet())
       return markOverdefined();
     else if (NewR == getConstantRange())

diff  --git a/llvm/lib/Analysis/ValueLattice.cpp b/llvm/lib/Analysis/ValueLattice.cpp
index eaf8885cc14e..1a15605ce1e1 100644
--- a/llvm/lib/Analysis/ValueLattice.cpp
+++ b/llvm/lib/Analysis/ValueLattice.cpp
@@ -19,6 +19,12 @@ raw_ostream &operator<<(raw_ostream &OS, const ValueLatticeElement &Val) {
 
   if (Val.isNotConstant())
     return OS << "notconstant<" << *Val.getNotConstant() << ">";
+
+  if (Val.isSingleCRFromUndef())
+    return OS << "constantrange (from undef)<"
+              << Val.getConstantRange().getLower() << ", "
+              << Val.getConstantRange().getUpper() << ">";
+
   if (Val.isConstantRange())
     return OS << "constantrange<" << Val.getConstantRange().getLower() << ", "
               << Val.getConstantRange().getUpper() << ">";

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll
index ffc92f5ab45c..271c52af779d 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll
@@ -199,7 +199,8 @@ define i64 @constant_range_and_undef_3_incoming_v2(i1 %c1, i1 %c2, i64 %a) {
 ; CHECK-NEXT:    br label [[BB4]]
 ; CHECK:       bb4:
 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ 10, [[BB2]] ], [ [[R]], [[BB3]] ]
-; CHECK-NEXT:    ret i64 [[P]]
+; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P]], 255
+; CHECK-NEXT:    ret i64 [[RES]]
 ;
 entry:
   br i1 %c1, label %bb1, label %bb2


        


More information about the llvm-commits mailing list