Skip to content

Commit 332df07

Browse files
committed
[RISCV][GISel] Add FP calling convention support using stack.
This builds on the register support to add stack support.
1 parent 19d7f6f commit 332df07

File tree

5 files changed

+705
-8
lines changed

5 files changed

+705
-8
lines changed

llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,29 @@ struct RISCVOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
122122
MRI.createGenericVirtualRegister(LLT::scalar(32))};
123123
MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]);
124124

125-
if (Thunk) {
126-
*Thunk = [=]() {
127-
assignValueToReg(NewRegs[0], VALo.getLocReg(), VALo);
125+
if (VAHi.isMemLoc()) {
126+
LLT MemTy(VAHi.getLocVT());
127+
128+
MachinePointerInfo MPO;
129+
Register StackAddr = getStackAddress(
130+
MemTy.getSizeInBytes(), VAHi.getLocMemOffset(), MPO, Arg.Flags[0]);
131+
132+
assignValueToAddress(NewRegs[1], StackAddr, MemTy, MPO,
133+
const_cast<CCValAssign &>(VAHi));
134+
}
135+
136+
auto assignFunc = [=]() {
137+
assignValueToReg(NewRegs[0], VALo.getLocReg(), VALo);
138+
if (VAHi.isRegLoc())
128139
assignValueToReg(NewRegs[1], VAHi.getLocReg(), VAHi);
129-
};
140+
};
141+
142+
if (Thunk) {
143+
*Thunk = assignFunc;
130144
return 1;
131145
}
132-
assignValueToReg(NewRegs[0], VALo.getLocReg(), VALo);
133-
assignValueToReg(NewRegs[1], VAHi.getLocReg(), VAHi);
146+
147+
assignFunc();
134148
return 1;
135149
}
136150

@@ -207,7 +221,7 @@ struct RISCVIncomingValueHandler : public CallLowering::IncomingValueHandler {
207221

208222
unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
209223
ArrayRef<CCValAssign> VAs,
210-
std::function<void()> *Thunk = nullptr) override {
224+
std::function<void()> *Thunk) override {
211225
assert(VAs.size() >= 2 && "Expected at least 2 VAs.");
212226
const CCValAssign &VALo = VAs[0];
213227
const CCValAssign &VAHi = VAs[1];
@@ -223,8 +237,20 @@ struct RISCVIncomingValueHandler : public CallLowering::IncomingValueHandler {
223237
Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
224238
MRI.createGenericVirtualRegister(LLT::scalar(32))};
225239

240+
if (VAHi.isMemLoc()) {
241+
LLT MemTy(VAHi.getLocVT());
242+
243+
MachinePointerInfo MPO;
244+
Register StackAddr = getStackAddress(
245+
MemTy.getSizeInBytes(), VAHi.getLocMemOffset(), MPO, Arg.Flags[0]);
246+
247+
assignValueToAddress(NewRegs[1], StackAddr, MemTy, MPO,
248+
const_cast<CCValAssign &>(VAHi));
249+
}
250+
226251
assignValueToReg(NewRegs[0], VALo.getLocReg(), VALo);
227-
assignValueToReg(NewRegs[1], VAHi.getLocReg(), VAHi);
252+
if (VAHi.isRegLoc())
253+
assignValueToReg(NewRegs[1], VAHi.getLocReg(), VAHi);
228254

229255
MIRBuilder.buildMergeLikeInstr(Arg.Regs[0], NewRegs);
230256

llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32.ll

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,67 @@ define i32 @caller_float_in_regs() nounwind {
3838
ret i32 %1
3939
}
4040

41+
define i32 @callee_float_on_stack(i64 %a, i64 %b, i64 %c, i64 %d, float %e) nounwind {
42+
; RV32I-LABEL: name: callee_float_on_stack
43+
; RV32I: bb.1 (%ir-block.0):
44+
; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
45+
; RV32I-NEXT: {{ $}}
46+
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
47+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
48+
; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
49+
; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
50+
; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
51+
; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
52+
; RV32I-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
53+
; RV32I-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
54+
; RV32I-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
55+
; RV32I-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
56+
; RV32I-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
57+
; RV32I-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
58+
; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
59+
; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
60+
; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV3]](s64)
61+
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[LOAD]]
62+
; RV32I-NEXT: $x10 = COPY [[ADD]](s32)
63+
; RV32I-NEXT: PseudoRET implicit $x10
64+
%1 = trunc i64 %d to i32
65+
%2 = bitcast float %e to i32
66+
%3 = add i32 %1, %2
67+
ret i32 %3
68+
}
69+
70+
define i32 @caller_float_on_stack() nounwind {
71+
; RV32I-LABEL: name: caller_float_on_stack
72+
; RV32I: bb.1 (%ir-block.0):
73+
; RV32I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
74+
; RV32I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
75+
; RV32I-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
76+
; RV32I-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
77+
; RV32I-NEXT: [[C4:%[0-9]+]]:_(s32) = G_FCONSTANT float 5.000000e+00
78+
; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
79+
; RV32I-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
80+
; RV32I-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
81+
; RV32I-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
82+
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
83+
; RV32I-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
84+
; RV32I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C5]](s32)
85+
; RV32I-NEXT: G_STORE [[C4]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
86+
; RV32I-NEXT: $x10 = COPY [[UV]](s32)
87+
; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
88+
; RV32I-NEXT: $x12 = COPY [[UV2]](s32)
89+
; RV32I-NEXT: $x13 = COPY [[UV3]](s32)
90+
; RV32I-NEXT: $x14 = COPY [[UV4]](s32)
91+
; RV32I-NEXT: $x15 = COPY [[UV5]](s32)
92+
; RV32I-NEXT: $x16 = COPY [[UV6]](s32)
93+
; RV32I-NEXT: $x17 = COPY [[UV7]](s32)
94+
; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @callee_float_on_stack, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
95+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
96+
; RV32I-NEXT: $x10 = COPY [[COPY1]](s32)
97+
; RV32I-NEXT: PseudoRET implicit $x10
98+
%1 = call i32 @callee_float_on_stack(i64 1, i64 2, i64 3, i64 4, float 5.0)
99+
ret i32 %1
100+
}
101+
41102
define float @callee_tiny_scalar_ret() nounwind {
42103
; RV32I-LABEL: name: callee_tiny_scalar_ret
43104
; RV32I: bb.1 (%ir-block.0):

0 commit comments

Comments
 (0)