[llvm] [RISCV][GISEL] Legalize G_VAARG through expansion. (PR #73065)

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 4 16:29:25 PST 2023


https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/73065

>From da4cd70000ef074fceb5c59e6520a16aefd55107 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Fri, 17 Nov 2023 07:27:37 -0800
Subject: [PATCH 1/9] [RISCV][GISEL] Legalize G_VAARG through expansion.

G_VAARG can be expanded similiar to SelectionDAG::expandVAArg through
LegalizerHelper::lower. This patch implements the lowering through this
style of expansion.

The expansion gets the head of the va_list by loading the pointer to
va_list. Then, the head of the list is adjusted depending on argument
alignment information. This gives a pointer to the element to be read
out of the va_list. Next, the head of the va_list is bumped to the
next element in the list. The new head of the list is stored back to the
original pointer to the head of the va_list so that subsequent G_VAARG
instructions get the next element in the list. Lastly, the element is
loaded from the alignment adjusted pointer constructed earlier.
---
 .../llvm/CodeGen/GlobalISel/LegalizerHelper.h |  1 +
 .../CodeGen/GlobalISel/LegalizerHelper.cpp    | 67 +++++++++++++++++++
 .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp |  5 ++
 .../legalizer/legalize-vaarg-rv32.mir         | 40 +++++++++++
 .../legalizer/legalize-vaarg-rv64.mir         | 40 +++++++++++
 5 files changed, 153 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 86d3cb2bedb95..350c91ad6fa4f 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -430,6 +430,7 @@ class LegalizerHelper {
   LegalizeResult lowerVectorReduction(MachineInstr &MI);
   LegalizeResult lowerMemcpyInline(MachineInstr &MI);
   LegalizeResult lowerMemCpyFamily(MachineInstr &MI, unsigned MaxLen = 0);
+  LegalizeResult lowerVAArg(MachineInstr &MI);
 };
 
 /// Helper function that creates a libcall to the given \p Name using the given
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 3fa659eff652a..c57751fd1ac30 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -3783,6 +3783,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
     return lowerTRUNC(MI);
   GISEL_VECREDUCE_CASES_NONSEQ
     return lowerVectorReduction(MI);
+  case G_VAARG:
+    return lowerVAArg(MI);
   }
 }
 
@@ -7868,6 +7870,71 @@ LegalizerHelper::lowerVectorReduction(MachineInstr &MI) {
   return UnableToLegalize;
 }
 
