diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h @@ -193,11 +193,11 @@ bool SelectScratchSVAddr(SDNode *N, SDValue Addr, SDValue &VAddr, SDValue &SAddr, SDValue &Offset) const; - bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue &Offset, - bool &Imm) const; + bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue &Offset, bool Imm, + bool Imm32Only) const; SDValue Expand32BitAddress(SDValue Addr) const; - bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue &Offset, - bool &Imm) const; + bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue &Offset, bool Imm, + bool Imm32Only = false) const; bool SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const; bool SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const; bool SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &Offset) const; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -1883,20 +1883,24 @@ return true; } +// 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) const { + SDValue &Offset, bool Imm, + bool Imm32Only) const { ConstantSDNode *C = dyn_cast(ByteOffsetNode); if (!C) { + if (Imm) + return false; if (ByteOffsetNode.getValueType().isScalarInteger() && ByteOffsetNode.getValueType().getSizeInBits() == 32) { Offset = ByteOffsetNode; - Imm = false; return true; } if (ByteOffsetNode.getOpcode() == ISD::ZERO_EXTEND) { if (ByteOffsetNode.getOperand(0).getValueType().getSizeInBits() == 32) { Offset = ByteOffsetNode.getOperand(0); - Imm = false; return true; } } @@ -1908,9 +1912,8 @@ int64_t ByteOffset = C->getSExtValue(); Optional EncodedOffset = AMDGPU::getSMRDEncodedOffset(*Subtarget, ByteOffset, false); - if (EncodedOffset) { + if (EncodedOffset && Imm && !Imm32Only) { Offset = CurDAG->getTargetConstant(*EncodedOffset, SL, MVT::i32); - Imm = true; return true; } @@ -1919,7 +1922,7 @@ return false; EncodedOffset = AMDGPU::getSMRDEncodedLiteralOffset32(*Subtarget, ByteOffset); - if (EncodedOffset) { + if (EncodedOffset && Imm32Only) { Offset = CurDAG->getTargetConstant(*EncodedOffset, SL, MVT::i32); return true; } @@ -1927,11 +1930,14 @@ if (!isUInt<32>(ByteOffset) && !isInt<32>(ByteOffset)) return false; - SDValue C32Bit = CurDAG->getTargetConstant(ByteOffset, SL, MVT::i32); - Offset = SDValue( - CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SL, MVT::i32, C32Bit), 0); + if (!Imm) { + SDValue C32Bit = CurDAG->getTargetConstant(ByteOffset, SL, MVT::i32); + Offset = SDValue( + CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SL, MVT::i32, C32Bit), 0); + return true; + } - return true; + return false; } SDValue AMDGPUDAGToDAGISel::Expand32BitAddress(SDValue Addr) const { @@ -1959,8 +1965,12 @@ Ops), 0); } +// 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) const { + SDValue &Offset, bool Imm, + bool Imm32Only) const { SDLoc SL(Addr); // A 32-bit (address + offset) should not cause unsigned 32-bit integer @@ -1977,41 +1987,34 @@ assert(N0 && N1 && isa(N1)); } if (N0 && N1) { - if (SelectSMRDOffset(N1, Offset, Imm)) { + if (SelectSMRDOffset(N1, Offset, Imm, Imm32Only)) { SBase = Expand32BitAddress(N0); return true; } } + return false; } + if (!Imm) + return false; SBase = Expand32BitAddress(Addr); Offset = CurDAG->getTargetConstant(0, SL, MVT::i32); - Imm = true; return true; } bool AMDGPUDAGToDAGISel::SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const { - bool Imm = false; - return SelectSMRD(Addr, SBase, Offset, Imm) && Imm; + return SelectSMRD(Addr, SBase, Offset, /* Imm */ true); } bool AMDGPUDAGToDAGISel::SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const { - assert(Subtarget->getGeneration() == AMDGPUSubtarget::SEA_ISLANDS); - - bool Imm = false; - if (!SelectSMRD(Addr, SBase, Offset, Imm)) - return false; - - return !Imm && isa(Offset); + return SelectSMRD(Addr, SBase, Offset, /* Imm */ true, /* Imm32Only */ true); } bool AMDGPUDAGToDAGISel::SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &Offset) const { - bool Imm = false; - return SelectSMRD(Addr, SBase, Offset, Imm) && !Imm && - !isa(Offset); + return SelectSMRD(Addr, SBase, Offset, /* Imm */ false); } bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm(SDValue Addr,