[AArch64][GlobalISel] Fall back if disabling neon/fp in the translator.

The previous technique relied on early-exiting the legalizer predicate
initialization, leaving an empty rule table. That causes a fallback
for most instructions, but some have legacy rules defined like G_ZEXT
which can try continue, but then crash.

We should fall back earlier, in the translator, to avoid this issue.

Differential Revision: https://reviews.llvm.org/D98730
This commit is contained in:
Amara Emerson 2021-03-16 11:56:32 -07:00
parent 991df7333d
commit d7fed7b899
5 changed files with 30 additions and 9 deletions

View File

@ -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 @@ public:
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

View File

@ -3110,7 +3110,7 @@ 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)) {
if (CLI->fallBackToDAGISel(*MF)) {
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
F.getSubprogram(), &F.getEntryBlock());
R << "unable to lower function: " << ore::NV("Prototype", F.getType());

View File

@ -433,12 +433,19 @@ static void handleMustTailForwardedRegisters(MachineIRBuilder &MIRBuilder,
}
}
bool AArch64CallLowering::fallBackToDAGISel(const Function &F) const {
bool AArch64CallLowering::fallBackToDAGISel(const MachineFunction &MF) const {
auto &F = MF.getFunction();
if (isa<ScalableVectorType>(F.getReturnType()))
return true;
return llvm::any_of(F.args(), [](const Argument &A) {
return isa<ScalableVectorType>(A.getType());
});
if (llvm::any_of(F.args(), [](const Argument &A) {
return isa<ScalableVectorType>(A.getType());
}))
return true;
const auto &ST = MF.getSubtarget<AArch64Subtarget>();
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(

View File

@ -37,7 +37,7 @@ public:
ArrayRef<Register> 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<ArrayRef<Register>> VRegs,

View File

@ -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" }