+static Type *getTypeForLLT(LLT Ty, LLVMContext &C);
+
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
+  Observer.changingInstr(MI);
+  MachineFunction &MF = *MI.getMF();
+  const DataLayout &DL = MIRBuilder.getDataLayout();
+  LLVMContext &Ctx = MF.getFunction().getContext();
+  Register ListPtr = MI.getOperand(1).getReg();
+  LLT PtrTy = MRI.getType(ListPtr);
+
+  // LstPtr is a pointer to the head of the list. Get the address
+  // of the head of the list.
+  Align PtrAlignment = Align(DL.getABITypeAlign(getTypeForLLT(PtrTy, Ctx)));
+  MachineMemOperand *PtrLoadMMO =
+      MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
+                              MachineMemOperand::MOLoad, PtrTy, PtrAlignment);
+  Register HeadOfList = MRI.createGenericVirtualRegister(PtrTy);
+  Register VAList =
+      MIRBuilder.buildLoad(HeadOfList, ListPtr, *PtrLoadMMO).getReg(0);
+
+  const MaybeAlign MA(MI.getOperand(2).getImm());
+  LLT PtrTyAsScalarTy = LLT::scalar(PtrTy.getSizeInBits());
+  if (MA && *MA > TLI.getMinStackArgumentAlignment()) {
+    Register AlignAmt =
+        MIRBuilder.buildConstant(PtrTyAsScalarTy, MA->value() - 1).getReg(0);
+    Register AddDst = MRI.createGenericVirtualRegister(PtrTy);
+    MIRBuilder.buildPtrAdd(AddDst, HeadOfList, AlignAmt);
+    Register Mask =
+        MIRBuilder.buildConstant(PtrTyAsScalarTy, -(int64_t)MA->value())
+            .getReg(0);
+    Register AndDst = MRI.createGenericVirtualRegister(PtrTy);
+    VAList = MIRBuilder.buildPtrMask(AndDst, AddDst, Mask).getReg(0);
+  }
+
+  // Increment the pointer, VAList, to the next vaarg
+  // The list should be bumped by the size of element in the current head of
+  // list.
+  Register Dst = MI.getOperand(0).getReg();
+  LLT Ty = MRI.getType(Dst);
+  Register IncAmt =
+      MIRBuilder
+          .buildConstant(PtrTyAsScalarTy,
+                         DL.getTypeAllocSize(getTypeForLLT(Ty, Ctx)))
+          .getReg(0);
+  Register Succ = MRI.createGenericVirtualRegister(PtrTy);
+  MIRBuilder.buildPtrAdd(Succ, VAList, IncAmt);
+
+  // Store the increment VAList to the legalized pointer
+  MachineMemOperand *StoreMMO =
+      MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
+                              MachineMemOperand::MOStore, PtrTy, PtrAlignment);
+  MIRBuilder.buildStore(Succ, ListPtr, *StoreMMO);
+  // Load the actual argument out of the pointer VAList
+  Align EltAlignment = Align(DL.getABITypeAlign(getTypeForLLT(Ty, Ctx)));
+  MachineMemOperand *EltLoadMMO =
+      MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
+                              MachineMemOperand::MOLoad, Ty, EltAlignment);
+  MIRBuilder.buildLoad(Dst, VAList, *EltLoadMMO);
+
+  Observer.changedInstr(MI);
+  Observer.erasingInstr(MI);
+  MI.eraseFromParent();
+  return Legalized;
+}
+
 static bool shouldLowerMemFuncForSize(const MachineFunction &MF) {
   // On Darwin, -Os means optimize for size without hurting performance, so
   // only really optimize for size when -Oz (MinSize) is used.
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 9564ed9c41874..78308c0a7d066 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -303,6 +303,11 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
 
   getActionDefinitionsBuilder(G_VASTART).customFor({p0});
 
+  // va_list must be a pointer, but most sized types are pretty easy to handle
+  // as the destination.
+  getActionDefinitionsBuilder(G_VAARG).lowerForCartesianProduct(
+      {s8, s16, s32, s64, p0}, {p0});
+
   getLegacyLegalizerInfo().computeTables();
 }
 
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
new file mode 100644
index 0000000000000..4876e0d5ee96b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
@@ -0,0 +1,40 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer %s -o - | FileCheck %s
+
+# On RISC-V, the MinStackArgumentAlignment is 1 and the ABI Alignment for p0 is
+# greater than 1, so we will always generate code to adjust for this alignment.
+
+--- |
+  define void @va_arg() {
+    %va = alloca ptr, align 4
+    %1 = va_arg ptr %va, i32
+    ret void
+  }
+...
+---
+name:            va_arg
+legalized:       false
+tracksRegLiveness: true
+stack:
+  - { id: 0, name: va, type: default, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1 (%ir-block.0):
+    ; CHECK-LABEL: name: va_arg
+    ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -4
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[PTR_ADD]](p0)
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[PTRTOINT]], [[C1]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s32)
+    ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s32)
+    ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
+    ; CHECK-NEXT: PseudoRET
+    %0:_(p0) = G_FRAME_INDEX %stack.0.va
+    %1:_(s32) = G_VAARG %0(p0), 4
+    PseudoRET
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
new file mode 100644
index 0000000000000..c32f590479c7a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
@@ -0,0 +1,40 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer %s -o - | FileCheck %s
+
+# On RISC-V, the MinStackArgumentAlignment is 1 and the ABI Alignment for p0 is
+# greater than 1, so we will always generate code to adjust for this alignment.
+
+--- |
+  define void @va_arg() {
+    %va = alloca ptr, align 8
+    %1 = va_arg ptr %va, i32
+    ret void
+  }
+...
+---
+name:            va_arg
+legalized:       false
+tracksRegLiveness: true
+stack:
+  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1 (%ir-block.0):
+    ; CHECK-LABEL: name: va_arg
+    ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s64)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -4
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR_ADD]](p0)
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]], [[C1]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s64)
+    ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s64)
+    ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
+    ; CHECK-NEXT: PseudoRET
+    %0:_(p0) = G_FRAME_INDEX %stack.0.va
+    %1:_(s32) = G_VAARG %0(p0), 4
+    PseudoRET
+...

