From 654ddede3dce4522e684d8f12deec1faf5aaab83 Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Thu, 25 Jun 2020 08:19:49 +0100 Subject: [PATCH] [SVE][CodeGen] Fix bug when falling back to DAG ISel In an earlier commit 584d0d5c1749c13625a5d322178ccb4121eea610 I added functionality to allow AArch64 CodeGen support for falling back to DAG ISel when Global ISel encounters scalable vector types. However, it seems that we were not falling back early enough as llvm::getLLTForType was still being invoked for scalable vector types. I've added a new fallback function to the call lowering class in order to catch this problem early enough, rather than wait for lowerFormalArguments to reject scalable vector types. Differential Revision: https://reviews.llvm.org/D82524 --- include/llvm/CodeGen/GlobalISel/CallLowering.h | 2 ++ lib/CodeGen/GlobalISel/IRTranslator.cpp | 8 ++++++++ .../AArch64/GISel/AArch64CallLowering.cpp | 11 ++++++++--- lib/Target/AArch64/GISel/AArch64CallLowering.h | 2 ++ .../AArch64/GlobalISel/arm64-fallback.ll | 17 +++++++++++++---- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/include/llvm/CodeGen/GlobalISel/CallLowering.h b/include/llvm/CodeGen/GlobalISel/CallLowering.h index 88a1837665a..4d60dffb91d 100644 --- a/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -290,6 +290,8 @@ public: return false; } + virtual bool fallBackToDAGISel(const Function &F) const { return false; } + /// This hook must be implemented to lower the incoming (formal) /// arguments, described by \p VRegs, for GlobalISel. Each argument /// must end up in the related virtual registers described by \p VRegs. diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index 4d950d4d203..0171d6cb18c 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2384,6 +2384,14 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { // Make our arguments/constants entry block fallthrough to the IR entry block. EntryBB->addSuccessor(&getMBB(F.front())); + if (CLI->fallBackToDAGISel(F)) { + OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure", + F.getSubprogram(), &F.getEntryBlock()); + R << "unable to lower function: " << ore::NV("Prototype", F.getType()); + reportTranslationError(*MF, *TPC, *ORE, R); + return false; + } + // Lower the actual args into this basic block. SmallVector, 8> VRegArgs; for (const Argument &Arg: F.args()) { diff --git a/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index 7903299fcc3..ec9683a560f 100644 --- a/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -427,6 +427,14 @@ static void handleMustTailForwardedRegisters(MachineIRBuilder &MIRBuilder, } } +bool AArch64CallLowering::fallBackToDAGISel(const Function &F) const { + if (isa(F.getReturnType())) + return true; + return llvm::any_of(F.args(), [](const Argument &A) { + return isa(A.getType()); + }); +} + bool AArch64CallLowering::lowerFormalArguments( MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef> VRegs) const { @@ -438,9 +446,6 @@ bool AArch64CallLowering::lowerFormalArguments( SmallVector SplitArgs; unsigned i = 0; for (auto &Arg : F.args()) { - if (isa(Arg.getType())) - return false; - if (DL.getTypeStoreSize(Arg.getType()).isZero()) continue; diff --git a/lib/Target/AArch64/GISel/AArch64CallLowering.h b/lib/Target/AArch64/GISel/AArch64CallLowering.h index b0c601c7062..640a8625305 100644 --- a/lib/Target/AArch64/GISel/AArch64CallLowering.h +++ b/lib/Target/AArch64/GISel/AArch64CallLowering.h @@ -37,6 +37,8 @@ public: ArrayRef VRegs, Register SwiftErrorVReg) const override; + bool fallBackToDAGISel(const Function &F) const override; + bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef> VRegs) const override; diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll b/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll index ca628fa45f6..8287ab716a8 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll @@ -220,21 +220,30 @@ entry: ret void } -; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to lower arguments{{.*}}scalable_arg +; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to lower function{{.*}}scalable_arg ; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_arg define @scalable_arg( %pred, i8* %addr) #1 { %res = call @llvm.aarch64.sve.ld1.nxv16i8( %pred, i8* %addr) ret %res } -; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to translate instruction{{.*}}scalable_call -; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_call -define @scalable_call(i8* %addr) #1 { +; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to lower function{{.*}}scalable_ret +; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_ret +define @scalable_ret(i8* %addr) #1 { %pred = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 0) %res = call @llvm.aarch64.sve.ld1.nxv16i8( %pred, i8* %addr) ret %res } +; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to translate instruction{{.*}}scalable_call +; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_call +define i8 @scalable_call(i8* %addr) #1 { + %pred = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 0) + %vec = call @llvm.aarch64.sve.ld1.nxv16i8( %pred, i8* %addr) + %res = extractelement %vec, i32 0 + ret i8 %res +} + attributes #1 = { "target-features"="+sve" } declare @llvm.aarch64.sve.ptrue.nxv16i1(i32 %pattern)