Skip to content

Commit

Permalink
[RISCV][GISEL] Add support for scalable vector types in lowerReturnVal
Browse files Browse the repository at this point in the history
Scalable vector types from LLVM IR are lowered into physical vector
registers in MIR based on calling convention.

This patch is stacked on llvm#70881.
  • Loading branch information
michaelmaitland committed Nov 14, 2023
1 parent a1a77bb commit 16a10c3
Show file tree
Hide file tree
Showing 7 changed files with 850 additions and 3 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ bool IRTranslator::translateCompare(const User &U,
bool IRTranslator::translateRet(const User &U, MachineIRBuilder &MIRBuilder) {
const ReturnInst &RI = cast<ReturnInst>(U);
const Value *Ret = RI.getReturnValue();
if (Ret && DL->getTypeStoreSize(Ret->getType()) == 0)
if (Ret && DL->getTypeStoreSize(Ret->getType()).isZero())
Ret = nullptr;

ArrayRef<Register> VRegs;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1966,6 +1966,9 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
if (SrcReg.isVirtual() && DstReg.isPhysical() && SrcSize.isScalable() &&
!DstSize.isScalable())
break;
if (SrcReg.isVirtual() && DstReg.isPhysical() && SrcSize.isScalable() &&
!DstSize.isScalable())
break;

if (SrcSize.isNonZero() && DstSize.isNonZero() && SrcSize != DstSize) {
if (!DstOp.getSubReg() && !SrcOp.getSubReg()) {
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,10 @@ static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget) {
return true;
}

if (T->isVectorTy() && Subtarget.hasVInstructions() && T->isScalableTy() &&
isLegalElementTypeForRVV(T->getScalarType(), Subtarget))
return true;

return false;
}

Expand Down
7 changes: 5 additions & 2 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19638,12 +19638,15 @@ unsigned RISCVTargetLowering::getCustomCtpopCost(EVT VT,
}

bool RISCVTargetLowering::fallBackToDAGISel(const Instruction &Inst) const {
// We don't support scalable vectors in GISel.
// At the moment, the only scalable instruction GISel knows how to lower is
// ret with scalable argument.

if (Inst.getType()->isScalableTy())
return true;

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

if (const AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; RUN: not --crash llc -mtriple=riscv32 -mattr=+v -global-isel -stop-after=irtranslator \
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s
; RUN: not --crash llc -mtriple=riscv64 -mattr=+v -global-isel -stop-after=irtranslator \
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s

; The purpose of this test is to show that the compiler throws an error when
; there is no support for bf16 vectors. If the compiler did not throw an error,
; then it will try to scalarize the argument to an s32, which may drop elements.
define <vscale x 1 x bfloat> @test_ret_nxv1bf16() {
entry:
ret <vscale x 1 x bfloat> undef
}

; CHECK: LLVM ERROR: unable to translate instruction: ret (in function: test_ret_nxv1bf16)
14 changes: 14 additions & 0 deletions llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/vec-ret-f16-err.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; RUN: not --crash llc -mtriple=riscv32 -mattr=+v -global-isel -stop-after=irtranslator \
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s
; RUN: not --crash llc -mtriple=riscv64 -mattr=+v -global-isel -stop-after=irtranslator \
; RUN: -verify-machineinstrs < %s 2>&1 | FileCheck %s

; The purpose of this test is to show that the compiler throws an error when
; there is no support for f16 vectors. If the compiler did not throw an error,
; then it will try to scalarize the argument to an s32, which may drop elements.
define <vscale x 1 x half> @test_ret_nxv1f16() {
entry:
ret <vscale x 1 x half> undef
}

; CHECK: LLVM ERROR: unable to translate instruction: ret (in function: test_ret_nxv1f16)
Loading

0 comments on commit 16a10c3

Please sign in to comment.