>From 04f5f01a63ace6783cb515982588d443c0ffbefc Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 27 Nov 2023 17:20:00 -0800
Subject: [PATCH 2/9] !fixup pass Ty to builder; remove Align constructor; use
 buildMaskLowPtrBits

---
 .../CodeGen/GlobalISel/LegalizerHelper.cpp    | 21 +++++++------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index c57751fd1ac30..ee3cc5027664c 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7886,22 +7886,18 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
   MachineMemOperand *PtrLoadMMO =
       MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
                               MachineMemOperand::MOLoad, PtrTy, PtrAlignment);
-  Register HeadOfList = MRI.createGenericVirtualRegister(PtrTy);
-  Register VAList =
-      MIRBuilder.buildLoad(HeadOfList, ListPtr, *PtrLoadMMO).getReg(0);
+  auto HeadOfList = MIRBuilder.buildLoad(PtrTy, ListPtr, *PtrLoadMMO).getReg(0);
+  Register VAList = HeadOfList;
 
   const MaybeAlign MA(MI.getOperand(2).getImm());
   LLT PtrTyAsScalarTy = LLT::scalar(PtrTy.getSizeInBits());
   if (MA && *MA > TLI.getMinStackArgumentAlignment()) {
     Register AlignAmt =
         MIRBuilder.buildConstant(PtrTyAsScalarTy, MA->value() - 1).getReg(0);
-    Register AddDst = MRI.createGenericVirtualRegister(PtrTy);
-    MIRBuilder.buildPtrAdd(AddDst, HeadOfList, AlignAmt);
-    Register Mask =
-        MIRBuilder.buildConstant(PtrTyAsScalarTy, -(int64_t)MA->value())
-            .getReg(0);
-    Register AndDst = MRI.createGenericVirtualRegister(PtrTy);
-    VAList = MIRBuilder.buildPtrMask(AndDst, AddDst, Mask).getReg(0);
+    auto AddDst = MIRBuilder.buildPtrAdd(PtrTy, HeadOfList, AlignAmt);
+    auto AndDst =
+        MIRBuilder.buildMaskLowPtrBits(PtrTy, AddDst, Log2(*MA));
+    VAList = AndDst.getReg(0);
   }
 
   // Increment the pointer, VAList, to the next vaarg
@@ -7914,8 +7910,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
           .buildConstant(PtrTyAsScalarTy,
                          DL.getTypeAllocSize(getTypeForLLT(Ty, Ctx)))
           .getReg(0);
-  Register Succ = MRI.createGenericVirtualRegister(PtrTy);
-  MIRBuilder.buildPtrAdd(Succ, VAList, IncAmt);
+  auto Succ = MIRBuilder.buildPtrAdd(PtrTy, VAList, IncAmt);
 
   // Store the increment VAList to the legalized pointer
   MachineMemOperand *StoreMMO =
@@ -7923,7 +7918,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
                               MachineMemOperand::MOStore, PtrTy, PtrAlignment);
   MIRBuilder.buildStore(Succ, ListPtr, *StoreMMO);
   // Load the actual argument out of the pointer VAList
-  Align EltAlignment = Align(DL.getABITypeAlign(getTypeForLLT(Ty, Ctx)));
+  Align EltAlignment = DL.getABITypeAlign(getTypeForLLT(Ty, Ctx));
   MachineMemOperand *EltLoadMMO =
       MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
                               MachineMemOperand::MOLoad, Ty, EltAlignment);

>From 4c122b9dd3c72d9814395544d330dd3da5430997 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 27 Nov 2023 17:25:22 -0800
Subject: [PATCH 3/9] !fixup clangformat

---
 llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index ee3cc5027664c..d8ced2678400a 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7895,8 +7895,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
     Register AlignAmt =
         MIRBuilder.buildConstant(PtrTyAsScalarTy, MA->value() - 1).getReg(0);
     auto AddDst = MIRBuilder.buildPtrAdd(PtrTy, HeadOfList, AlignAmt);
-    auto AndDst =
-        MIRBuilder.buildMaskLowPtrBits(PtrTy, AddDst, Log2(*MA));
+    auto AndDst = MIRBuilder.buildMaskLowPtrBits(PtrTy, AddDst, Log2(*MA));
     VAList = AndDst.getReg(0);
   }
 

