[llvm] [RISCV][GISEL] Legalize G_VAARG through expansion. (PR #73065)
Michael Maitland via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 09:34:29 PST 2023
https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/73065
>From 1138caa354beb5f57225e148adaca22ef7d83129 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Fri, 17 Nov 2023 07:37:47 -0800
Subject: [PATCH 1/8] [RISCV][GISEL] Legalize G_PTRMASK
G_PTRMASK is custom legalized by using G_PTRTOINT on the pointer, using a
G_AND to calculate the mask, and converted back to pointer using G_PTRTOINT.
---
.../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 23 ++++++++++++++++++
.../Target/RISCV/GISel/RISCVLegalizerInfo.h | 3 +++
.../legalizer/legalize-ptrmask-rv32.mir | 24 +++++++++++++++++++
.../legalizer/legalize-ptrmask-rv64.mir | 24 +++++++++++++++++++
4 files changed, 74 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv32.mir
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv64.mir
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 9eb5812e024b915..1c1c4ee6a9aed3a 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -147,6 +147,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
getActionDefinitionsBuilder(G_PTR_ADD).legalFor({{p0, sXLen}});
+ getActionDefinitionsBuilder(G_PTRMASK).customFor({{p0, sXLen}});
+
getActionDefinitionsBuilder(G_PTRTOINT)
.legalFor({{sXLen, p0}})
.clampScalar(0, sXLen, sXLen);
@@ -288,6 +290,25 @@ bool RISCVLegalizerInfo::legalizeShlAshrLshr(
return true;
}
+bool RISCVLegalizerInfo::legalizePtrMask(MachineInstr &MI,
+ MachineIRBuilder &MIRBuilder,
+ GISelChangeObserver &Observer) const {
+ assert(MI.getOpcode() == TargetOpcode::G_PTRMASK);
+
+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+ Register Tmp1 =
+ MRI.createGenericVirtualRegister(MRI.getType(MI.getOperand(2).getReg()));
+ Register Tmp2 =
+ MRI.createGenericVirtualRegister(MRI.getType(MI.getOperand(2).getReg()));
+ MIRBuilder.buildPtrToInt(Tmp1, MI.getOperand(1).getReg());
+ MIRBuilder.buildAnd(Tmp2, Tmp1, MI.getOperand(2).getReg());
+ MIRBuilder.buildIntToPtr(MI.getOperand(0).getReg(), Tmp2);
+
+ Observer.erasingInstr(MI);
+ MI.eraseFromParent();
+ return true;
+}
+
bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
MachineInstr &MI) const {
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
@@ -309,6 +330,8 @@ bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
return Helper.lower(MI, 0, /* Unused hint type */ LLT()) ==
LegalizerHelper::Legalized;
}
+ case TargetOpcode::G_PTRMASK:
+ return legalizePtrMask(MI, MIRBuilder, Observer);
}
llvm_unreachable("expected switch to return");
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
index f39d3a130d85063..ff2be0622023795 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
@@ -31,6 +31,9 @@ class RISCVLegalizerInfo : public LegalizerInfo {
private:
bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
GISelChangeObserver &Observer) const;
+
+ bool legalizePtrMask(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
+ GISelChangeObserver &Observer) const;
};
} // end namespace llvm
#endif
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv32.mir
new file mode 100644
index 000000000000000..af91461040047f8
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv32.mir
@@ -0,0 +1,24 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: ptrmask_p0_s32
+body: |
+ bb.0:
+ liveins: $x10, $x11
+ ; CHECK-LABEL: name: ptrmask_p0_s32
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY]](p0)
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[PTRTOINT]], [[COPY1]]
+ ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s32)
+ ; CHECK-NEXT: $x10 = COPY [[INTTOPTR]](p0)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:_(p0) = COPY $x10
+ %1:_(s32) = COPY $x11
+ %2:_(p0) = G_PTRMASK %0(p0), %1(s32)
+ $x10 = COPY %2(p0)
+ PseudoRET implicit $x10
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv64.mir
new file mode 100644
index 000000000000000..b7223c1e2ca2ea6
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-ptrmask-rv64.mir
@@ -0,0 +1,24 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: ptrmask_p0_s64
+body: |
+ bb.0:
+ liveins: $x10, $x11
+ ; CHECK-LABEL: name: ptrmask_p0_s64
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[COPY]](p0)
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]], [[COPY1]]
+ ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[AND]](s64)
+ ; CHECK-NEXT: $x10 = COPY [[INTTOPTR]](p0)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:_(p0) = COPY $x10
+ %1:_(s64) = COPY $x11
+ %2:_(p0) = G_PTRMASK %0(p0), %1(s64)
+ $x10 = COPY %2(p0)
+ PseudoRET implicit $x10
+...
>From 8e46f0fd5757955ee1286fb39fc96f334f9c0bb1 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 2/8] [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 86d3cb2bedb95b6..350c91ad6fa4f61 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 dd5577d47f97764..310b71dca37bf3c 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -3780,6 +3780,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);
}
}
@@ -7865,6 +7867,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 1c1c4ee6a9aed3a..e19231777eb335d 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -263,6 +263,11 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
getActionDefinitionsBuilder({G_FCEIL, G_FFLOOR})
.libcallFor({s32, s64});
+ // 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 000000000000000..4876e0d5ee96b2f
--- /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 000000000000000..c32f590479c7aa3
--- /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 4078504dba15d0edd80fbad168b1718f1ae58f92 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 3/8] !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 310b71dca37bf3c..542dba6b9fb9ae5 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7883,22 +7883,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
@@ -7911,8 +7907,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 =
@@ -7920,7 +7915,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 e08e699f9a94d07192fdaccd63a55a07fbe7c3ce 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 4/8] !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 542dba6b9fb9ae5..c6f0ade7641fa38 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7892,8 +7892,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 d2707e0497c74632fc8677c107dbbde4e9a24f03 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 5/8] !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 c6f0ade7641fa38..0039c4a85b23aa6 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7886,13 +7886,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 d5a50838e4475dadb9e73cc7ad39e04a8f35cc8b Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 27 Nov 2023 18:02:26 -0800
Subject: [PATCH 6/8] !fixup hide createVirtualRegister
---
llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index e19231777eb335d..84448183029719c 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -301,12 +301,9 @@ bool RISCVLegalizerInfo::legalizePtrMask(MachineInstr &MI,
assert(MI.getOpcode() == TargetOpcode::G_PTRMASK);
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
- Register Tmp1 =
- MRI.createGenericVirtualRegister(MRI.getType(MI.getOperand(2).getReg()));
- Register Tmp2 =
- MRI.createGenericVirtualRegister(MRI.getType(MI.getOperand(2).getReg()));
- MIRBuilder.buildPtrToInt(Tmp1, MI.getOperand(1).getReg());
- MIRBuilder.buildAnd(Tmp2, Tmp1, MI.getOperand(2).getReg());
+ LLT Ty = MRI.getType(MI.getOperand(2).getReg());
+ auto Tmp1 = MIRBuilder.buildPtrToInt(Ty, MI.getOperand(1).getReg());
+ auto Tmp2 = MIRBuilder.buildAnd(Ty, Tmp1, MI.getOperand(2).getReg());
MIRBuilder.buildIntToPtr(MI.getOperand(0).getReg(), Tmp2);
Observer.erasingInstr(MI);
>From a1ae6249d7596c0c5d4e50f9a1893093309312d7 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 7/8] !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 84448183029719c..b14d1bd908aa863 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -265,8 +265,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 4876e0d5ee96b2f..ff10a2b242c2bb3 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 c32f590479c7aa3..74e455513fa292f 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 f389096904e3b59dd27c5816e00ba8c491720b04 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 8/8] !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 0039c4a85b23aa6..1e743b1012e5fc1 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7883,8 +7883,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());
@@ -7920,7 +7919,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;
More information about the llvm-commits
mailing list