[llvm] r354884 - [DAG] Fix constant store folding to handle non-byte sizes.

Nirav Dave via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 26 07:02:33 PST 2019


Author: niravd
Date: Tue Feb 26 07:02:32 2019
New Revision: 354884

URL: http://llvm.org/viewvc/llvm-project?rev=354884&view=rev
Log:
[DAG] Fix constant store folding to handle non-byte sizes.

Avoid crashes from zero-byte values due to sub-byte store sizes.

Reviewers: uabelho, courbet, rnk

Reviewed By: courbet

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
    llvm/trunk/test/CodeGen/X86/constant-combines.ll

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h?rev=354884&r1=354883&r2=354884&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h Tue Feb 26 07:02:32 2019
@@ -62,14 +62,15 @@ public:
 
   // Returns true if `Other` (with size `OtherSize`) can be proven to be fully
   // contained in `*this` (with size `Size`).
-  bool contains(int64_t Size, const BaseIndexOffset &Other, int64_t OtherSize,
-                const SelectionDAG &DAG) const {
-    int64_t Offset;
-    return contains(Size, Other, OtherSize, DAG, Offset);
-  }
+  bool contains(const SelectionDAG &DAG, int64_t BitSize,
+                const BaseIndexOffset &Other, int64_t OtherBitSize,
+                int64_t &BitOffset) const;
 
-  bool contains(int64_t Size, const BaseIndexOffset &Other, int64_t OtherSize,
-                const SelectionDAG &DAG, int64_t &Offset) const;
+  bool contains(const SelectionDAG &DAG, int64_t BitSize,
+                const BaseIndexOffset &Other, int64_t OtherBitSize) const {
+    int64_t BitOffset;
+    return contains(DAG, BitSize, Other, OtherBitSize, BitOffset);
+  }
 
   // Returns true `BasePtr0` and `BasePtr1` can be proven to alias/not alias, in
   // which case `IsAlias` is set to true/false.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=354884&r1=354883&r2=354884&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 26 07:02:32 2019
@@ -15427,13 +15427,13 @@ SDValue DAGCombiner::visitSTORE(SDNode *
           !ST1->getBasePtr().isUndef()) {
         const BaseIndexOffset STBase = BaseIndexOffset::match(ST, DAG);
         const BaseIndexOffset ChainBase = BaseIndexOffset::match(ST1, DAG);
-        unsigned STByteSize = ST->getMemoryVT().getSizeInBits() / 8;
-        unsigned ChainByteSize = ST1->getMemoryVT().getSizeInBits() / 8;
+        unsigned STBitSize = ST->getMemoryVT().getSizeInBits();
+        unsigned ChainBitSize = ST1->getMemoryVT().getSizeInBits();
         // If this is a store who's preceding store to a subset of the current
         // location and no one other node is chained to that store we can
         // effectively drop the store. Do not remove stores to undef as they may
         // be used as data sinks.
-        if (STBase.contains(STByteSize, ChainBase, ChainByteSize, DAG)) {
+        if (STBase.contains(DAG, STBitSize, ChainBase, ChainBitSize)) {
           CombineTo(ST1, ST1->getChain());
           return SDValue();
         }
@@ -15442,17 +15442,17 @@ SDValue DAGCombiner::visitSTORE(SDNode *
         // able to fold ST's value into the preceding stored value. As we know
         // the other uses of ST1's chain are unconcerned with ST, this folding
         // will not affect those nodes.
-        int64_t Offset;
-        if (ChainBase.contains(ChainByteSize, STBase, STByteSize, DAG,
-                               Offset)) {
+        int64_t BitOffset;
+        if (ChainBase.contains(DAG, ChainBitSize, STBase, STBitSize,
+                               BitOffset)) {
           SDValue ChainValue = ST1->getValue();
           if (auto *C1 = dyn_cast<ConstantSDNode>(ChainValue)) {
             if (auto *C = dyn_cast<ConstantSDNode>(Value)) {
               APInt Val = C1->getAPIntValue();
-              APInt InsertVal = C->getAPIntValue().zextOrTrunc(STByteSize * 8);
+              APInt InsertVal = C->getAPIntValue().zextOrTrunc(STBitSize);
               // FIXME: Handle Big-endian mode.
               if (!DAG.getDataLayout().isBigEndian()) {
-                Val.insertBits(InsertVal, Offset * 8);
+                Val.insertBits(InsertVal, BitOffset);
                 SDValue NewSDVal =
                     DAG.getConstant(Val, SDLoc(C), ChainValue.getValueType(),
                                     C1->isTargetOpcode(), C1->isOpaque());

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp?rev=354884&r1=354883&r2=354884&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp Tue Feb 26 07:02:32 2019
@@ -135,9 +135,10 @@ bool BaseIndexOffset::computeAliasing(co
   return false; // Cannot determine whether the pointers alias.
 }
 
-bool BaseIndexOffset::contains(int64_t Size, const BaseIndexOffset &Other,
-                               int64_t OtherSize, const SelectionDAG &DAG,
-                               int64_t &Offset) const {
+bool BaseIndexOffset::contains(const SelectionDAG &DAG, int64_t BitSize,
+                               const BaseIndexOffset &Other,
+                               int64_t OtherBitSize, int64_t &BitOffset) const {
+  int64_t Offset;
   if (!equalBaseIndex(Other, DAG, Offset))
     return false;
   if (Offset >= 0) {
@@ -145,7 +146,8 @@ bool BaseIndexOffset::contains(int64_t S
     // [-------*this---------]
     //            [---Other--]
     // ==Offset==>
-    return Offset + OtherSize <= Size;
+    BitOffset = 8 * Offset;
+    return BitOffset + OtherBitSize <= BitSize;
   }
   // Other starts strictly before *this, it cannot be fully contained.
   //    [-------*this---------]

Modified: llvm/trunk/test/CodeGen/X86/constant-combines.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/constant-combines.ll?rev=354884&r1=354883&r2=354884&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/constant-combines.ll (original)
+++ llvm/trunk/test/CodeGen/X86/constant-combines.ll Tue Feb 26 07:02:32 2019
@@ -38,3 +38,15 @@ entry:
   store float %8, float* %0, align 4
   ret void
 }
+
+
+define void @bitstore_fold() {
+; CHECK-LABEL: bitstore_fold:
+; CHECK:       # %bb.0: # %BB
+; CHECK-NEXT:    movl $-2, 0
+; CHECK-NEXT:    retq
+BB:
+   store i32 -1, i32* null
+   store i1 false, i1* null
+   ret void
+}




More information about the llvm-commits mailing list