[llvm] [WIP][AMDGPU] Support the RF inline asm constraint (PR #195123)

Jun Wang via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 17 15:50:04 PDT 2026


https://github.com/jwanggit86 updated https://github.com/llvm/llvm-project/pull/195123

>From 3a784b46c087e2e609b9a5f0b7d4960b7cc5d305 Mon Sep 17 00:00:00 2001
From: Jun Wang <jwang86 at yahoo.com>
Date: Thu, 30 Apr 2026 09:34:53 -0700
Subject: [PATCH 1/6] [AMDGPU] Support the RF inline asm constraint

This patch supports the RF inline asm constraint for memory
operands in the flat address space.
---
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp   |  12 ++
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h     |   3 +
 llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp |  12 ++
 llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h   |   3 +
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |  10 ++
 llvm/lib/Target/AMDGPU/SIISelLowering.h       |   2 +
 .../CodeGen/AMDGPU/inline-mem-constraints.ll  | 143 ++++++++++++++++++
 7 files changed, 185 insertions(+)
 create mode 100644 llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index a01130af415db..19239095392d1 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -1940,6 +1940,18 @@ bool AMDGPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
   return true;
 }
 
+bool AMDGPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
+                                             unsigned OpNo,
+                                             const char *ExtraCode,
+                                             raw_ostream &OS) {
+  const MachineOperand &MO = MI->getOperand(OpNo);
+  if (!MO.isReg())
+    return true;
+  AMDGPUInstPrinter::printRegOperand(MO.getReg(), OS,
+                                     *MF->getSubtarget().getRegisterInfo());
+  return false;
+}
+
 void AMDGPUAsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<AMDGPUResourceUsageAnalysisWrapperPass>();
   AU.addPreserved<AMDGPUResourceUsageAnalysisWrapperPass>();
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h
index 4394cde308665..598510a3eddaf 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h
@@ -156,6 +156,9 @@ class AMDGPUAsmPrinter final : public AsmPrinter {
   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                        const char *ExtraCode, raw_ostream &O) override;
 
+  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
+                             const char *ExtraCode, raw_ostream &O) override;
+
 protected:
   void getAnalysisUsage(AnalysisUsage &AU) const override;
 
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index 97004dd6f743a..28328eb2443e8 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -4761,6 +4761,18 @@ void AMDGPUDAGToDAGISel::PostprocessISelDAG() {
   } while (IsModified);
 }
 
