summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU
diff options
context:
space:
mode:
authorAustin Kerbow <Austin.Kerbow@amd.com>2019-10-28 09:39:20 -0700
committerAustin Kerbow <Austin.Kerbow@amd.com>2019-10-28 10:02:22 -0700
commitd11b93ec6ac1cf48dce0a8b7beb3e07f0ee9b0fc (patch)
tree3f5a885b61fe23680e336adfccf92a09a6303c19 /llvm/lib/Target/AMDGPU
parent2ddd1564a9c2c648ac63fcaca474d5386cebd3fe (diff)
downloadbcm5719-llvm-d11b93ec6ac1cf48dce0a8b7beb3e07f0ee9b0fc.tar.gz
bcm5719-llvm-d11b93ec6ac1cf48dce0a8b7beb3e07f0ee9b0fc.zip
AMDGPU: Avoid overwriting saved PC
Summary: An outstanding load with same destination sgpr as call could cause PC to be updated with junk value on return. Reviewers: arsenm, rampitec Reviewed By: arsenm Subscribers: kzhuravl, jvesely, wdng, nhaehnle, yaxunl, dstuttard, tpr, t-tye, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69474
Diffstat (limited to 'llvm/lib/Target/AMDGPU')
-rw-r--r--llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
index dcb04e42658..e84e948edb6 100644
--- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
@@ -939,19 +939,33 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(
}
if (MI.isCall() && callWaitsOnFunctionEntry(MI)) {
- // Don't bother waiting on anything except the call address. The function
- // is going to insert a wait on everything in its prolog. This still needs
- // to be careful if the call target is a load (e.g. a GOT load).
+ // The function is going to insert a wait on everything in its prolog.
+ // This still needs to be careful if the call target is a load (e.g. a GOT
+ // load). We also need to check WAW depenancy with saved PC.
Wait = AMDGPU::Waitcnt();
int CallAddrOpIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src0);
- RegInterval Interval = ScoreBrackets.getRegInterval(&MI, TII, MRI, TRI,
- CallAddrOpIdx, false);
- for (signed RegNo = Interval.first; RegNo < Interval.second; ++RegNo) {
+ RegInterval CallAddrOpInterval = ScoreBrackets.getRegInterval(
+ &MI, TII, MRI, TRI, CallAddrOpIdx, false);
+
+ for (signed RegNo = CallAddrOpInterval.first;
+ RegNo < CallAddrOpInterval.second; ++RegNo)
ScoreBrackets.determineWait(
LGKM_CNT, ScoreBrackets.getRegScore(RegNo, LGKM_CNT), Wait);
+
+ int RtnAddrOpIdx =
+ AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dst);
+ if (RtnAddrOpIdx != -1) {
+ RegInterval RtnAddrOpInterval = ScoreBrackets.getRegInterval(
+ &MI, TII, MRI, TRI, RtnAddrOpIdx, false);
+
+ for (signed RegNo = RtnAddrOpInterval.first;
+ RegNo < RtnAddrOpInterval.second; ++RegNo)
+ ScoreBrackets.determineWait(
+ LGKM_CNT, ScoreBrackets.getRegScore(RegNo, LGKM_CNT), Wait);
}
+
} else {
// FIXME: Should not be relying on memoperands.
// Look at the source operands of every instruction to see if
OpenPOWER on IntegriCloud