Closed tomeksowi closed 2 months ago
Part of dotnet/runtime#84834
@llvm/issue-subscribers-backend-risc-v
Author: Tomasz Sowiński (tomeksowi)
The following change seems to fix the issue:
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -361,12 +361,12 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
CGCXXABI::RAA_DirectInMemory);
}
+ uint64_t Size = getContext().getTypeSize(Ty);
+
// Ignore empty structs/unions.
- if (isEmptyRecord(getContext(), Ty, true))
+ if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
return ABIArgInfo::getIgnore();
- uint64_t Size = getContext().getTypeSize(Ty);
-
// Pass floating point values via FPRs if possible.
if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
FLen >= Size && ArgFPRsLeft) {
@svs-quic Looks like the same problem exists on 32-bit ARM. Comparison against GCC on Godbolt
I'm less familiar with ARM 32 so I can't point to the exact wording in the ABI that specifies empty struct treatment.
@svs-quic Looks like the same problem exists on 32-bit ARM. Comparison against GCC on Godbolt
I'm less familiar with ARM 32 so I can't point to the exact wording in the ABI that specifies empty struct treatment.
Same here. Perhaps @efriedma-quic might be some idea?
According to RISC-V integer calling convention:
Clang doesn't assign a register nor a stack slot to the empty struct for passing:
I'd expect these functions to be
mv a0, a2
andld a0, 8(sp)
respectively.This also doesn't match GCC which does allocate a register and stack slot to the empty struct argument. Comparison with GCC on Godbolt
ISA: rv64gc Clang version: 18.1.0 and Godbolt "trunk" at the time of filing this issue (2024-07-01).