summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2015-05-18 16:42:10 +0000
committerHal Finkel <hfinkel@anl.gov>2015-05-18 16:42:10 +0000
commit44b81ee40bc037be792fdd899ece966eef26e2c8 (patch)
treee4704a62996f0ae68dc19ce4e3f855bea48a2b57 /llvm
parent6cb23465e0ccd195efdc4843f753a4d1eb815f5b (diff)
downloadbcm5719-llvm-44b81ee40bc037be792fdd899ece966eef26e2c8.tar.gz
bcm5719-llvm-44b81ee40bc037be792fdd899ece966eef26e2c8.zip
Preserve the order of READ_REGISTER and WRITE_REGISTER
At the present time, we don't have a way to represent general dependency relationships, so everything is represented using memory dependency. In order to preserve the data dependency of a READ_REGISTER on WRITE_REGISTER, we need to model WRITE_REGISTER as writing (which we had been doing) and model READ_REGISTER as reading (which we had not been doing). Fix this, and also the way that the chain operands were generated at the SDAG level. Patch by Nicholas Paul Johnson, thanks! Test case by me. llvm-svn: 237584
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/Intrinsics.td2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp8
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp6
-rw-r--r--llvm/test/Transforms/EarlyCSE/read-reg.ll34
4 files changed, 44 insertions, 6 deletions
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 1442b64762f..6d98e69eaa9 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -266,7 +266,7 @@ def int_framerecover : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
- [IntrNoMem], "llvm.read_register">;
+ [IntrReadMem], "llvm.read_register">;
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
[], "llvm.write_register">;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 3c5d32f1749..48bf22699b0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4045,16 +4045,20 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
return nullptr;
case Intrinsic::read_register: {
Value *Reg = I.getArgOperand(0);
+ SDValue Chain = getRoot();
SDValue RegName =
DAG.getMDNode(cast<MDNode>(cast<MetadataAsValue>(Reg)->getMetadata()));
EVT VT = TLI.getValueType(I.getType());
- setValue(&I, DAG.getNode(ISD::READ_REGISTER, sdl, VT, RegName));
+ Res = DAG.getNode(ISD::READ_REGISTER, sdl,
+ DAG.getVTList(VT, MVT::Other), Chain, RegName);
+ setValue(&I, Res);
+ DAG.setRoot(Res.getValue(1));
return nullptr;
}
case Intrinsic::write_register: {
Value *Reg = I.getArgOperand(0);
Value *RegValue = I.getArgOperand(1);
- SDValue Chain = getValue(RegValue).getOperand(0);
+ SDValue Chain = getRoot();
SDValue RegName =
DAG.getMDNode(cast<MDNode>(cast<MetadataAsValue>(Reg)->getMetadata()));
DAG.setRoot(DAG.getNode(ISD::WRITE_REGISTER, sdl, MVT::Other, Chain,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 175434e94f8..22f592afae7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1926,12 +1926,12 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
SDNode
*SelectionDAGISel::Select_READ_REGISTER(SDNode *Op) {
SDLoc dl(Op);
- MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(Op->getOperand(0));
+ MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(Op->getOperand(1));
const MDString *RegStr = dyn_cast<MDString>(MD->getMD()->getOperand(0));
unsigned Reg =
TLI->getRegisterByName(RegStr->getString().data(), Op->getValueType(0));
SDValue New = CurDAG->getCopyFromReg(
- CurDAG->getEntryNode(), dl, Reg, Op->getValueType(0));
+ Op->getOperand(0), dl, Reg, Op->getValueType(0));
New->setNodeId(-1);
return New.getNode();
}
@@ -1944,7 +1944,7 @@ SDNode
unsigned Reg = TLI->getRegisterByName(RegStr->getString().data(),
Op->getOperand(2).getValueType());
SDValue New = CurDAG->getCopyToReg(
- CurDAG->getEntryNode(), dl, Reg, Op->getOperand(2));
+ Op->getOperand(0), dl, Reg, Op->getOperand(2));
New->setNodeId(-1);
return New.getNode();
}
diff --git a/llvm/test/Transforms/EarlyCSE/read-reg.ll b/llvm/test/Transforms/EarlyCSE/read-reg.ll
new file mode 100644
index 00000000000..83a299912c7
--- /dev/null
+++ b/llvm/test/Transforms/EarlyCSE/read-reg.ll
@@ -0,0 +1,34 @@
+; RUN: opt -S -early-cse < %s | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define i64 @f(i64 %x) #0 {
+entry:
+ %0 = call i64 @llvm.read_register.i64(metadata !0)
+ call void bitcast (void (...)* @foo to void ()*)()
+ %1 = call i64 @llvm.read_register.i64(metadata !0)
+ %add = add nsw i64 %0, %1
+ ret i64 %add
+}
+
+; CHECK-LABEL: @f
+; CHECK: call i64 @llvm.read_register.i64
+; CHECK: call i64 @llvm.read_register.i64
+
+; Function Attrs: nounwind readnone
+declare i64 @llvm.read_register.i64(metadata) #1
+
+; Function Attrs: nounwind
+declare void @llvm.write_register.i64(metadata, i64) #2
+
+declare void @foo(...)
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+attributes #2 = { nounwind }
+
+!llvm.named.register.r1 = !{!0}
+
+!0 = !{!"r1"}
+
OpenPOWER on IntegriCloud