>From 1544292bbf74baeb1a89fe151cd499bfda1556bb Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 27 Nov 2023 17:44:03 -0800
Subject: [PATCH 4/9] !fixup use Align instead of MaybeAlign

---
 llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index d8ced2678400a..69eda673dd110 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7889,13 +7889,13 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
   auto HeadOfList = MIRBuilder.buildLoad(PtrTy, ListPtr, *PtrLoadMMO).getReg(0);
   Register VAList = HeadOfList;
 
-  const MaybeAlign MA(MI.getOperand(2).getImm());
+  const Align A(MI.getOperand(2).getImm());
   LLT PtrTyAsScalarTy = LLT::scalar(PtrTy.getSizeInBits());
-  if (MA && *MA > TLI.getMinStackArgumentAlignment()) {
+  if (A > TLI.getMinStackArgumentAlignment()) {
     Register AlignAmt =
-        MIRBuilder.buildConstant(PtrTyAsScalarTy, MA->value() - 1).getReg(0);
+        MIRBuilder.buildConstant(PtrTyAsScalarTy, A.value() - 1).getReg(0);
     auto AddDst = MIRBuilder.buildPtrAdd(PtrTy, HeadOfList, AlignAmt);
-    auto AndDst = MIRBuilder.buildMaskLowPtrBits(PtrTy, AddDst, Log2(*MA));
+    auto AndDst = MIRBuilder.buildMaskLowPtrBits(PtrTy, AddDst, Log2(A));
     VAList = AndDst.getReg(0);
   }
 

>From 945f7792de0036d53e2dc91b53d47f9ed3dfb71b Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Wed, 29 Nov 2023 13:29:42 -0800
Subject: [PATCH 5/9] !fixup clamp scalar

---
 .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp |  7 +-
 .../legalizer/legalize-vaarg-rv32.mir         | 38 +++++++++-
 .../legalizer/legalize-vaarg-rv64.mir         | 70 ++++++++++++++++++-
 3 files changed, 107 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 78308c0a7d066..bf40894f0924f 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -305,8 +305,11 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
 
   // va_list must be a pointer, but most sized types are pretty easy to handle
   // as the destination.
-  getActionDefinitionsBuilder(G_VAARG).lowerForCartesianProduct(
-      {s8, s16, s32, s64, p0}, {p0});
+  getActionDefinitionsBuilder(G_VAARG)
+      // TODO: Implement narrowScalar and widenScalar for G_VAARG for types
+      // outside the [s32, sXLen] range.
+      .clampScalar(0, s32, sXLen)
+      .lowerForCartesianProduct({s32, sXLen, p0}, {p0});
 
   getLegacyLegalizerInfo().computeTables();
 }
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
index 4876e0d5ee96b..ff10a2b242c2b 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
@@ -5,14 +5,19 @@
 # greater than 1, so we will always generate code to adjust for this alignment.
 
 --- |
-  define void @va_arg() {
+  define void @va_arg_i32() {
     %va = alloca ptr, align 4
     %1 = va_arg ptr %va, i32
     ret void
   }
+  define void @va_arg_ptr() {
+    %va = alloca ptr, align 4
+    %1 = va_arg ptr %va, ptr
+    ret void
+  }
 ...
 ---
-name:            va_arg
+name:            va_arg_i32
 legalized:       false
 tracksRegLiveness: true
 stack:
@@ -21,7 +26,7 @@ stack:
       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
 body:             |
   bb.1 (%ir-block.0):
-    ; CHECK-LABEL: name: va_arg
+    ; CHECK-LABEL: name: va_arg_i32
     ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
     ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
@@ -38,3 +43,30 @@ body:             |
     %1:_(s32) = G_VAARG %0(p0), 4
     PseudoRET
 ...
+---
+name:            va_arg_ptr
+legalized:       false
+tracksRegLiveness: true
+stack:
+  - { id: 0, name: va, type: default, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1 (%ir-block.0):
+    ; CHECK-LABEL: name: va_arg_ptr
+    ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -4
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[PTR_ADD]](p0)
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[PTRTOINT]], [[C1]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s32)
+    ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s32)
+    ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
+    ; CHECK-NEXT: PseudoRET
+    %0:_(p0) = G_FRAME_INDEX %stack.0.va
+    %1:_(p0) = G_VAARG %0(p0), 4
+    PseudoRET
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
index c32f590479c7a..74e455513fa29 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
@@ -5,14 +5,24 @@
 # greater than 1, so we will always generate code to adjust for this alignment.
 
 --- |
