summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadav Rotem <nrotem@apple.com>2012-10-03 19:30:31 +0000
committerNadav Rotem <nrotem@apple.com>2012-10-03 19:30:31 +0000
commitac92066b0c0ccf0e9852b8aa8555501a6ecef538 (patch)
tree8bdb640dcef43eb015537184cd5756ed5f90c98c
parent85a62b1a1d5c73946455051e075b00486f402a20 (diff)
downloadbcm5719-llvm-ac92066b0c0ccf0e9852b8aa8555501a6ecef538.tar.gz
bcm5719-llvm-ac92066b0c0ccf0e9852b8aa8555501a6ecef538.zip
Fix a cycle in the DAG. In this code we replace multiple loads with a single load and
multiple stores with a single load. We create the wide loads and stores (and their chains) before we remove the scalar loads and stores and fix the DAG chain. We attempted to merge loads with a different chain. When that happened, the assumption that it is safe to RAUW broke and a cycle was introduced. llvm-svn: 165148
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp26
-rw-r--r--llvm/test/CodeGen/X86/2012-10-03-DAGCycle.ll31
2 files changed, 50 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f03a2a9e61f..ba14a4dbb5d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7722,7 +7722,12 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) {
unsigned LastLegalVectorType = 0;
unsigned LastLegalIntegerType = 0;
StartAddress = LoadNodes[0].OffsetFromBase;
- for (unsigned i=1; i<LoadNodes.size(); ++i) {
+ SDValue FirstChain = LoadNodes[0].MemNode->getChain();
+ for (unsigned i = 1; i < LoadNodes.size(); ++i) {
+ // All loads much share the same chain.
+ if (LoadNodes[i].MemNode->getChain() != FirstChain)
+ break;
+
int64_t CurrAddress = LoadNodes[i].OffsetFromBase;
if (CurrAddress - StartAddress != (ElementSizeBytes * i))
break;
@@ -7791,16 +7796,23 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) {
FirstInChain->getPointerInfo(), false, false,
FirstInChain->getAlignment());
- // Replace the first store with the new store
- CombineTo(EarliestOp, NewStore);
- // Erase all other stores.
- for (unsigned i = 0; i < NumElem ; ++i) {
+ // Replace one of the loads with the new load.
+ LoadSDNode *Ld = cast<LoadSDNode>(LoadNodes[0].MemNode);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1),
+ SDValue(NewLoad.getNode(), 1));
+
+ // Remove the rest of the load chains.
+ for (unsigned i = 1; i < NumElem ; ++i) {
// Replace all chain users of the old load nodes with the chain of the new
// load node.
LoadSDNode *Ld = cast<LoadSDNode>(LoadNodes[i].MemNode);
- DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1),
- SDValue(NewLoad.getNode(), 1));
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), Ld->getChain());
+ }
+ // Replace the first store with the new store.
+ CombineTo(EarliestOp, NewStore);
+ // Erase all other stores.
+ for (unsigned i = 0; i < NumElem ; ++i) {
// Remove all Store nodes.
if (StoreNodes[i].MemNode == EarliestOp)
continue;
diff --git a/llvm/test/CodeGen/X86/2012-10-03-DAGCycle.ll b/llvm/test/CodeGen/X86/2012-10-03-DAGCycle.ll
new file mode 100644
index 00000000000..72083c7115e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/2012-10-03-DAGCycle.ll
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple=x86_64-apple-macosx -mcpu=corei7 < %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.8.0"
+
+%struct.pluto.0 = type { %struct.bar.1, %struct.hoge.368* }
+%struct.bar.1 = type { %i8* }
+%i8 = type { i8 }
+%struct.hoge.368 = type { i32, i32 }
+%struct.widget.375 = type { i32, i32, %i8*, %struct.hoge.368* }
+
+define fastcc void @bar(%struct.pluto.0* %arg) nounwind uwtable ssp align 2 {
+bb:
+ %tmp1 = alloca %struct.widget.375, align 8
+ %tmp2 = getelementptr inbounds %struct.pluto.0* %arg, i64 0, i32 1
+ %tmp3 = load %struct.hoge.368** %tmp2, align 8
+ store %struct.pluto.0* %arg, %struct.pluto.0** undef, align 8
+ %tmp = getelementptr inbounds %struct.widget.375* %tmp1, i64 0, i32 2
+ %tmp4 = getelementptr %struct.pluto.0* %arg, i64 0, i32 0, i32 0
+ %tmp5 = load %i8** %tmp4, align 8
+ store %i8* %tmp5, %i8** %tmp, align 8
+ %tmp6 = getelementptr inbounds %struct.widget.375* %tmp1, i64 0, i32 3
+ store %struct.hoge.368* %tmp3, %struct.hoge.368** %tmp6, align 8
+ br i1 undef, label %bb8, label %bb7
+
+bb7: ; preds = %bb
+ unreachable
+
+bb8: ; preds = %bb
+ unreachable
+}
OpenPOWER on IntegriCloud