Skip to content

Commit 725e599

Browse files
[RISCV][GISEL] Add support for scalable vector types in lowerReturnVal (#71587)
Scalable vector types from LLVM IR are lowered into physical vector registers in MIR based on calling convention for return instructions.
1 parent 0b8379b commit 725e599

File tree

7 files changed

+856
-5
lines changed

7 files changed

+856
-5
lines changed

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ bool IRTranslator::translateCompare(const User &U,
359359
bool IRTranslator::translateRet(const User &U, MachineIRBuilder &MIRBuilder) {
360360
const ReturnInst &RI = cast<ReturnInst>(U);
361361
const Value *Ret = RI.getReturnValue();
362-
if (Ret && DL->getTypeStoreSize(Ret->getType()) == 0)
362+
if (Ret && DL->getTypeStoreSize(Ret->getType()).isZero())
363363
Ret = nullptr;
364364

365365
ArrayRef<Register> VRegs;

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,6 +1966,9 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
19661966
if (SrcReg.isVirtual() && DstReg.isPhysical() && SrcSize.isScalable() &&
19671967
!DstSize.isScalable())
19681968
break;
1969+
if (SrcReg.isVirtual() && DstReg.isPhysical() && SrcSize.isScalable() &&
1970+
!DstSize.isScalable())
1971+
break;
19691972

19701973
if (SrcSize.isNonZero() && DstSize.isNonZero() && SrcSize != DstSize) {
19711974
if (!DstOp.getSubReg() && !SrcOp.getSubReg()) {

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,10 @@ static bool isSupportedArgumentType(Type *T, const RISCVSubtarget &Subtarget,
347347
}
348348

349349
// TODO: Only integer, pointer and aggregate types are supported now.
350-
static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget) {
350+
// TODO: Remove IsLowerRetVal argument by adding support for vectors in
351+
// lowerCall.
352+
static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget,
353+
bool IsLowerRetVal = false) {
351354
// TODO: Integers larger than 2*XLen are passed indirectly which is not
352355
// supported yet.
353356
if (T->isIntegerTy())
@@ -368,6 +371,11 @@ static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget) {
368371
return true;
369372
}
370373

374+
if (IsLowerRetVal && T->isVectorTy() && Subtarget.hasVInstructions() &&
375+
T->isScalableTy() &&
376+
isLegalElementTypeForRVV(T->getScalarType(), Subtarget))
377+
return true;
378+
371379
return false;
372380
}
373381

@@ -380,7 +388,7 @@ bool RISCVCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
380388

381389
const RISCVSubtarget &Subtarget =
382390
MIRBuilder.getMF().getSubtarget<RISCVSubtarget>();
383-
if (!isSupportedReturnType(Val->getType(), Subtarget))
391+
if (!isSupportedReturnType(Val->getType(), Subtarget, /*IsLowerRetVal=*/true))
384392
return false;
385393

386394
MachineFunction &MF = MIRBuilder.getMF();

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19638,12 +19638,15 @@ unsigned RISCVTargetLowering::getCustomCtpopCost(EVT VT,
1963819638
}
1963919639

1964019640
bool RISCVTargetLowering::fallBackToDAGISel(const Instruction &Inst) const {
19641-
// We don't support scalable vectors in GISel.
19641+
// At the moment, the only scalable instruction GISel knows how to lower is
19642+
// ret with scalable argument.
19643+
1964219644
if (Inst.getType()->isScalableTy())
1964319645
return true;
1964419646

1964519647
for (unsigned i = 0; i < Inst.getNumOperands(); ++i)
19646-
if (Inst.getOperand(i)->getType()->isScalableTy())
19648+
if (Inst.getOperand(i)->getType()->isScalableTy() &&
19649+
!isa<ReturnInst>(&Inst))
1964719650
return true;
1964819651

1964919652
if (const AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: not --crash llc -mtriple=riscv32 -mattr=+v -global-isel -stop-after=irtranslator \
2+
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s
3+
; RUN: not --crash llc -mtriple=riscv64 -mattr=+v -global-isel -stop-after=irtranslator \
4+
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s
5+
6+
; The purpose of this test is to show that the compiler throws an error when
7+
; there is no support for bf16 vectors. If the compiler did not throw an error,
8+
; then it will try to scalarize the argument to an s32, which may drop elements.
9+
define <vscale x 1 x bfloat> @test_ret_nxv1bf16() {
10+
entry:
11+
ret <vscale x 1 x bfloat> undef
12+
}
13+
14+
; CHECK: LLVM ERROR: unable to translate instruction: ret (in function: test_ret_nxv1bf16)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: not --crash llc -mtriple=riscv32 -mattr=+v -global-isel -stop-after=irtranslator \
2+
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s
3+
; RUN: not --crash llc -mtriple=riscv64 -mattr=+v -global-isel -stop-after=irtranslator \
4+
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s
5+
6+
; The purpose of this test is to show that the compiler throws an error when
7+
; there is no support for f16 vectors. If the compiler did not throw an error,
8+
; then it will try to scalarize the argument to an s32, which may drop elements.
9+
define <vscale x 1 x half> @test_ret_nxv1f16() {
10+
entry:
11+
ret <vscale x 1 x half> undef
12+
}
13+
14+
; CHECK: LLVM ERROR: unable to translate instruction: ret (in function: test_ret_nxv1f16)

0 commit comments

Comments
 (0)