[llvm] af8e386 - [RISCV][GlobalISel] Add lowerFormalArguments for calling convention
Nitin John Raj via llvm-commits
llvm-commits at lists.llvm.org
Tue May 30 13:43:25 PDT 2023
Author: Nitin John Raj
Date: 2023-05-30T13:42:49-07:00
New Revision: af8e3861025f3c931cc67ced86d6bd8c939e6fc0
URL: https://github.com/llvm/llvm-project/commit/af8e3861025f3c931cc67ced86d6bd8c939e6fc0
DIFF: https://github.com/llvm/llvm-project/commit/af8e3861025f3c931cc67ced86d6bd8c939e6fc0.diff
LOG: [RISCV][GlobalISel] Add lowerFormalArguments for calling convention
This patch adds an IncomingValueHandler and IncomingValueAssigner, and implements minimal support for lowering formal arguments according to the RISC-V calling convention. Simple non-aggregate integer and pointer types are supported.
In the future, we must correctly handle byval and sret pointer arguments, and instances where the number of arguments exceeds the number of registers.
Coauthored By: lewis-revill
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D74977
Added:
llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/args.ll
Modified:
llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
index 7b39b1c9444d4..cc6cf64a9a2db 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
@@ -79,6 +79,60 @@ struct RISCVOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
}
};
+struct RISCVIncomingValueAssigner : public CallLowering::IncomingValueAssigner {
+private:
+ // The function used internally to assign args - we ignore the AssignFn stored
+ // by IncomingValueAssigner since RISC-V implements its CC using a custom
+ // function with a
diff erent signature.
+ RISCVTargetLowering::RISCVCCAssignFn *RISCVAssignFn;
+
+ // Whether this is assigning args from a return.
+ bool IsRet;
+
+public:
+ RISCVIncomingValueAssigner(
+ RISCVTargetLowering::RISCVCCAssignFn *RISCVAssignFn_, bool IsRet)
+ : CallLowering::IncomingValueAssigner(nullptr),
+ RISCVAssignFn(RISCVAssignFn_), IsRet(IsRet) {}
+
+ bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
+ CCValAssign::LocInfo LocInfo,
+ const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
+ CCState &State) override {
+ MachineFunction &MF = State.getMachineFunction();
+ const DataLayout &DL = MF.getDataLayout();
+ const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>();
+
+ return RISCVAssignFn(DL, Subtarget.getTargetABI(), ValNo, ValVT, LocVT,
+ LocInfo, Flags, State, /*IsFixed=*/true, IsRet,
+ Info.Ty, *Subtarget.getTargetLowering(),
+ /*FirstMaskArgument=*/std::nullopt);
+ }
+};
+
+struct RISCVIncomingValueHandler : public CallLowering::IncomingValueHandler {
+ RISCVIncomingValueHandler(MachineIRBuilder &B, MachineRegisterInfo &MRI)
+ : IncomingValueHandler(B, MRI) {}
+
+ Register getStackAddress(uint64_t MemSize, int64_t Offset,
+ MachinePointerInfo &MPO,
+ ISD::ArgFlagsTy Flags) override {
+ llvm_unreachable("not implemented");
+ }
+
+ void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
+ MachinePointerInfo &MPO, CCValAssign &VA) override {
+ llvm_unreachable("not implemented");
+ }
+
+ void assignValueToReg(Register ValVReg, Register PhysReg,
+ CCValAssign VA) override {
+ // Copy argument received in physical register to desired VReg.
+ MIRBuilder.getMBB().addLiveIn(PhysReg);
+ MIRBuilder.buildCopy(ValVReg, PhysReg);
+ }
+};
+
} // namespace
RISCVCallLowering::RISCVCallLowering(const RISCVTargetLowering &TLI)
@@ -131,11 +185,49 @@ bool RISCVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
const Function &F,
ArrayRef<ArrayRef<Register>> VRegs,
FunctionLoweringInfo &FLI) const {
-
+ // Early exit if there are no arguments.
if (F.arg_empty())
return true;
- return false;
+ // TODO: Support vararg functions.
+ if (F.isVarArg())
+ return false;
+
+ // TODO: Support all argument types.
+ for (auto &Arg : F.args()) {
+ if (Arg.getType()->isIntegerTy())
+ continue;
+ if (Arg.getType()->isPointerTy())
+ continue;
+ return false;
+ }
+
+ MachineFunction &MF = MIRBuilder.getMF();
+ const DataLayout &DL = MF.getDataLayout();
+ CallingConv::ID CC = F.getCallingConv();
+
+ SmallVector<ArgInfo, 32> SplitArgInfos;
+ unsigned Index = 0;
+ for (auto &Arg : F.args()) {
+ // Construct the ArgInfo object from destination register and argument type.
+ ArgInfo AInfo(VRegs[Index], Arg.getType(), Index);
+ setArgFlags(AInfo, Index + AttributeList::FirstArgIndex, DL, F);
+
+ // Handle any required merging from split value types from physical
+ // registers into the desired VReg. ArgInfo objects are constructed
+ // correspondingly and appended to SplitArgInfos.
+ splitToValueTypes(AInfo, SplitArgInfos, DL, CC);
+
+ ++Index;
+ }
+
+ RISCVIncomingValueAssigner Assigner(
+ CC == CallingConv::Fast ? RISCV::CC_RISCV_FastCC : RISCV::CC_RISCV,
+ /*IsRet=*/false);
+ RISCVIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
+
+ return determineAndHandleAssignments(Handler, Assigner, SplitArgInfos,
+ MIRBuilder, CC, F.isVarArg());
}
bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/args.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/args.ll
new file mode 100644
index 0000000000000..fda08d91dc3a2
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/args.ll
@@ -0,0 +1,297 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -mtriple=riscv32 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV32I %s
+; RUN: llc -mtriple=riscv64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
+
+define void @test_args_i8(i8 %a) {
+
+ ; RV32I-LABEL: name: test_args_i8
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[C]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_i8
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[C]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i8 %a, 1
+ ret void
+}
+
+define void @test_args_i16(i16 %a) {
+
+ ; RV32I-LABEL: name: test_args_i16
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[C]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_i16
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[C]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i16 %a, 1
+ ret void
+}
+
+define void @test_args_i32(i32 %a) {
+
+ ; RV32I-LABEL: name: test_args_i32
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_i32
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[C]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i32 %a, 1
+ ret void
+}
+
+define void @test_args_i64(i64 %a) {
+
+ ; RV32I-LABEL: name: test_args_i64
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[MV]], [[C]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_i64
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[C]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i64 %a, 1
+ ret void
+}
+
+define void @test_args_i8_ptr(ptr %a) {
+
+ ; RV32I-LABEL: name: test_args_i8_ptr
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_i8_ptr
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = load i8, ptr %a
+ ret void
+}
+
+define void @test_args_2xi8(i8 %a, i8 %b) {
+
+ ; RV32I-LABEL: name: test_args_2xi8
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_2xi8
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10, $x11
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s64)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i8 %a, %b
+ ret void
+}
+
+define void @test_args_2xi16(i16 %a, i16 %b) {
+
+ ; RV32I-LABEL: name: test_args_2xi16
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC1]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_2xi16
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10, $x11
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s64)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC1]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i16 %a, %b
+ ret void
+}
+
+define void @test_args_2xi32(i32 %a, i32 %b) {
+
+ ; RV32I-LABEL: name: test_args_2xi32
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY1]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_2xi32
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10, $x11
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[TRUNC1]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i32 %a, %b
+ ret void
+}
+
+define void @test_args_2xi64(i64 %a, i64 %b) {
+
+ ; RV32I-LABEL: name: test_args_2xi64
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[MV]], [[MV1]]
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_2xi64
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10, $x11
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]]
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = add i64 %a, %b
+ ret void
+}
+
+define void @test_args_2xi8_ptr(ptr %a, ptr %b) {
+
+ ; RV32I-LABEL: name: test_args_2xi8_ptr
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
+ ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[COPY1]](p0) :: (load (s8) from %ir.b)
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_2xi8_ptr
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10, $x11
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
+ ; RV64I-NEXT: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[COPY1]](p0) :: (load (s8) from %ir.b)
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = load i8, ptr %a
+ %1 = load i8, ptr %b
+ ret void
+}
+
+define void @test_args_ptr_byval(ptr byval(i8) %a) {
+ ; RV32I-LABEL: name: test_args_ptr_byval
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_ptr_byval
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = load i8, ptr %a
+ ret void
+}
+
+define void @test_args_ptr_sret(ptr sret(i8) %a) {
+ ; RV32I-LABEL: name: test_args_ptr_sret
+ ; RV32I: bb.1.entry:
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
+ ; RV32I-NEXT: PseudoRET
+ ; RV64I-LABEL: name: test_args_ptr_sret
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
+ ; RV64I-NEXT: PseudoRET
+entry:
+ %0 = load i8, ptr %a
+ ret void
+}
More information about the llvm-commits
mailing list