Skip to content

Commit 36346fe

Browse files
[RISCV][GISEL] Add support for scalable vector types in lowerReturnVal
Scalable vector types from LLVM IR are lowered into physical vector registers in MIR based on calling convention.
1 parent d19616f commit 36346fe

File tree

7 files changed

+850
-3
lines changed

7 files changed

+850
-3
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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,10 @@ static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget) {
368368
return true;
369369
}
370370

371+
if (T->isVectorTy() && Subtarget.hasVInstructions() && T->isScalableTy() &&
372+
isLegalElementTypeForRVV(T->getScalarType(), Subtarget))
373+
return true;
374+
371375
return false;
372376
}
373377

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)