-  define void @va_arg() {
+  define void @va_arg_i32() {
     %va = alloca ptr, align 8
     %1 = va_arg ptr %va, i32
     ret void
   }
+  define void @va_arg_i64() {
+    %va = alloca ptr, align 8
+    %1 = va_arg ptr %va, i32
+    ret void
+  }
+  define void @va_arg_ptr() {
+    %va = alloca ptr, align 8
+    %1 = va_arg ptr %va, ptr
+    ret void
+  }
 ...
 ---
-name:            va_arg
+name:            va_arg_i32
 legalized:       false
 tracksRegLiveness: true
 stack:
@@ -21,7 +31,7 @@ stack:
       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
 body:             |
   bb.1 (%ir-block.0):
-    ; CHECK-LABEL: name: va_arg
+    ; CHECK-LABEL: name: va_arg_i32
     ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
     ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
@@ -38,3 +48,57 @@ body:             |
     %1:_(s32) = G_VAARG %0(p0), 4
     PseudoRET
 ...
+---
+name:            va_arg_i64
+legalized:       false
+tracksRegLiveness: true
+stack:
+  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1 (%ir-block.0):
+    ; CHECK-LABEL: name: va_arg_i64
+    ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s64)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -4
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR_ADD]](p0)
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]], [[C1]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s64)
+    ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s64)
+    ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
+    ; CHECK-NEXT: PseudoRET
+    %0:_(p0) = G_FRAME_INDEX %stack.0.va
+    %1:_(s64) = G_VAARG %0(p0), 4
+    PseudoRET
+...
+---
+name:            va_arg_ptr
+legalized:       false
+tracksRegLiveness: true
+stack:
+  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1 (%ir-block.0):
+    ; CHECK-LABEL: name: va_arg_ptr
+    ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s64)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -4
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR_ADD]](p0)
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]], [[C1]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s64)
+    ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s64)
+    ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
+    ; CHECK-NEXT: PseudoRET
+    %0:_(p0) = G_FRAME_INDEX %stack.0.va
+    %1:_(s64) = G_VAARG %0(p0), 4
+    PseudoRET
+...

>From 0e74d27d121e84b7d58f3c9f7b0e877431513075 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Thu, 30 Nov 2023 09:34:04 -0800
Subject: [PATCH 6/9] !fixup remove observer call; remove HeadOfList

---
 llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 69eda673dd110..88b4ad3a03951 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7886,8 +7886,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
   MachineMemOperand *PtrLoadMMO =
       MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
                               MachineMemOperand::MOLoad, PtrTy, PtrAlignment);
-  auto HeadOfList = MIRBuilder.buildLoad(PtrTy, ListPtr, *PtrLoadMMO).getReg(0);
-  Register VAList = HeadOfList;
+  auto VAList = MIRBuilder.buildLoad(PtrTy, ListPtr, *PtrLoadMMO).getReg(0);
 
   const Align A(MI.getOperand(2).getImm());
   LLT PtrTyAsScalarTy = LLT::scalar(PtrTy.getSizeInBits());
@@ -7923,7 +7922,6 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
                               MachineMemOperand::MOLoad, Ty, EltAlignment);
   MIRBuilder.buildLoad(Dst, VAList, *EltLoadMMO);
 
-  Observer.changedInstr(MI);
   Observer.erasingInstr(MI);
   MI.eraseFromParent();
   return Legalized;

>From d8c7063c8b35b48dc75df94d7522cd7ad13a53ac Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Fri, 1 Dec 2023 10:18:34 -0800
Subject: [PATCH 7/9] !fixup cleanup

---
 llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 88b4ad3a03951..b0e6f0d901abb 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7873,7 +7873,6 @@ LegalizerHelper::lowerVectorReduction(MachineInstr &MI) {
 static Type *getTypeForLLT(LLT Ty, LLVMContext &C);
 
 LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
-  Observer.changingInstr(MI);
   MachineFunction &MF = *MI.getMF();
   const DataLayout &DL = MIRBuilder.getDataLayout();
   LLVMContext &Ctx = MF.getFunction().getContext();
@@ -7882,7 +7881,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
 
   // LstPtr is a pointer to the head of the list. Get the address
   // of the head of the list.
-  Align PtrAlignment = Align(DL.getABITypeAlign(getTypeForLLT(PtrTy, Ctx)));
+  Align PtrAlignment = DL.getABITypeAlign(getTypeForLLT(PtrTy, Ctx));
   MachineMemOperand *PtrLoadMMO =
       MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
                               MachineMemOperand::MOLoad, PtrTy, PtrAlignment);
