diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h --- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -17,6 +17,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/TargetCallingConv.h" #include "llvm/IR/Attributes.h" @@ -407,7 +408,9 @@ return false; } - virtual bool fallBackToDAGISel(const Function &F) const { return false; } + virtual bool fallBackToDAGISel(const MachineFunction &MF) const { + return false; + } /// This hook must be implemented to lower the incoming (formal) /// arguments, described by \p VRegs, for GlobalISel. Each argument diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -3110,7 +3110,7 @@ // Make our arguments/constants entry block fallthrough to the IR entry block. EntryBB->addSuccessor(&getMBB(F.front())); - if (CLI->fallBackToDAGISel(F)) { + if (CLI->fallBackToDAGISel(*MF)) { OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure", F.getSubprogram(), &F.getEntryBlock()); R << "unable to lower function: " << ore::NV("Prototype", F.getType()); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.h b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.h --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.h +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.h @@ -37,7 +37,7 @@ ArrayRef VRegs, FunctionLoweringInfo &FLI, Register SwiftErrorVReg) const override; - bool fallBackToDAGISel(const Function &F) const override; + bool fallBackToDAGISel(const MachineFunction &MF) const override; bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef> VRegs, diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -433,12 +433,19 @@ } } -bool AArch64CallLowering::fallBackToDAGISel(const Function &F) const { +bool AArch64CallLowering::fallBackToDAGISel(const MachineFunction &MF) const { + auto &F = MF.getFunction(); if (isa(F.getReturnType())) return true; - return llvm::any_of(F.args(), [](const Argument &A) { - return isa(A.getType()); - }); + if (llvm::any_of(F.args(), [](const Argument &A) { + return isa(A.getType()); + })) + return true; + const auto &ST = MF.getSubtarget(); + LLVM_DEBUG(dbgs() << "Falling back to SDAG because we don't support no-NEON"); + if (!ST.hasNEON() || !ST.hasFPARMv8()) + return true; + return false; } bool AArch64CallLowering::lowerFormalArguments( diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/no-neon-no-fp.ll b/llvm/test/CodeGen/AArch64/GlobalISel/no-neon-no-fp.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/no-neon-no-fp.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/no-neon-no-fp.ll @@ -1,13 +1,24 @@ -; RUN: not --crash llc -o - -verify-machineinstrs -global-isel -global-isel-abort=1 -stop-after=legalizer %s 2>&1 | FileCheck %s +; RUN: llc -o - -verify-machineinstrs -global-isel -global-isel-abort=2 %s 2>&1 | FileCheck %s target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64-unknown-unknown" -; CHECK: unable to legalize instruction: G_STORE %1:_(s128), %0:_(p0) :: (store 16 into %ir.ptr) (in function: foo) +; We should fall back in the translator if we don't have no-neon/no-fp support. +; CHECK: Instruction selection used fallback path for foo define void @foo(i128 *%ptr) #0 align 2 { entry: store i128 0, i128* %ptr, align 16 ret void } +; This test below will crash the legalizer due to trying to use legacy rules, +; if we don't fall back in the translator. +declare i1 @zoo() +; CHECK: Instruction selection used fallback path for bar +define i32 @bar() #0 { + %1 = call zeroext i1 @zoo() + %2 = zext i1 %1 to i32 + ret i32 %2 +} + attributes #0 = { "use-soft-float"="false" "target-features"="-fp-armv8,-neon" }