aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/lib/Target/RISCV/RISCVCallLowering.cpp5
-rw-r--r--backend/unittests/Target/RISCVCallLoweringTest.cpp16
2 files changed, 18 insertions, 3 deletions
diff --git a/backend/lib/Target/RISCV/RISCVCallLowering.cpp b/backend/lib/Target/RISCV/RISCVCallLowering.cpp
index 13cd348..ec794bc 100644
--- a/backend/lib/Target/RISCV/RISCVCallLowering.cpp
+++ b/backend/lib/Target/RISCV/RISCVCallLowering.cpp
@@ -79,8 +79,7 @@ constexpr std::uint32_t AllowedDirectCallFlags =
return makeUnexpected(ErrorCode::InvalidArgument,
"LP64D ABI value requires a source or destination register");
}
- if (!Value.Type.isValid() || !Value.Type.isScalarValue() || Value.Type.isAnyScalar() ||
- Value.Type.scalarBitWidth() > 64) {
+ if (!Value.Type.isValid() || !Value.Type.isScalarValue() || Value.Type.scalarBitWidth() > 64) {
return makeUnexpected(
ErrorCode::Unsupported,
"LP64D accepts explicitly classified integer, pointer, f32, and f64 scalar fragments");
@@ -92,7 +91,7 @@ constexpr std::uint32_t AllowedDirectCallFlags =
if (Value.Type.isPointer() && Value.Type.scalarBitWidth() != 64) {
return makeUnexpected(ErrorCode::Unsupported, "RV64GC LP64D requires 64-bit machine pointers");
}
- if (Value.Type.isInteger() && Value.Type.scalarBitWidth() < 64) {
+ if ((Value.Type.isInteger() || Value.Type.isAnyScalar()) && Value.Type.scalarBitWidth() < 64) {
if (Value.Extension == ABIExtensionKind::None) {
return makeUnexpected(ErrorCode::InvalidArgument,
"narrow LP64D integer fragments require an explicit extension kind");
diff --git a/backend/unittests/Target/RISCVCallLoweringTest.cpp b/backend/unittests/Target/RISCVCallLoweringTest.cpp
index 0262bf5..514c277 100644
--- a/backend/unittests/Target/RISCVCallLoweringTest.cpp
+++ b/backend/unittests/Target/RISCVCallLoweringTest.cpp
@@ -63,6 +63,13 @@ private:
return *Type;
}
+[[nodiscard]] rcc::LLT anyScalar(std::uint32_t Bits) {
+ const auto Type = rcc::LLT::makeAnyScalar(Bits);
+ if (!Type)
+ std::terminate();
+ return *Type;
+}
+
[[nodiscard]] rcc::LLT floating(rcc::FloatSemantics Semantics) {
const auto Type = rcc::LLT::makeFloat(Semantics);
if (!Type)
@@ -231,6 +238,15 @@ void testIntegerAndFloatingAssignments(TestContext &Context) {
isLocation(MixedPlan->argumentAssignments()[1], argumentGPR(0)),
"a mixed floating/integer aggregate must use one FPR and one GPR");
+ auto GenericScalar = callRequest({abiValue(anyScalar(64), 0)}, 1);
+ GenericScalar.Results = {abiValue(anyScalar(64), 0)};
+ auto GenericScalarPlan = rcc::riscv::callLowering().planCall(GenericScalar);
+ Context.expect(GenericScalarPlan && GenericScalarPlan->argumentAssignments().size() == 1 &&
+ GenericScalarPlan->returnAssignments().size() == 1 &&
+ GenericScalarPlan->argumentAssignments()[0].ValueType == anyScalar(64) &&
+ GenericScalarPlan->returnAssignments()[0].ValueType == anyScalar(64),
+ "LLVM generic scalar LLTs must use integer ABI transport without type loss");
+
auto Narrow = abiValue(integer(32), 0);
auto InvalidNarrow = callRequest({Narrow}, 1);
Context.expect(!rcc::riscv::callLowering().planCall(InvalidNarrow),