summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp76
1 files changed, 52 insertions, 24 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index 589992c7a7ec..147c8850587e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -33,7 +33,7 @@
#include "llvm/IR/Dominators.h"
#endif
-#define DEBUG_TYPE "isel"
+#define DEBUG_TYPE "amdgpu-isel"
using namespace llvm;
@@ -1886,21 +1886,21 @@ bool AMDGPUDAGToDAGISel::SelectScratchSVAddr(SDNode *N, SDValue Addr,
// Match an immediate (if Imm is true) or an SGPR (if Imm is false)
// offset. If Imm32Only is true, match only 32-bit immediate offsets
// available on CI.
-bool AMDGPUDAGToDAGISel::SelectSMRDOffset(SDValue ByteOffsetNode,
- SDValue &Offset, bool Imm,
+bool AMDGPUDAGToDAGISel::SelectSMRDOffset(SDValue Addr, SDValue ByteOffsetNode,
+ SDValue *SOffset, SDValue *Offset,
bool Imm32Only) const {
ConstantSDNode *C = dyn_cast<ConstantSDNode>(ByteOffsetNode);
if (!C) {
- if (Imm)
+ if (!SOffset)
return false;
if (ByteOffsetNode.getValueType().isScalarInteger() &&
ByteOffsetNode.getValueType().getSizeInBits() == 32) {
- Offset = ByteOffsetNode;
+ *SOffset = ByteOffsetNode;
return true;
}
if (ByteOffsetNode.getOpcode() == ISD::ZERO_EXTEND) {
if (ByteOffsetNode.getOperand(0).getValueType().getSizeInBits() == 32) {
- Offset = ByteOffsetNode.getOperand(0);
+ *SOffset = ByteOffsetNode.getOperand(0);
return true;
}
}
@@ -1912,8 +1912,8 @@ bool AMDGPUDAGToDAGISel::SelectSMRDOffset(SDValue ByteOffsetNode,
int64_t ByteOffset = C->getSExtValue();
Optional<int64_t> EncodedOffset =
AMDGPU::getSMRDEncodedOffset(*Subtarget, ByteOffset, false);
- if (EncodedOffset && Imm && !Imm32Only) {
- Offset = CurDAG->getTargetConstant(*EncodedOffset, SL, MVT::i32);
+ if (EncodedOffset && Offset && !Imm32Only) {
+ *Offset = CurDAG->getTargetConstant(*EncodedOffset, SL, MVT::i32);
return true;
}
@@ -1922,17 +1922,17 @@ bool AMDGPUDAGToDAGISel::SelectSMRDOffset(SDValue ByteOffsetNode,
return false;
EncodedOffset = AMDGPU::getSMRDEncodedLiteralOffset32(*Subtarget, ByteOffset);
- if (EncodedOffset && Imm32Only) {
- Offset = CurDAG->getTargetConstant(*EncodedOffset, SL, MVT::i32);
+ if (EncodedOffset && Offset && Imm32Only) {
+ *Offset = CurDAG->getTargetConstant(*EncodedOffset, SL, MVT::i32);
return true;
}
if (!isUInt<32>(ByteOffset) && !isInt<32>(ByteOffset))
return false;
- if (!Imm) {
+ if (SOffset) {
SDValue C32Bit = CurDAG->getTargetConstant(ByteOffset, SL, MVT::i32);
- Offset = SDValue(
+ *SOffset = SDValue(
CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SL, MVT::i32, C32Bit), 0);
return true;
}
@@ -1968,11 +1968,18 @@ SDValue AMDGPUDAGToDAGISel::Expand32BitAddress(SDValue Addr) const {
// Match a base and an immediate (if Imm is true) or an SGPR
// (if Imm is false) offset. If Imm32Only is true, match only 32-bit
// immediate offsets available on CI.
-bool AMDGPUDAGToDAGISel::SelectSMRD(SDValue Addr, SDValue &SBase,
- SDValue &Offset, bool Imm,
- bool Imm32Only) const {
+bool AMDGPUDAGToDAGISel::SelectSMRDBaseOffset(SDValue Addr, SDValue &SBase,
+ SDValue *SOffset, SDValue *Offset,
+ bool Imm32Only) const {
SDLoc SL(Addr);
+ if (SOffset && Offset) {
+ assert(!Imm32Only);
+ SDValue B;
+ return SelectSMRDBaseOffset(Addr, B, nullptr, Offset) &&
+ SelectSMRDBaseOffset(B, SBase, SOffset, nullptr);
+ }
+
// A 32-bit (address + offset) should not cause unsigned 32-bit integer
// wraparound, because s_load instructions perform the addition in 64 bits.
if ((Addr.getValueType() != MVT::i32 ||
@@ -1987,34 +1994,55 @@ bool AMDGPUDAGToDAGISel::SelectSMRD(SDValue Addr, SDValue &SBase,
assert(N0 && N1 && isa<ConstantSDNode>(N1));
}
if (N0 && N1) {
- if (SelectSMRDOffset(N1, Offset, Imm, Imm32Only)) {
- SBase = Expand32BitAddress(N0);
+ if (SelectSMRDOffset(N0, N1, SOffset, Offset, Imm32Only)) {
+ SBase = N0;
+ return true;
+ }
+ if (SelectSMRDOffset(N1, N0, SOffset, Offset, Imm32Only)) {
+ SBase = N1;
return true;
}
}
return false;
}
- if (!Imm)
+ if (Offset && !SOffset) {
+ SBase = Addr;
+ *Offset = CurDAG->getTargetConstant(0, SL, MVT::i32);
+ return true;
+ }
+ return false;
+}
+
+bool AMDGPUDAGToDAGISel::SelectSMRD(SDValue Addr, SDValue &SBase,
+ SDValue *SOffset, SDValue *Offset,
+ bool Imm32Only) const {
+ if (!SelectSMRDBaseOffset(Addr, SBase, SOffset, Offset, Imm32Only))
return false;
- SBase = Expand32BitAddress(Addr);
- Offset = CurDAG->getTargetConstant(0, SL, MVT::i32);
+ SBase = Expand32BitAddress(SBase);
return true;
}
bool AMDGPUDAGToDAGISel::SelectSMRDImm(SDValue Addr, SDValue &SBase,
SDValue &Offset) const {
- return SelectSMRD(Addr, SBase, Offset, /* Imm */ true);
+ return SelectSMRD(Addr, SBase, /* SOffset */ nullptr, &Offset);
}
bool AMDGPUDAGToDAGISel::SelectSMRDImm32(SDValue Addr, SDValue &SBase,
SDValue &Offset) const {
assert(Subtarget->getGeneration() == AMDGPUSubtarget::SEA_ISLANDS);
- return SelectSMRD(Addr, SBase, Offset, /* Imm */ true, /* Imm32Only */ true);
+ return SelectSMRD(Addr, SBase, /* SOffset */ nullptr, &Offset,
+ /* Imm32Only */ true);
}
bool AMDGPUDAGToDAGISel::SelectSMRDSgpr(SDValue Addr, SDValue &SBase,
- SDValue &Offset) const {
- return SelectSMRD(Addr, SBase, Offset, /* Imm */ false);
+ SDValue &SOffset) const {
+ return SelectSMRD(Addr, SBase, &SOffset, /* Offset */ nullptr);
+}
+
+bool AMDGPUDAGToDAGISel::SelectSMRDSgprImm(SDValue Addr, SDValue &SBase,
+ SDValue &SOffset,
+ SDValue &Offset) const {
+ return SelectSMRD(Addr, SBase, &SOffset, &Offset);
}
bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm(SDValue Addr,