summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp14
-rw-r--r--llvm/test/CodeGen/PowerPC/merge_stores_dereferenceable.ll24
2 files changed, 36 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index d1a5a98607c..ceba71d52a4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12829,6 +12829,7 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
// This variable refers to the size and not index in the array.
unsigned LastLegalVectorType = 1;
unsigned LastLegalIntegerType = 1;
+ bool isDereferenceable = true;
bool DoIntegerTruncate = false;
StartAddress = LoadNodes[0].OffsetFromBase;
SDValue FirstChain = FirstLoad->getChain();
@@ -12841,6 +12842,10 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
if (CurrAddress - StartAddress != (ElementSizeBytes * i))
break;
LastConsecutiveLoad = i;
+
+ if (isDereferenceable && !LoadNodes[i].MemNode->isDereferenceable())
+ isDereferenceable = false;
+
// Find a legal type for the vector store.
EVT StoreTy = EVT::getVectorVT(Context, MemVT, i + 1);
bool IsFastSt, IsFastLd;
@@ -12926,11 +12931,16 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
SDValue NewStoreChain = getMergeStoreChains(StoreNodes, NumElem);
AddToWorklist(NewStoreChain.getNode());
+ MachineMemOperand::Flags MMOFlags = isDereferenceable ?
+ MachineMemOperand::MODereferenceable:
+ MachineMemOperand::MONone;
+
SDValue NewLoad, NewStore;
if (UseVectorTy || !DoIntegerTruncate) {
NewLoad = DAG.getLoad(JointMemOpVT, LoadDL, FirstLoad->getChain(),
FirstLoad->getBasePtr(),
- FirstLoad->getPointerInfo(), FirstLoadAlign);
+ FirstLoad->getPointerInfo(), FirstLoadAlign,
+ MMOFlags);
NewStore = DAG.getStore(NewStoreChain, StoreDL, NewLoad,
FirstInChain->getBasePtr(),
FirstInChain->getPointerInfo(), FirstStoreAlign);
@@ -12940,7 +12950,7 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
NewLoad =
DAG.getExtLoad(ISD::EXTLOAD, LoadDL, ExtendedTy, FirstLoad->getChain(),
FirstLoad->getBasePtr(), FirstLoad->getPointerInfo(),
- JointMemOpVT, FirstLoadAlign);
+ JointMemOpVT, FirstLoadAlign, MMOFlags);
NewStore = DAG.getTruncStore(NewStoreChain, StoreDL, NewLoad,
FirstInChain->getBasePtr(),
FirstInChain->getPointerInfo(), JointMemOpVT,
diff --git a/llvm/test/CodeGen/PowerPC/merge_stores_dereferenceable.ll b/llvm/test/CodeGen/PowerPC/merge_stores_dereferenceable.ll
new file mode 100644
index 00000000000..29aee7a3825
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/merge_stores_dereferenceable.ll
@@ -0,0 +1,24 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr8 -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
+
+; This code causes an assertion failure if dereferenceable flag is not properly set when in merging consecutive stores
+; CHECK-LABEL: func:
+; CHECK: lxvd2x [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+; CHECK-NOT: lxvd2x
+; CHECK: stxvd2x [[REG1:[0-9]+]], {{[0-9]+}}, {{[0-9]+}}
+
+define <2 x i64> @func(i64* %pdst) {
+entry:
+ %a = alloca [4 x i64], align 8
+ %psrc0 = bitcast [4 x i64]* %a to i64*
+ %psrc1 = getelementptr inbounds i64, i64* %psrc0, i64 1
+ %d0 = load i64, i64* %psrc0
+ %d1 = load i64, i64* %psrc1
+ %pdst0 = getelementptr inbounds i64, i64* %pdst, i64 0
+ %pdst1 = getelementptr inbounds i64, i64* %pdst, i64 1
+ store i64 %d0, i64* %pdst0, align 8
+ store i64 %d1, i64* %pdst1, align 8
+ %psrcd = bitcast [4 x i64]* %a to <2 x i64>*
+ %vec = load <2 x i64>, <2 x i64>* %psrcd
+ ret <2 x i64> %vec
+}
+
OpenPOWER on IntegriCloud