+bool AMDGPUDAGToDAGISel::SelectInlineAsmMemoryOperand(
+    const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
+    std::vector<SDValue> &OutOps) {
+  switch (ConstraintID) {
+  case InlineAsm::ConstraintCode::m:
+    OutOps.push_back(Op);
+    return false;
+  default:
+    return true;
+  }
+}
+
 AMDGPUDAGToDAGISelLegacy::AMDGPUDAGToDAGISelLegacy(TargetMachine &TM,
                                                    CodeGenOptLevel OptLevel)
     : SelectionDAGISelLegacy(
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h
index 95f85a6151375..df6c6c57862c8 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h
@@ -70,6 +70,9 @@ class AMDGPUDAGToDAGISel : public SelectionDAGISel {
   void PreprocessISelDAG() override;
   void Select(SDNode *N) override;
   void PostprocessISelDAG() override;
+  bool SelectInlineAsmMemoryOperand(const SDValue &Op,
+                                    InlineAsm::ConstraintCode ConstraintID,
+                                    std::vector<SDValue> &OutOps) override;
 
 protected:
   void SelectBuildVector(SDNode *N, unsigned RegClassID);
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 87e951e489ba5..4c647b465d418 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -19524,6 +19524,8 @@ SITargetLowering::getConstraintType(StringRef Constraint) const {
   } else if (Constraint.size() == 2) {
     if (Constraint == "VA")
       return C_RegisterClass;
+    else if (Constraint == "RF")
+      return C_Memory;
   }
   if (isImmConstraint(Constraint)) {
     return C_Other;
@@ -19531,6 +19533,14 @@ SITargetLowering::getConstraintType(StringRef Constraint) const {
   return TargetLowering::getConstraintType(Constraint);
 }
 
+InlineAsm::ConstraintCode
+SITargetLowering::getInlineAsmMemConstraint(StringRef ConstraintCode) const {
+  if (ConstraintCode == "RF")
+    return InlineAsm::ConstraintCode::m;
+
+  return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
+}
+
 static uint64_t clearUnusedBits(uint64_t Val, unsigned Size) {
   if (!AMDGPU::isInlinableIntLiteral(Val)) {
     Val = Val & maskTrailingOnes<uint64_t>(Size);
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h
index 86653fe6920c5..98a36450a9b77 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h
@@ -525,6 +525,8 @@ class SITargetLowering final : public AMDGPUTargetLowering {
   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                StringRef Constraint, MVT VT) const override;
   ConstraintType getConstraintType(StringRef Constraint) const override;
+  InlineAsm::ConstraintCode
+  getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
   void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
                                     std::vector<SDValue> &Ops,
                                     SelectionDAG &DAG) const override;
diff --git a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
new file mode 100644
index 0000000000000..8ee80b0115417
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
@@ -0,0 +1,143 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+
+; RUN: llc -mtriple=amdgcn -mcpu=tonga < %s | FileCheck --check-prefix=VI %s
+
+define amdgpu_kernel void @flat_load_v(ptr addrspace(0) %ptr) {
+; VI-LABEL: flat_load_v:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+entry:
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  ret void
+}
+
+define amdgpu_kernel void @flat_load_v_with_offset(ptr addrspace(0) %ptr) {
+; VI-LABEL: flat_load_v_with_offset:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, s[0:1] offset:4095
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+entry:
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=v,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  ret void
+}
+
+define amdgpu_kernel void @flat_load_s(ptr addrspace(0) %ptr) {
+; VI-LABEL: flat_load_s:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword s0, s[0:1]
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+entry:
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=s,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  ret void
+}
+
+define amdgpu_kernel void @flat_load_s_with_offset(ptr addrspace(0) %ptr) {
+; VI-LABEL: flat_load_s_with_offset:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword s0, s[0:1] offset:4095
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+entry:
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=s,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  ret void
+}
+
+define amdgpu_kernel void @flat_store_imm(ptr addrspace(0) %out) {
+; VI-LABEL: flat_store_imm:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], 63
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1", "=*^RF,I"(ptr addrspace(0) elementtype(i32) %out, i32 63)
+  ret void
+}
+
+define amdgpu_kernel void @flat_store_imm_with_offset(ptr addrspace(0) %out) {
+; VI-LABEL: flat_store_imm_with_offset:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], 63 offset:4095
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1 offset:4095", "=*^RF,I"(ptr addrspace(0) elementtype(i32) %out, i32 63)
+  ret void
+}
+
+define amdgpu_kernel void @flat_store_v(ptr addrspace(0) %out, i32 %in) {
+; VI-LABEL: flat_store_v:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    v_mov_b32_e32 v0, s2
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], v0
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  ret void
+}
+
+define amdgpu_kernel void @flat_store_v_with_offset(ptr addrspace(0) %out, i32 %in) {
+; VI-LABEL: flat_store_v_with_offset:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    v_mov_b32_e32 v0, s2
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], v0 offset:4095
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1 offset:4095", "=*^RF,v"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  ret void
+}
+
+define amdgpu_kernel void @flat_store_s(ptr addrspace(0) %out, i32 %in) {
+; VI-LABEL: flat_store_s:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], s2
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1", "=*^RF,s"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  ret void
+}
+
+define amdgpu_kernel void @flat_store_s_with_offset(ptr addrspace(0) %out, i32 %in) {
+; VI-LABEL: flat_store_s_with_offset:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], s2 offset:4095
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1 offset:4095", "=*^RF,s"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  ret void
+}

>From 23046e6924312263aae5e82ee948cfffc89c2c4f Mon Sep 17 00:00:00 2001
From: Jun Wang <jwang86 at yahoo.com>
Date: Tue, 26 May 2026 16:32:53 -0700
Subject: [PATCH 2/6] Add support for the 'm' constraint.