@@ -7893,7 +7892,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
   if (A > TLI.getMinStackArgumentAlignment()) {
     Register AlignAmt =
         MIRBuilder.buildConstant(PtrTyAsScalarTy, A.value() - 1).getReg(0);
-    auto AddDst = MIRBuilder.buildPtrAdd(PtrTy, HeadOfList, AlignAmt);
+    auto AddDst = MIRBuilder.buildPtrAdd(PtrTy, VAList, AlignAmt);
     auto AndDst = MIRBuilder.buildMaskLowPtrBits(PtrTy, AddDst, Log2(A));
     VAList = AndDst.getReg(0);
   }
@@ -7903,11 +7902,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
   // list.
   Register Dst = MI.getOperand(0).getReg();
   LLT Ty = MRI.getType(Dst);
-  Register IncAmt =
-      MIRBuilder
-          .buildConstant(PtrTyAsScalarTy,
-                         DL.getTypeAllocSize(getTypeForLLT(Ty, Ctx)))
-          .getReg(0);
+  auto IncAmt = MIRBuilder.buildConstant(
+      PtrTyAsScalarTy, DL.getTypeAllocSize(getTypeForLLT(Ty, Ctx)));
   auto Succ = MIRBuilder.buildPtrAdd(PtrTy, VAList, IncAmt);
 
   // Store the increment VAList to the legalized pointer

>From d1f8967b1a3bd7277752a5885b69a649d19aa60c Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 4 Dec 2023 15:36:26 -0800
Subject: [PATCH 8/9] !fixup rebase

---
 .../legalizer/legalize-vaarg-rv32.mir          | 12 ++++--------
 .../legalizer/legalize-vaarg-rv64.mir          | 18 ++++++------------
 2 files changed, 10 insertions(+), 20 deletions(-)

diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
index ff10a2b242c2b..6a81809727fbb 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
@@ -32,11 +32,9 @@ body:             |
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
     ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
     ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -4
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[PTR_ADD]](p0)
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[PTRTOINT]], [[C1]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s32)
+    ; CHECK-NEXT: [[PTRMASK:%[0-9]+]]:_(p0) = G_PTRMASK [[PTR_ADD]], [[C1]](s32)
     ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
-    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s32)
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[PTRMASK]], [[C2]](s32)
     ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
     ; CHECK-NEXT: PseudoRET
     %0:_(p0) = G_FRAME_INDEX %stack.0.va
@@ -59,11 +57,9 @@ body:             |
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
     ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
     ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -4
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[PTR_ADD]](p0)
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[PTRTOINT]], [[C1]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s32)
+    ; CHECK-NEXT: [[PTRMASK:%[0-9]+]]:_(p0) = G_PTRMASK [[PTR_ADD]], [[C1]](s32)
     ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
-    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s32)
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[PTRMASK]], [[C2]](s32)
     ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
     ; CHECK-NEXT: PseudoRET
     %0:_(p0) = G_FRAME_INDEX %stack.0.va
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
index 74e455513fa29..4fad4b8747a51 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
@@ -37,11 +37,9 @@ body:             |
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
     ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s64)
     ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -4
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR_ADD]](p0)
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]], [[C1]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s64)
+    ; CHECK-NEXT: [[PTRMASK:%[0-9]+]]:_(p0) = G_PTRMASK [[PTR_ADD]], [[C1]](s64)
     ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
-    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s64)
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[PTRMASK]], [[C2]](s64)
     ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
     ; CHECK-NEXT: PseudoRET
     %0:_(p0) = G_FRAME_INDEX %stack.0.va
@@ -64,11 +62,9 @@ body:             |
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
     ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s64)
     ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -4
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR_ADD]](p0)
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]], [[C1]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s64)
+    ; CHECK-NEXT: [[PTRMASK:%[0-9]+]]:_(p0) = G_PTRMASK [[PTR_ADD]], [[C1]](s64)
     ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
