diff options
author | Jessica Paquette <jpaquette@apple.com> | 2019-03-11 20:51:17 +0000 |
---|---|---|
committer | Jessica Paquette <jpaquette@apple.com> | 2019-03-11 20:51:17 +0000 |
commit | 42d16501e68a3c5465c842434aafbb8658979697 (patch) | |
tree | 985d980b72bf3598e783c6f041a497b0ca5d9199 /llvm/lib | |
parent | 2c6c84e52c452e3d4a94ecf0e85c1cb526603580 (diff) | |
download | bcm5719-llvm-42d16501e68a3c5465c842434aafbb8658979697.tar.gz bcm5719-llvm-42d16501e68a3c5465c842434aafbb8658979697.zip |
[GlobalISel][AArch64] Always fall back on aarch64.neon.addp.*
Overloaded intrinsics aren't necessarily safe for instruction selection. One
such intrinsic is aarch64.neon.addp.*.
This is a temporary workaround to ensure that we always fall back on that
intrinsic. Eventually this will be replaced with a proper solution.
https://bugs.llvm.org/show_bug.cgi?id=40968
Differential Revision: https://reviews.llvm.org/D59062
llvm-svn: 355865
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp | 38 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp | 24 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64LegalizerInfo.h | 3 |
3 files changed, 58 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp index e17993987f0..32357ff657c 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp @@ -59,10 +59,30 @@ raw_ostream &LegalityQuery::print(raw_ostream &OS) const { } #ifndef NDEBUG +// Make sure the rule won't (trivially) loop forever. +static bool hasNoSimpleLoops(const LegalizeRule &Rule, const LegalityQuery &Q, + const std::pair<unsigned, LLT> &Mutation) { + switch (Rule.getAction()) { + case Custom: + case Lower: + case MoreElements: + case FewerElements: + break; + default: + return Q.Types[Mutation.first] != Mutation.second; + } + return true; +} + // Make sure the returned mutation makes sense for the match type. static bool mutationIsSane(const LegalizeRule &Rule, const LegalityQuery &Q, std::pair<unsigned, LLT> Mutation) { + // If the user wants a custom mutation, then we can't really say much about + // it. Return true, and trust that they're doing the right thing. + if (Rule.getAction() == Custom) + return true; + const unsigned TypeIdx = Mutation.first; const LLT OldTy = Q.Types[TypeIdx]; const LLT NewTy = Mutation.second; @@ -133,12 +153,7 @@ LegalizeActionStep LegalizeRuleSet::apply(const LegalityQuery &Query) const { << Mutation.first << ", " << Mutation.second << "\n"); assert(mutationIsSane(Rule, Query, Mutation) && "legality mutation invalid for match"); - - assert((Query.Types[Mutation.first] != Mutation.second || - Rule.getAction() == Lower || - Rule.getAction() == MoreElements || - Rule.getAction() == FewerElements) && - "Simple loop detected"); + assert(hasNoSimpleLoops(Rule, Query, Mutation) && "Simple loop detected"); return {Rule.getAction(), Mutation.first, Mutation.second}; } else LLVM_DEBUG(dbgs() << ".. no match\n"); @@ -435,6 +450,14 @@ bool LegalizerInfo::isLegal(const MachineInstr &MI, return getAction(MI, MRI).Action == Legal; } +bool LegalizerInfo::isLegalOrCustom(const MachineInstr &MI, + const MachineRegisterInfo &MRI) const { + auto Action = getAction(MI, MRI).Action; + // If the action is custom, it may not necessarily modify the instruction, + // so we have to assume it's legal. + return Action == Legal || Action == Custom; +} + bool LegalizerInfo::legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const { @@ -644,7 +667,8 @@ const MachineInstr *llvm::machineFunctionIsIllegal(const MachineFunction &MF) { const MachineRegisterInfo &MRI = MF.getRegInfo(); for (const MachineBasicBlock &MBB : MF) for (const MachineInstr &MI : MBB) - if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) + if (isPreISelGenericOpcode(MI.getOpcode()) && + !MLI->isLegalOrCustom(MI, MRI)) return &MI; } return nullptr; diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp index 03933b1d098..c473dc490c5 100644 --- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -64,6 +64,11 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) { return std::make_pair(0, EltTy); }); + // HACK: Check that the intrinsic isn't ambiguous. + // (See: https://bugs.llvm.org/show_bug.cgi?id=40968) + getActionDefinitionsBuilder(G_INTRINSIC) + .custom(); + getActionDefinitionsBuilder(G_PHI) .legalFor({p0, s16, s32, s64}) .clampScalar(0, s16, s64) @@ -500,11 +505,30 @@ bool AArch64LegalizerInfo::legalizeCustom(MachineInstr &MI, return false; case TargetOpcode::G_VAARG: return legalizeVaArg(MI, MRI, MIRBuilder); + case TargetOpcode::G_INTRINSIC: + return legalizeIntrinsic(MI, MRI, MIRBuilder); } llvm_unreachable("expected switch to return"); } +bool AArch64LegalizerInfo::legalizeIntrinsic( + MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilder &MIRBuilder) const { + // HACK: Don't allow faddp/addp for now. We don't pass down the type info + // necessary to get this right today. + // + // It looks like addp/faddp is the only intrinsic that's impacted by this. + // All other intrinsics fully describe the required types in their names. + // + // (See: https://bugs.llvm.org/show_bug.cgi?id=40968) + const MachineOperand &IntrinOp = MI.getOperand(1); + if (IntrinOp.isIntrinsicID() && + IntrinOp.getIntrinsicID() == Intrinsic::aarch64_neon_addp) + return false; + return true; +} + bool AArch64LegalizerInfo::legalizeVaArg(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder) const { diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.h b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.h index c5979d8bbe5..9472a4e9c93 100644 --- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.h +++ b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.h @@ -34,6 +34,9 @@ public: private: bool legalizeVaArg(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder) const; + + bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilder &MIRBuilder) const; }; } // End llvm namespace. #endif |