[llvm] [AMDGPU] Fix negative immediate offset for unbuffered smem loads (PR #79553)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 29 04:42:36 PST 2024
================
@@ -2096,21 +2099,53 @@ bool AMDGPUDAGToDAGISel::SelectSMRDBaseOffset(SDValue Addr, SDValue &SBase,
}
if (!N0 || !N1)
return false;
+
+ bool Selected = false;
if (SelectSMRDOffset(N1, SOffset, Offset, Imm32Only, IsBuffer)) {
SBase = N0;
- return true;
- }
- if (SelectSMRDOffset(N0, SOffset, Offset, Imm32Only, IsBuffer)) {
+ Selected = true;
+ } else if (SelectSMRDOffset(N0, SOffset, Offset, Imm32Only, IsBuffer)) {
SBase = N1;
+ Selected = true;
+ }
+
+ if (Selected) {
+ // For unbuffered smem loads, it is illegal and undefined for the Immediate
+ // Offset to be negative if the resulting (Offset + (M0 or SOffset or zero)
+ // is negative. Handle the case where the Immediate Offset is negative and
+ // there is no SOffset.
+ //
+ // FIXME: Also handle M0 or SOffset case?
+ if (Offset && !HasSOffset && !IsBuffer && !IsPrefetch &&
+ Subtarget->hasSignedSMRDImmOffset()) {
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(*Offset)) {
+ if (C->getSExtValue() < 0) {
+ SDLoc SL(SBase);
+ *Offset = CurDAG->getTargetConstant(std::abs(C->getSExtValue()), SL,
+ MVT::i32);
+ const SDValue Ops[] = {SBase, *Offset};
+ if (Subtarget->hasScalarAddSub64())
+ SBase = SDValue(
+ CurDAG->getMachineNode(AMDGPU::S_SUB_U64, SL, MVT::i64, Ops),
+ 0);
+ else
+ SBase = SDValue(CurDAG->getMachineNode(AMDGPU::S_SUB_U64_PSEUDO, SL,
+ MVT::i64, Ops),
+ 0);
----------------
arsenm wrote:
This can be ternary to select the opcode only
https://github.com/llvm/llvm-project/pull/79553
More information about the llvm-commits
mailing list