---
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |  4 +-
 .../CodeGen/AMDGPU/inline-mem-constraints.ll  | 70 +++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 4c647b465d418..d9b2e793eb140 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -19520,6 +19520,8 @@ SITargetLowering::getConstraintType(StringRef Constraint) const {
     case 'v':
     case 'a':
       return C_RegisterClass;
+    case 'm':
+      return C_Memory;
     }
   } else if (Constraint.size() == 2) {
     if (Constraint == "VA")
@@ -19535,7 +19537,7 @@ SITargetLowering::getConstraintType(StringRef Constraint) const {
 
 InlineAsm::ConstraintCode
 SITargetLowering::getInlineAsmMemConstraint(StringRef ConstraintCode) const {
-  if (ConstraintCode == "RF")
+  if (ConstraintCode == "m" || ConstraintCode == "RF")
     return InlineAsm::ConstraintCode::m;
 
   return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
diff --git a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
index 8ee80b0115417..822b0d9f25f22 100644
--- a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
+++ b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
@@ -16,6 +16,20 @@ entry:
   ret void
 }
 
+define amdgpu_kernel void @flat_load_v_m_constraint(ptr addrspace(0) %ptr) {
+; VI-LABEL: flat_load_v_m_constraint:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+entry:
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(0) elementtype(i32) %ptr)
+  ret void
+}
+
 define amdgpu_kernel void @flat_load_v_with_offset(ptr addrspace(0) %ptr) {
 ; VI-LABEL: flat_load_v_with_offset:
 ; VI:       ; %bb.0: ; %entry
@@ -44,6 +58,20 @@ entry:
   ret void
 }
 
+define amdgpu_kernel void @flat_load_s_m_constraint(ptr addrspace(0) %ptr) {
+; VI-LABEL: flat_load_s_m_constraint:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword s0, s[0:1]
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+entry:
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=s,*m"(ptr addrspace(0) elementtype(i32) %ptr)
+  ret void
+}
+
 define amdgpu_kernel void @flat_load_s_with_offset(ptr addrspace(0) %ptr) {
 ; VI-LABEL: flat_load_s_with_offset:
 ; VI:       ; %bb.0: ; %entry
@@ -71,6 +99,19 @@ define amdgpu_kernel void @flat_store_imm(ptr addrspace(0) %out) {
   ret void
 }
 
+define amdgpu_kernel void @flat_store_imm_m_constraint(ptr addrspace(0) %out) {
+; VI-LABEL: flat_store_imm_m_constraint:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], 63
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1", "=*m,I"(ptr addrspace(0) elementtype(i32) %out, i32 63)
+  ret void
+}
+
 define amdgpu_kernel void @flat_store_imm_with_offset(ptr addrspace(0) %out) {
 ; VI-LABEL: flat_store_imm_with_offset:
 ; VI:       ; %bb.0:
@@ -99,6 +140,21 @@ define amdgpu_kernel void @flat_store_v(ptr addrspace(0) %out, i32 %in) {
   ret void
 }
 
+define amdgpu_kernel void @flat_store_v_m_constraint(ptr addrspace(0) %out, i32 %in) {
+; VI-LABEL: flat_store_v_m_constraint:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    v_mov_b32_e32 v0, s2
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], v0
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  ret void
+}
+
 define amdgpu_kernel void @flat_store_v_with_offset(ptr addrspace(0) %out, i32 %in) {
 ; VI-LABEL: flat_store_v_with_offset:
 ; VI:       ; %bb.0:
@@ -128,6 +184,20 @@ define amdgpu_kernel void @flat_store_s(ptr addrspace(0) %out, i32 %in) {
   ret void
 }
 
+define amdgpu_kernel void @flat_store_s_m_constraint(ptr addrspace(0) %out, i32 %in) {
+; VI-LABEL: flat_store_s_m_constraint:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword s[0:1], s2
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_endpgm
+  call void asm "flat_store_dword $0, $1", "=*m,s"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  ret void
+}
+
 define amdgpu_kernel void @flat_store_s_with_offset(ptr addrspace(0) %out, i32 %in) {
 ; VI-LABEL: flat_store_s_with_offset:
 ; VI:       ; %bb.0:

>From b4c19cf1840a7191ab078834b19c6de5c3b2f1f9 Mon Sep 17 00:00:00 2001
From: Jun Wang <jwang86 at yahoo.com>
Date: Mon, 1 Jun 2026 15:28:18 -0700
Subject: [PATCH 3/6] (1) minor code change (2) update tests as sgprs are not
 allowed in flat_load/store.

---
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |   4 +-
 .../CodeGen/AMDGPU/inline-mem-constraints.ll  | 186 ++++++++++--------
 2 files changed, 109 insertions(+), 81 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index d9b2e793eb140..ddc203eae9552 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -19526,7 +19526,7 @@ SITargetLowering::getConstraintType(StringRef Constraint) const {
   } else if (Constraint.size() == 2) {
     if (Constraint == "VA")
       return C_RegisterClass;
-    else if (Constraint == "RF")
+    if (Constraint == "RF")
       return C_Memory;
   }
   if (isImmConstraint(Constraint)) {
@@ -19537,7 +19537,7 @@ SITargetLowering::getConstraintType(StringRef Constraint) const {
 
 InlineAsm::ConstraintCode
 SITargetLowering::getInlineAsmMemConstraint(StringRef ConstraintCode) const {
-  if (ConstraintCode == "m" || ConstraintCode == "RF")
+  if (ConstraintCode == "RF")
     return InlineAsm::ConstraintCode::m;
 
   return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
diff --git a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
index 822b0d9f25f22..c657d1ffb87df 100644
--- a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
+++ b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
@@ -2,8 +2,8 @@
 
 ; RUN: llc -mtriple=amdgcn -mcpu=tonga < %s | FileCheck --check-prefix=VI %s
 
-define amdgpu_kernel void @flat_load_v(ptr addrspace(0) %ptr) {
-; VI-LABEL: flat_load_v:
+define amdgpu_kernel void @flat_load(ptr %ptr) {
+; VI-LABEL: flat_load:
 ; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
@@ -12,12 +12,12 @@ define amdgpu_kernel void @flat_load_v(ptr addrspace(0) %ptr) {
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr elementtype(i32) %ptr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_v_m_constraint(ptr addrspace(0) %ptr) {
-; VI-LABEL: flat_load_v_m_constraint:
+define amdgpu_kernel void @flat_load_as1(ptr addrspace(1) %ptr) {
+; VI-LABEL: flat_load_as1:
 ; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
@@ -26,188 +26,216 @@ define amdgpu_kernel void @flat_load_v_m_constraint(ptr addrspace(0) %ptr) {
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(0) elementtype(i32) %ptr)
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(1) elementtype(i32) %ptr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_v_with_offset(ptr addrspace(0) %ptr) {
-; VI-LABEL: flat_load_v_with_offset:
+define amdgpu_kernel void @flat_load_as4(ptr addrspace(4) %ptr) {
+; VI-LABEL: flat_load_as4:
 ; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1] offset:4095
+; VI-NEXT:    flat_load_dword v0, s[0:1]
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=v,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(4) elementtype(i32) %ptr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_s(ptr addrspace(0) %ptr) {
-; VI-LABEL: flat_load_s:
+define amdgpu_kernel void @flat_load_m_constraint(ptr %ptr) {
+; VI-LABEL: flat_load_m_constraint:
 ; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword s0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, s[0:1]
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=s,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr elementtype(i32) %ptr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_s_m_constraint(ptr addrspace(0) %ptr) {
-; VI-LABEL: flat_load_s_m_constraint:
+define amdgpu_kernel void @flat_load_m_constraint_as1(ptr addrspace(1) %ptr) {
+; VI-LABEL: flat_load_m_constraint_as1:
 ; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword s0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, s[0:1]
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=s,*m"(ptr addrspace(0) elementtype(i32) %ptr)
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(1) elementtype(i32) %ptr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_s_with_offset(ptr addrspace(0) %ptr) {
-; VI-LABEL: flat_load_s_with_offset:
+define amdgpu_kernel void @flat_load_m_constraint_as4(ptr addrspace(4) %ptr) {
+; VI-LABEL: flat_load_m_constraint_as4:
 ; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword s0, s[0:1] offset:4095
+; VI-NEXT:    flat_load_dword v0, s[0:1]
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=s,*^RF"(ptr addrspace(0) elementtype(i32) %ptr)
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(4) elementtype(i32) %ptr)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_imm(ptr addrspace(0) %out) {
-; VI-LABEL: flat_store_imm:
-; VI:       ; %bb.0:
+define amdgpu_kernel void @flat_load_with_offset(ptr %ptr) {
+; VI-LABEL: flat_load_with_offset:
+; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], 63
+; VI-NEXT:    flat_load_dword v0, s[0:1] offset:4095
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1", "=*^RF,I"(ptr addrspace(0) elementtype(i32) %out, i32 63)
+entry:
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=v,*^RF"(ptr elementtype(i32) %ptr)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_imm_m_constraint(ptr addrspace(0) %out) {
-; VI-LABEL: flat_store_imm_m_constraint:
-; VI:       ; %bb.0:
+define amdgpu_kernel void @flat_load_from_v(ptr %ptr) {
+; VI-LABEL: flat_load_from_v:
+; VI:       ; %bb.0: ; %entry
 ; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    v_mov_b32_e32 v0, s0
+; VI-NEXT:    v_mov_b32_e32 v1, s1
+; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], 63
+; VI-NEXT:    flat_load_dword v0, v[0:1]
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1", "=*m,I"(ptr addrspace(0) elementtype(i32) %out, i32 63)
+entry:
+  %addr = load ptr, ptr %ptr
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_imm_with_offset(ptr addrspace(0) %out) {
-; VI-LABEL: flat_store_imm_with_offset:
-; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], 63 offset:4095
-; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1 offset:4095", "=*^RF,I"(ptr addrspace(0) elementtype(i32) %out, i32 63)
-  ret void
-}
 
-define amdgpu_kernel void @flat_store_v(ptr addrspace(0) %out, i32 %in) {
+define amdgpu_kernel void @flat_store_v(ptr %in, ptr %in2) {
 ; VI-LABEL: flat_store_v:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s2
+; VI-NEXT:    v_mov_b32_e32 v0, s0
+; VI-NEXT:    v_mov_b32_e32 v1, s1
+; VI-NEXT:    v_mov_b32_e32 v2, s2
+; VI-NEXT:    v_mov_b32_e32 v3, s3
+; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
+; VI-NEXT:    flat_load_dword v2, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], v0
+; VI-NEXT:    flat_store_dword v[0:1], v2
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  %addr = load ptr, ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_v_m_constraint(ptr addrspace(0) %out, i32 %in) {
-; VI-LABEL: flat_store_v_m_constraint:
+define amdgpu_kernel void @flat_store_v_as1(ptr addrspace(1) %in, ptr addrspace(1) %in2) {
+; VI-LABEL: flat_store_v_as1:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
 ; VI-NEXT:    v_mov_b32_e32 v0, s2
 ; VI-NEXT:    ;;#ASMSTART
 ; VI-NEXT:    flat_store_dword s[0:1], v0
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  %addr = load ptr addrspace(1), ptr addrspace(1) %in
+  %data = load i32, ptr addrspace(1) %in2
+  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(1) elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_v_with_offset(ptr addrspace(0) %out, i32 %in) {
-; VI-LABEL: flat_store_v_with_offset:
+define amdgpu_kernel void @flat_store_v_as4(ptr addrspace(4) %in, ptr addrspace(4) %in2) {
+; VI-LABEL: flat_store_v_as4:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
 ; VI-NEXT:    v_mov_b32_e32 v0, s2
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], v0 offset:4095
+; VI-NEXT:    flat_store_dword s[0:1], v0
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1 offset:4095", "=*^RF,v"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  %addr = load ptr addrspace(4), ptr addrspace(4) %in
+  %data = load i32, ptr addrspace(4) %in2
+  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(4) elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_s(ptr addrspace(0) %out, i32 %in) {
-; VI-LABEL: flat_store_s:
+define amdgpu_kernel void @flat_store_v_m_constraint(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_v_m_constraint:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    v_mov_b32_e32 v0, s0
+; VI-NEXT:    v_mov_b32_e32 v1, s1
+; VI-NEXT:    v_mov_b32_e32 v2, s2
+; VI-NEXT:    v_mov_b32_e32 v3, s3
+; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
+; VI-NEXT:    flat_load_dword v2, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], s2
+; VI-NEXT:    flat_store_dword v[0:1], v2
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1", "=*^RF,s"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  %addr = load ptr, ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_s_m_constraint(ptr addrspace(0) %out, i32 %in) {
-; VI-LABEL: flat_store_s_m_constraint:
+define amdgpu_kernel void @flat_store_v_m_constraint_as1(ptr addrspace(1) %in, ptr addrspace(1) %in2) {
+; VI-LABEL: flat_store_v_m_constraint_as1:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    v_mov_b32_e32 v0, s2
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], s2
+; VI-NEXT:    flat_store_dword s[0:1], v0
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1", "=*m,s"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  %addr = load ptr addrspace(1), ptr addrspace(1) %in
+  %data = load i32, ptr addrspace(1) %in2
+  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(1) elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_s_with_offset(ptr addrspace(0) %out, i32 %in) {
-; VI-LABEL: flat_store_s_with_offset:
+define amdgpu_kernel void @flat_store_v_m_constraint_as4(ptr addrspace(4) %in, ptr addrspace(4) %in2) {
+; VI-LABEL: flat_store_v_m_constraint_as4:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
+; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
+; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
 ; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    v_mov_b32_e32 v0, s2
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], s2 offset:4095
+; VI-NEXT:    flat_store_dword s[0:1], v0
 ; VI-NEXT:    ;;#ASMEND
 ; VI-NEXT:    s_endpgm
-  call void asm "flat_store_dword $0, $1 offset:4095", "=*^RF,s"(ptr addrspace(0) elementtype(i32) %out, i32 %in)
+  %addr = load ptr addrspace(4), ptr addrspace(4) %in
+  %data = load i32, ptr addrspace(4) %in2
+  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(4) elementtype(i32) %addr, i32 %data)
   ret void
 }

>From 7886469db560f083b96218e6a12cbe658205fc47 Mon Sep 17 00:00:00 2001
From: Jun Wang <jwang86 at yahoo.com>
Date: Tue, 9 Jun 2026 13:11:31 -0700
Subject: [PATCH 4/6] Update an assert in SelectionDAGBuilder.cpp; also update
 the test file.

An assert in SelectionDAGBuilder.cpp calls getPointerTy() but omits
the 2nd parameter which is for address space and defaults to 0.
This is problematic for AMDGPU where pointers of address spaces
2,3, and 5 have a different size (32-bit) than address space 0
(64-bit).
---
 .../SelectionDAG/SelectionDAGBuilder.cpp      |   7 +-
 .../CodeGen/AMDGPU/inline-mem-constraints.ll  | 501 +++++++++++++-----
 2 files changed, 375 insertions(+), 133 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 0f6bd53cafdd8..ca41e7247a7fb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10658,8 +10658,13 @@ static bool prepareDAGLevelOperands(ConstraintDecisionInfo &Info,
         assert((OpInfo.isIndirect ||
                 OpInfo.ConstraintType != TargetLowering::C_Memory) &&
                "Operand must be indirect to be a mem!");
+        unsigned AddrSpace = 0;
+        const Value *Ptr = OpInfo.CallOperandVal;
+        if (Ptr && Ptr->getType()->getTypeID() == Type::PointerTyID)
+          AddrSpace = cast<PointerType>(Ptr->getType())->getAddressSpace();
+
         assert(InOperandVal.getValueType() ==
-                   TLI.getPointerTy(DAG.getDataLayout()) &&
+                   TLI.getPointerTy(DAG.getDataLayout(), AddrSpace) &&
                "Memory operands expect pointer values");
 
         const InlineAsm::ConstraintCode ConstraintID =
diff --git a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
index c657d1ffb87df..ef7f889e8b943 100644
--- a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
+++ b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
@@ -2,240 +2,477 @@
 
 ; RUN: llc -mtriple=amdgcn -mcpu=tonga < %s | FileCheck --check-prefix=VI %s
 
-define amdgpu_kernel void @flat_load(ptr %ptr) {
-; VI-LABEL: flat_load:
+define void @flat_load_RF(ptr %in) {
+; VI-LABEL: flat_load_RF:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %addr = load ptr, ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr elementtype(i32) %addr)
+  ret void
+}
+
+define void @flat_load_RF_as1(ptr %in) {
+; VI-LABEL: flat_load_RF_as1:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %addr = load ptr addrspace(1), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(1) elementtype(i32) %addr)
+  ret void
+}
+
+define void @flat_load_RF_as2(ptr %in) {
+; VI-LABEL: flat_load_RF_as2:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, v0
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr elementtype(i32) %ptr)
+  %addr = load ptr addrspace(2), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(2) elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_as1(ptr addrspace(1) %ptr) {
-; VI-LABEL: flat_load_as1:
+define void @flat_load_RF_as3(ptr %in) {
+; VI-LABEL: flat_load_RF_as3:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, v0
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(1) elementtype(i32) %ptr)
+  %addr = load ptr addrspace(3), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(3) elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_as4(ptr addrspace(4) %ptr) {
-; VI-LABEL: flat_load_as4:
+define void @flat_load_RF_as4(ptr %in) {
+; VI-LABEL: flat_load_RF_as4:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, v[0:1]
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(4) elementtype(i32) %ptr)
+  %addr = load ptr addrspace(4), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(4) elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_m_constraint(ptr %ptr) {
+define void @flat_load_RF_as5(ptr %in) {
+; VI-LABEL: flat_load_RF_as5:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, v0
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %addr = load ptr addrspace(5), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr addrspace(5) elementtype(i32) %addr)
+  ret void
+}
+
+
+define void @flat_load_m_constraint(ptr %in) {
 ; VI-LABEL: flat_load_m_constraint:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, v[0:1]
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr elementtype(i32) %ptr)
+  %addr = load ptr, ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_m_constraint_as1(ptr addrspace(1) %ptr) {
+define void @flat_load_m_constraint_as1(ptr %in) {
 ; VI-LABEL: flat_load_m_constraint_as1:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %addr = load ptr addrspace(1), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(1) elementtype(i32) %addr)
+  ret void
+}
+
+define void @flat_load_m_constraint_as2(ptr %in) {
+; VI-LABEL: flat_load_m_constraint_as2:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, v0
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %addr = load ptr addrspace(2), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(2) elementtype(i32) %addr)
+  ret void
+}
+
+define void @flat_load_m_constraint_as3(ptr %in) {
+; VI-LABEL: flat_load_m_constraint_as3:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, v0
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(1) elementtype(i32) %ptr)
+  %addr = load ptr addrspace(3), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(3) elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_m_constraint_as4(ptr addrspace(4) %ptr) {
+define void @flat_load_m_constraint_as4(ptr %in) {
 ; VI-LABEL: flat_load_m_constraint_as4:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1]
+; VI-NEXT:    flat_load_dword v0, v[0:1]
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(4) elementtype(i32) %ptr)
+  %addr = load ptr addrspace(4), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(4) elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_with_offset(ptr %ptr) {
-; VI-LABEL: flat_load_with_offset:
+define void @flat_load_m_constraint_as5(ptr %in) {
+; VI-LABEL: flat_load_m_constraint_as5:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_load_dword v0, s[0:1] offset:4095
+; VI-NEXT:    flat_load_dword v0, v0
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=v,*^RF"(ptr elementtype(i32) %ptr)
+  %addr = load ptr addrspace(5), ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*m"(ptr addrspace(5) elementtype(i32) %addr)
   ret void
 }
 
-define amdgpu_kernel void @flat_load_from_v(ptr %ptr) {
-; VI-LABEL: flat_load_from_v:
+
+define void @flat_load_with_offset_RF(ptr %in) {
+; VI-LABEL: flat_load_with_offset_RF:
 ; VI:       ; %bb.0: ; %entry
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s0
-; VI-NEXT:    v_mov_b32_e32 v1, s1
-; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
 ; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, v[0:1] offset:4095
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %addr = load ptr, ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=v,*^RF"(ptr elementtype(i32) %addr)
+  ret void
+}
+
+define void @flat_load_with_offset_m_constraint(ptr %in) {
+; VI-LABEL: flat_load_with_offset_m_constraint:
+; VI:       ; %bb.0: ; %entry
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
 ; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_load_dword v0, v[0:1] offset:4095
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
 entry:
-  %addr = load ptr, ptr %ptr
-  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1", "=v,*^RF"(ptr elementtype(i32) %addr)
+  %addr = load ptr, ptr %in
+  %a = tail call i32 asm sideeffect "flat_load_dword $0, $1 offset:4095", "=v,*m"(ptr elementtype(i32) %addr)
   ret void
 }
 
 
-define amdgpu_kernel void @flat_store_v(ptr %in, ptr %in2) {
-; VI-LABEL: flat_store_v:
+
+define void @flat_store_RF(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_RF:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s0
-; VI-NEXT:    v_mov_b32_e32 v1, s1
-; VI-NEXT:    v_mov_b32_e32 v2, s2
-; VI-NEXT:    v_mov_b32_e32 v3, s3
-; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v4, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[4:5]
 ; VI-NEXT:    flat_load_dword v2, v[2:3]
 ; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
 ; VI-NEXT:    flat_store_dword v[0:1], v2
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
   %addr = load ptr, ptr %in
   %data = load i32, ptr %in2
   call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_v_as1(ptr addrspace(1) %in, ptr addrspace(1) %in2) {
-; VI-LABEL: flat_store_v_as1:
+define void @flat_store_RF_as1(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_RF_as1:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s2
-; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], v0
-; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
-  %addr = load ptr addrspace(1), ptr addrspace(1) %in
-  %data = load i32, ptr addrspace(1) %in2
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v4, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[4:5]
+; VI-NEXT:    flat_load_dword v2, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v[0:1], v2
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(1), ptr %in
+  %data = load i32, ptr %in2
   call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(1) elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_v_as4(ptr addrspace(4) %in, ptr addrspace(4) %in2) {
-; VI-LABEL: flat_store_v_as4:
+define void @flat_store_RF_as2(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_RF_as2:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v0, v1
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(2), ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(2) elementtype(i32) %addr, i32 %data)
+  ret void
+}
+
+define void @flat_store_RF_as3(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_RF_as3:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v0, v1
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(3), ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(3) elementtype(i32) %addr, i32 %data)
+  ret void
+}
+
+define void @flat_store_RF_as4(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_RF_as4:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s2
-; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], v0
-; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
-  %addr = load ptr addrspace(4), ptr addrspace(4) %in
-  %data = load i32, ptr addrspace(4) %in2
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v4, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[4:5]
+; VI-NEXT:    flat_load_dword v2, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v[0:1], v2
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(4), ptr %in
+  %data = load i32, ptr %in2
   call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(4) elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_v_m_constraint(ptr %in, ptr %in2) {
-; VI-LABEL: flat_store_v_m_constraint:
+define void @flat_store_RF_as5(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_RF_as5:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s0
-; VI-NEXT:    v_mov_b32_e32 v1, s1
-; VI-NEXT:    v_mov_b32_e32 v2, s2
-; VI-NEXT:    v_mov_b32_e32 v3, s3
-; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v0, v1
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(5), ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*^RF,v"(ptr addrspace(5) elementtype(i32) %addr, i32 %data)
+  ret void
+}
+
+define void @flat_store_m_constraint(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_m_constraint:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v4, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[4:5]
 ; VI-NEXT:    flat_load_dword v2, v[2:3]
 ; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
 ; VI-NEXT:    ;;#ASMSTART
 ; VI-NEXT:    flat_store_dword v[0:1], v2
 ; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
+; VI-NEXT:    s_setpc_b64 s[30:31]
   %addr = load ptr, ptr %in
   %data = load i32, ptr %in2
   call void asm "flat_store_dword $0, $1", "=*m,v"(ptr elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_v_m_constraint_as1(ptr addrspace(1) %in, ptr addrspace(1) %in2) {
-; VI-LABEL: flat_store_v_m_constraint_as1:
+define void @flat_store_m_constraint_as1(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_m_constraint_as1:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s2
-; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], v0
-; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
-  %addr = load ptr addrspace(1), ptr addrspace(1) %in
-  %data = load i32, ptr addrspace(1) %in2
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v4, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[4:5]
+; VI-NEXT:    flat_load_dword v2, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v[0:1], v2
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(1), ptr %in
+  %data = load i32, ptr %in2
   call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(1) elementtype(i32) %addr, i32 %data)
   ret void
 }
 
-define amdgpu_kernel void @flat_store_v_m_constraint_as4(ptr addrspace(4) %in, ptr addrspace(4) %in2) {
-; VI-LABEL: flat_store_v_m_constraint_as4:
+define void @flat_store_m_constraint_as2(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_m_constraint_as2:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v0, v1
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(2), ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(2) elementtype(i32) %addr, i32 %data)
+  ret void
+}
+
+define void @flat_store_m_constraint_as3(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_m_constraint_as3:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v0, v1
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(3), ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(3) elementtype(i32) %addr, i32 %data)
+  ret void
+}
+
+define void @flat_store_m_constraint_as4(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_m_constraint_as4:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x24
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    s_load_dword s2, s[2:3], 0x0
-; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
-; VI-NEXT:    s_waitcnt lgkmcnt(0)
-; VI-NEXT:    v_mov_b32_e32 v0, s2
-; VI-NEXT:    ;;#ASMSTART
-; VI-NEXT:    flat_store_dword s[0:1], v0
-; VI-NEXT:    ;;#ASMEND
-; VI-NEXT:    s_endpgm
-  %addr = load ptr addrspace(4), ptr addrspace(4) %in
-  %data = load i32, ptr addrspace(4) %in2
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    v_add_u32_e32 v4, vcc, 4, v0
+; VI-NEXT:    v_addc_u32_e32 v5, vcc, 0, v1, vcc
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[4:5]
+; VI-NEXT:    flat_load_dword v2, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v[0:1], v2
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(4), ptr %in
+  %data = load i32, ptr %in2
   call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(4) elementtype(i32) %addr, i32 %data)
   ret void
 }
+
+define void @flat_store_m_constraint_as5(ptr %in, ptr %in2) {
+; VI-LABEL: flat_store_m_constraint_as5:
+; VI:       ; %bb.0:
+; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT:    flat_load_dword v0, v[0:1]
+; VI-NEXT:    flat_load_dword v1, v[2:3]
+; VI-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; VI-NEXT:    ;;#ASMSTART
+; VI-NEXT:    flat_store_dword v0, v1
+; VI-NEXT:    ;;#ASMEND
+; VI-NEXT:    s_setpc_b64 s[30:31]
+  %addr = load ptr addrspace(5), ptr %in
+  %data = load i32, ptr %in2
+  call void asm "flat_store_dword $0, $1", "=*m,v"(ptr addrspace(5) elementtype(i32) %addr, i32 %data)
+  ret void
+}
+

>From 928a9294768712b6c175bca003a9f76539e36d14 Mon Sep 17 00:00:00 2001
From: Jun Wang <jwang86 at yahoo.com>
Date: Thu, 11 Jun 2026 11:47:42 -0700
Subject: [PATCH 5/6] Use dyn_cast

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index ca41e7247a7fb..a3d686f7539f8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10660,8 +10660,10 @@ static bool prepareDAGLevelOperands(ConstraintDecisionInfo &Info,
                "Operand must be indirect to be a mem!");
         unsigned AddrSpace = 0;
         const Value *Ptr = OpInfo.CallOperandVal;
-        if (Ptr && Ptr->getType()->getTypeID() == Type::PointerTyID)
-          AddrSpace = cast<PointerType>(Ptr->getType())->getAddressSpace();
+        if (Ptr) {
+          if (auto *Pt = dyn_cast<PointerType>(Ptr->getType()))
+            AddrSpace = Pt->getAddressSpace();
+        }
 
         assert(InOperandVal.getValueType() ==
                    TLI.getPointerTy(DAG.getDataLayout(), AddrSpace) &&

>From 70d7cd899dd15bfcbffda5e1641ff0a1b26b5925 Mon Sep 17 00:00:00 2001
From: Jun Wang <jwang86 at yahoo.com>
Date: Fri, 17 Jul 2026 15:49:27 -0700
Subject: [PATCH 6/6] Minor code/test changes

---
 .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp    | 13 ++++++-------
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp         |  2 --
 llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll  |  2 +-
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index a3d686f7539f8..307e394c3155b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10658,15 +10658,14 @@ static bool prepareDAGLevelOperands(ConstraintDecisionInfo &Info,
         assert((OpInfo.isIndirect ||
                 OpInfo.ConstraintType != TargetLowering::C_Memory) &&
                "Operand must be indirect to be a mem!");
-        unsigned AddrSpace = 0;
-        const Value *Ptr = OpInfo.CallOperandVal;
-        if (Ptr) {
-          if (auto *Pt = dyn_cast<PointerType>(Ptr->getType()))
-            AddrSpace = Pt->getAddressSpace();
-        }
 
         assert(InOperandVal.getValueType() ==
-                   TLI.getPointerTy(DAG.getDataLayout(), AddrSpace) &&
+                   TLI.getPointerTy(DAG.getDataLayout(),
+                                    OpInfo.CallOperandVal
+                                        ? dyn_cast<PointerType>(
+                                              OpInfo.CallOperandVal->getType())
+                                              ->getAddressSpace()
+                                        : 0) &&
                "Memory operands expect pointer values");
 
         const InlineAsm::ConstraintCode ConstraintID =
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 19239095392d1..c579505f47b51 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -1945,8 +1945,6 @@ bool AMDGPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
                                              const char *ExtraCode,
                                              raw_ostream &OS) {
   const MachineOperand &MO = MI->getOperand(OpNo);
-  if (!MO.isReg())
-    return true;
   AMDGPUInstPrinter::printRegOperand(MO.getReg(), OS,
                                      *MF->getSubtarget().getRegisterInfo());
   return false;
diff --git a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
index ef7f889e8b943..8177b442d752e 100644
--- a/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
+++ b/llvm/test/CodeGen/AMDGPU/inline-mem-constraints.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 
-; RUN: llc -mtriple=amdgcn -mcpu=tonga < %s | FileCheck --check-prefix=VI %s
+; RUN: llc -mtriple=amdgpu8.02 < %s | FileCheck --check-prefix=VI %s
 
 define void @flat_load_RF(ptr %in) {
 ; VI-LABEL: flat_load_RF:



More information about the llvm-commits mailing list