Skip to content

Commit 292c78b

Browse files
author
Hal Finkel
committed
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237584 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0139af3 commit 292c78b

File tree

4 files changed

+44
-6
lines changed

4 files changed

+44
-6
lines changed

include/llvm/IR/Intrinsics.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ def int_framerecover : Intrinsic<[llvm_ptr_ty],
266266
[llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
267267
[IntrNoMem]>;
268268
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
269-
[IntrNoMem], "llvm.read_register">;
269+
[IntrReadMem], "llvm.read_register">;
270270
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
271271
[], "llvm.write_register">;
272272

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4045,16 +4045,20 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
40454045
return nullptr;
40464046
case Intrinsic::read_register: {
40474047
Value *Reg = I.getArgOperand(0);
4048+
SDValue Chain = getRoot();
40484049
SDValue RegName =
40494050
DAG.getMDNode(cast<MDNode>(cast<MetadataAsValue>(Reg)->getMetadata()));
40504051
EVT VT = TLI.getValueType(I.getType());
4051-
setValue(&I, DAG.getNode(ISD::READ_REGISTER, sdl, VT, RegName));
4052+
Res = DAG.getNode(ISD::READ_REGISTER, sdl,
4053+
DAG.getVTList(VT, MVT::Other), Chain, RegName);
4054+
setValue(&I, Res);
4055+
DAG.setRoot(Res.getValue(1));
40524056
return nullptr;
40534057
}
40544058
case Intrinsic::write_register: {
40554059
Value *Reg = I.getArgOperand(0);
40564060
Value *RegValue = I.getArgOperand(1);
4057-
SDValue Chain = getValue(RegValue).getOperand(0);
4061+
SDValue Chain = getRoot();
40584062
SDValue RegName =
40594063
DAG.getMDNode(cast<MDNode>(cast<MetadataAsValue>(Reg)->getMetadata()));
40604064
DAG.setRoot(DAG.getNode(ISD::WRITE_REGISTER, sdl, MVT::Other, Chain,

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,12 +1926,12 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {
19261926
SDNode
19271927
*SelectionDAGISel::Select_READ_REGISTER(SDNode *Op) {
19281928
SDLoc dl(Op);
1929-
MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(Op->getOperand(0));
1929+
MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(Op->getOperand(1));
19301930
const MDString *RegStr = dyn_cast<MDString>(MD->getMD()->getOperand(0));
19311931
unsigned Reg =
19321932
TLI->getRegisterByName(RegStr->getString().data(), Op->getValueType(0));
19331933
SDValue New = CurDAG->getCopyFromReg(
1934-
CurDAG->getEntryNode(), dl, Reg, Op->getValueType(0));
1934+
Op->getOperand(0), dl, Reg, Op->getValueType(0));
19351935
New->setNodeId(-1);
19361936
return New.getNode();
19371937
}
@@ -1944,7 +1944,7 @@ SDNode
19441944
unsigned Reg = TLI->getRegisterByName(RegStr->getString().data(),
19451945
Op->getOperand(2).getValueType());
19461946
SDValue New = CurDAG->getCopyToReg(
1947-
CurDAG->getEntryNode(), dl, Reg, Op->getOperand(2));
1947+
Op->getOperand(0), dl, Reg, Op->getOperand(2));
19481948
New->setNodeId(-1);
19491949
return New.getNode();
19501950
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; RUN: opt -S -early-cse < %s | FileCheck %s
2+
target datalayout = "E-m:e-i64:64-n32:64"
3+
target triple = "powerpc64-unknown-linux-gnu"
4+
5+
; Function Attrs: nounwind
6+
define i64 @f(i64 %x) #0 {
7+
entry:
8+
%0 = call i64 @llvm.read_register.i64(metadata !0)
9+
call void bitcast (void (...)* @foo to void ()*)()
10+
%1 = call i64 @llvm.read_register.i64(metadata !0)
11+
%add = add nsw i64 %0, %1
12+
ret i64 %add
13+
}
14+
15+
; CHECK-LABEL: @f
16+
; CHECK: call i64 @llvm.read_register.i64
17+
; CHECK: call i64 @llvm.read_register.i64
18+
19+
; Function Attrs: nounwind readnone
20+
declare i64 @llvm.read_register.i64(metadata) #1
21+
22+
; Function Attrs: nounwind
23+
declare void @llvm.write_register.i64(metadata, i64) #2
24+
25+
declare void @foo(...)
26+
27+
attributes #0 = { nounwind }
28+
attributes #1 = { nounwind readnone }
29+
attributes #2 = { nounwind }
30+
31+
!llvm.named.register.r1 = !{!0}
32+
33+
!0 = !{!"r1"}
34+

0 commit comments

Comments
 (0)