-    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s64)
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[PTRMASK]], [[C2]](s64)
     ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
     ; CHECK-NEXT: PseudoRET
     %0:_(p0) = G_FRAME_INDEX %stack.0.va
@@ -91,11 +87,9 @@ body:             |
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
     ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s64)
     ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -4
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR_ADD]](p0)
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]], [[C1]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s64)
+    ; CHECK-NEXT: [[PTRMASK:%[0-9]+]]:_(p0) = G_PTRMASK [[PTR_ADD]], [[C1]](s64)
     ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
-    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[INTTOPTR]], [[C2]](s64)
+    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[PTRMASK]], [[C2]](s64)
     ; CHECK-NEXT: G_STORE [[PTR_ADD1]](p0), [[FRAME_INDEX]](p0) :: (store (p0))
     ; CHECK-NEXT: PseudoRET
     %0:_(p0) = G_FRAME_INDEX %stack.0.va

>From ac7697dae0856bcd17601396d1a685c4a505b73e Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 4 Dec 2023 16:19:07 -0800
Subject: [PATCH 9/9] !fixup fix MMO and remove observer call

---
 .../CodeGen/GlobalISel/LegalizerHelper.cpp    | 16 +++----
 .../legalizer/legalize-vaarg-rv32.mir         | 42 ++++++++++------
 .../legalizer/legalize-vaarg-rv64.mir         | 48 ++++++++++++-------
 3 files changed, 64 insertions(+), 42 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index b0e6f0d901abb..d0b0d9f93ef7f 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7882,9 +7882,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
   // LstPtr is a pointer to the head of the list. Get the address
   // of the head of the list.
   Align PtrAlignment = DL.getABITypeAlign(getTypeForLLT(PtrTy, Ctx));
-  MachineMemOperand *PtrLoadMMO =
-      MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
-                              MachineMemOperand::MOLoad, PtrTy, PtrAlignment);
+  MachineMemOperand *PtrLoadMMO = MF.getMachineMemOperand(
+      MachinePointerInfo(), MachineMemOperand::MOLoad, PtrTy, PtrAlignment);
   auto VAList = MIRBuilder.buildLoad(PtrTy, ListPtr, *PtrLoadMMO).getReg(0);
 
   const Align A(MI.getOperand(2).getImm());
@@ -7907,18 +7906,15 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
   auto Succ = MIRBuilder.buildPtrAdd(PtrTy, VAList, IncAmt);
 
   // Store the increment VAList to the legalized pointer
-  MachineMemOperand *StoreMMO =
-      MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
-                              MachineMemOperand::MOStore, PtrTy, PtrAlignment);
+  MachineMemOperand *StoreMMO = MF.getMachineMemOperand(
+      MachinePointerInfo(), MachineMemOperand::MOStore, PtrTy, PtrAlignment);
   MIRBuilder.buildStore(Succ, ListPtr, *StoreMMO);
   // Load the actual argument out of the pointer VAList
   Align EltAlignment = DL.getABITypeAlign(getTypeForLLT(Ty, Ctx));
-  MachineMemOperand *EltLoadMMO =
-      MF.getMachineMemOperand(MachinePointerInfo::getUnknownStack(MF),
-                              MachineMemOperand::MOLoad, Ty, EltAlignment);
+  MachineMemOperand *EltLoadMMO = MF.getMachineMemOperand(
+      MachinePointerInfo(), MachineMemOperand::MOLoad, Ty, EltAlignment);
   MIRBuilder.buildLoad(Dst, VAList, *EltLoadMMO);
 
-  Observer.erasingInstr(MI);
   MI.eraseFromParent();
   return Legalized;
 }
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
index 6a81809727fbb..d94e841509248 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv32.mir
@@ -5,14 +5,14 @@
 # greater than 1, so we will always generate code to adjust for this alignment.
 
 --- |
