diff options
| author | Tim Renouf <tpr.llvm@botech.co.uk> | 2018-10-03 10:29:43 +0000 |
|---|---|---|
| committer | Tim Renouf <tpr.llvm@botech.co.uk> | 2018-10-03 10:29:43 +0000 |
| commit | a37679d67b0df3e265e872294f76d926791d8d6f (patch) | |
| tree | 624bb4af95fb284e0f9ac0597fe6248e93c722a8 /llvm/lib | |
| parent | c68cc4efbe5f8ad49dbd4d5080a9a5fb1720013b (diff) | |
| download | bcm5719-llvm-a37679d67b0df3e265e872294f76d926791d8d6f.tar.gz bcm5719-llvm-a37679d67b0df3e265e872294f76d926791d8d6f.zip | |
[AMDGPU] Fix for negative offsets in buffer/tbuffer intrinsics
Summary:
The new buffer/tbuffer intrinsics handle an out-of-range immediate
offset by moving/adding offset&-4096 to a vgpr, leaving an in-range
immediate offset, with a chance of the move/add being CSEd for similar
loads/stores.
However it turns out that a negative offset in a vgpr is illegal, even
if adding the immediate offset makes it legal again.
Therefore, this commit disables the offset&-4096 thing if the offset is
negative.
Differential Revision: https://reviews.llvm.org/D52683
Change-Id: Ie02f0a74f240a138dc2a29d17cfbd9e350e4ed13
llvm-svn: 343672
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 1bc430b3e06..7f1467c48dd 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -5983,11 +5983,18 @@ std::pair<SDValue, SDValue> SITargetLowering::splitBufferOffsets( if (C1) { unsigned ImmOffset = C1->getZExtValue(); // If the immediate value is too big for the immoffset field, put the value - // mod 4096 into the immoffset field so that the value that is copied/added + // and -4096 into the immoffset field so that the value that is copied/added // for the voffset field is a multiple of 4096, and it stands more chance // of being CSEd with the copy/add for another similar load/store. + // However, do not do that rounding down to a multiple of 4096 if that is a + // negative number, as it appears to be illegal to have a negative offset + // in the vgpr, even if adding the immediate offset makes it positive. unsigned Overflow = ImmOffset & ~MaxImm; ImmOffset -= Overflow; + if ((int32_t)Overflow < 0) { + Overflow += ImmOffset; + ImmOffset = 0; + } C1 = cast<ConstantSDNode>(DAG.getConstant(ImmOffset, DL, MVT::i32)); if (Overflow) { auto OverflowVal = DAG.getConstant(Overflow, DL, MVT::i32); |

