1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[SVE] Fall back on DAG ISel at -O0 when encountering scalable types

At the moment we use Global ISel by default at -O0, however it is
currently not capable of dealing with scalable vectors for two
reasons:

1. The register banks know nothing about SVE registers.
2. The LLT (Low Level Type) class knows nothing about scalable
   vectors.

For now, the easiest way to avoid users hitting issues when using
the SVE ACLE is to fall back on normal DAG ISel when encountering
instructions that operate on scalable vector types.

I've added a couple of RUN lines to existing SVE tests to ensure
we can compile at -O0. I've also added some new tests to

  CodeGen/AArch64/GlobalISel/arm64-fallback.ll

that demonstrate we correctly fallback to DAG ISel at -O0 when
lowering formal arguments or translating instructions that involve
scalable vector types.

Differential Revision: https://reviews.llvm.org/D81557
This commit is contained in:
David Sherwood 2020-06-09 14:51:38 +01:00
parent 589444b8e2
commit c46fc6adbe
8 changed files with 47 additions and 0 deletions

View File

@ -516,6 +516,10 @@ public:
return PredictableSelectIsExpensive; return PredictableSelectIsExpensive;
} }
virtual bool fallBackToDAGISel(const Instruction &Inst) const {
return false;
}
/// If a branch or a select condition is skewed in one direction by more than /// If a branch or a select condition is skewed in one direction by more than
/// this factor, it is very likely to be predicted correctly. /// this factor, it is very likely to be predicted correctly.
virtual BranchProbability getPredictableBranchThreshold() const; virtual BranchProbability getPredictableBranchThreshold() const;

View File

@ -2195,6 +2195,10 @@ bool IRTranslator::translate(const Instruction &Inst) {
else else
EntryBuilder->setDebugLoc(DebugLoc()); EntryBuilder->setDebugLoc(DebugLoc());
auto &TLI = *MF->getSubtarget().getTargetLowering();
if (TLI.fallBackToDAGISel(Inst))
return false;
switch (Inst.getOpcode()) { switch (Inst.getOpcode()) {
#define HANDLE_INST(NUM, OPCODE, CLASS) \ #define HANDLE_INST(NUM, OPCODE, CLASS) \
case Instruction::OPCODE: \ case Instruction::OPCODE: \

View File

@ -14642,3 +14642,14 @@ bool AArch64TargetLowering::shouldLocalize(
} }
return TargetLoweringBase::shouldLocalize(MI, TTI); return TargetLoweringBase::shouldLocalize(MI, TTI);
} }
bool AArch64TargetLowering::fallBackToDAGISel(const Instruction &Inst) const {
if (isa<ScalableVectorType>(Inst.getType()))
return true;
for (unsigned i = 0; i < Inst.getNumOperands(); ++i)
if (isa<ScalableVectorType>(Inst.getOperand(i)->getType()))
return true;
return false;
}

View File

@ -702,6 +702,9 @@ public:
bool isVarArg) const override; bool isVarArg) const override;
/// Used for exception handling on Win64. /// Used for exception handling on Win64.
bool needsFixedCatchObjects() const override; bool needsFixedCatchObjects() const override;
bool fallBackToDAGISel(const Instruction &Inst) const override;
private: private:
/// Keep a pointer to the AArch64Subtarget around so that we can /// Keep a pointer to the AArch64Subtarget around so that we can
/// make the right decision when generating code for different targets. /// make the right decision when generating code for different targets.

View File

@ -438,6 +438,9 @@ bool AArch64CallLowering::lowerFormalArguments(
SmallVector<ArgInfo, 8> SplitArgs; SmallVector<ArgInfo, 8> SplitArgs;
unsigned i = 0; unsigned i = 0;
for (auto &Arg : F.args()) { for (auto &Arg : F.args()) {
if (isa<ScalableVectorType>(Arg.getType()))
return false;
if (DL.getTypeStoreSize(Arg.getType()).isZero()) if (DL.getTypeStoreSize(Arg.getType()).isZero())
continue; continue;

View File

@ -219,3 +219,23 @@ entry:
tail call void asm sideeffect "", "imr,imr,~{memory}"(i32 %x, i32 %y) tail call void asm sideeffect "", "imr,imr,~{memory}"(i32 %x, i32 %y)
ret void ret void
} }
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower arguments{{.*}}scalable_arg
; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_arg
define <vscale x 16 x i8> @scalable_arg(<vscale x 16 x i1> %pred, i8* %addr) #1 {
%res = call <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1> %pred, i8* %addr)
ret <vscale x 16 x i8> %res
}
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction{{.*}}scalable_call
; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_call
define <vscale x 16 x i8> @scalable_call(i8* %addr) #1 {
%pred = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 0)
%res = call <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1> %pred, i8* %addr)
ret <vscale x 16 x i8> %res
}
attributes #1 = { "target-features"="+sve" }
declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 %pattern)
declare <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1>, i8*)

View File

@ -1,4 +1,5 @@
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
; RUN: llc -O0 -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
; ;
; LD1B ; LD1B

View File

@ -1,4 +1,5 @@
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
; RUN: llc -O0 -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t ; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
; WARN-NOT: warning ; WARN-NOT: warning