-  define void @va_arg_i32() {
+  define void @va_arg_i32(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4, ptr %5, ptr %6, ptr %7, ...) {
     %va = alloca ptr, align 4
-    %1 = va_arg ptr %va, i32
+    %p = va_arg ptr %va, i32
     ret void
   }
-  define void @va_arg_ptr() {
+  define void @va_arg_ptr(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4, ptr %5, ptr %6, ptr %7, ...) {
     %va = alloca ptr, align 4
-    %1 = va_arg ptr %va, ptr
+    %p = va_arg ptr %va, ptr
     ret void
   }
 ...
@@ -20,14 +20,21 @@
 name:            va_arg_i32
 legalized:       false
 tracksRegLiveness: true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 4, alignment: 16,
+      isImmutable: true, isAliased: false }
 stack:
-  - { id: 0, name: va, type: default, offset: 0, size: 4, alignment: 4,
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 0, name: va, type: default, offset: 0, size: 4, alignment: 4 }
+machineFunctionInfo:
+  varArgsFrameIndex: -1
+  varArgsSaveSize: 0
 body:             |
-  bb.1 (%ir-block.0):
+  bb.1 (%ir-block.8):
+    liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
     ; CHECK-LABEL: name: va_arg_i32
-    ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
     ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
     ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
@@ -45,14 +52,21 @@ body:             |
 name:            va_arg_ptr
 legalized:       false
 tracksRegLiveness: true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 4, alignment: 16,
+      isImmutable: true, isAliased: false }
 stack:
-  - { id: 0, name: va, type: default, offset: 0, size: 4, alignment: 4,
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 0, name: va, type: default, offset: 0, size: 4, alignment: 4 }
+machineFunctionInfo:
+  varArgsFrameIndex: -1
+  varArgsSaveSize: 0
 body:             |
-  bb.1 (%ir-block.0):
+  bb.1 (%ir-block.8):
+    liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
     ; CHECK-LABEL: name: va_arg_ptr
-    ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
     ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
     ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
     ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[LOAD]], [[C]](s32)
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
index 4fad4b8747a51..9fcbfb0e96801 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vaarg-rv64.mir
@@ -5,19 +5,19 @@
 # greater than 1, so we will always generate code to adjust for this alignment.
 
 --- |
-  define void @va_arg_i32() {
+  define void @va_arg_i32(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4, ptr %5, ptr %6, ptr %7, ...) {
     %va = alloca ptr, align 8
-    %1 = va_arg ptr %va, i32
+    %p = va_arg ptr %va, i32
     ret void
   }
-  define void @va_arg_i64() {
+  define void @va_arg_i64(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4, ptr %5, ptr %6, ptr %7, ...) {
     %va = alloca ptr, align 8
-    %1 = va_arg ptr %va, i32
+    %p = va_arg ptr %va, i32
     ret void
   }
-  define void @va_arg_ptr() {
+  define void @va_arg_ptr(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4, ptr %5, ptr %6, ptr %7, ...) {
     %va = alloca ptr, align 8
-    %1 = va_arg ptr %va, ptr
+    %p = va_arg ptr %va, ptr
     ret void
   }
 ...
@@ -25,12 +25,16 @@
 name:            va_arg_i32
 legalized:       false
 tracksRegLiveness: true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 8, alignment: 16,
+      isImmutable: true, isAliased: false }
 stack:
-  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 4,
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 8 }
+machineFunctionInfo:
+  varArgsFrameIndex: -1
+  varArgsSaveSize: 0
 body:             |
-  bb.1 (%ir-block.0):
+  bb.1 (%ir-block.8):
     ; CHECK-LABEL: name: va_arg_i32
     ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
     ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
@@ -50,12 +54,16 @@ body:             |
 name:            va_arg_i64
 legalized:       false
 tracksRegLiveness: true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 8, alignment: 16,
+      isImmutable: true, isAliased: false }
 stack:
-  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 4,
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 8 }
+machineFunctionInfo:
+  varArgsFrameIndex: -1
+  varArgsSaveSize: 0
 body:             |
-  bb.1 (%ir-block.0):
+  bb.1 (%ir-block.8):
     ; CHECK-LABEL: name: va_arg_i64
     ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
     ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))
@@ -75,12 +83,16 @@ body:             |
 name:            va_arg_ptr
 legalized:       false
 tracksRegLiveness: true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 8, alignment: 16,
+      isImmutable: true, isAliased: false }
 stack:
-  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 4,
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 0, name: va, type: default, offset: 0, size: 8, alignment: 8 }
+machineFunctionInfo:
+  varArgsFrameIndex: -1
+  varArgsSaveSize: 0
 body:             |
-  bb.1 (%ir-block.0):
+  bb.1 (%ir-block.8):
     ; CHECK-LABEL: name: va_arg_ptr
     ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.va
     ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0))



More information about the llvm-commits mailing list