[globalisel][tablegen] Honour priority order within nested instructions.

It appears that we haven't been prioritizing rules that contain nested
instructions properly. InstructionOperandMatcher didn't override
isHigherPriorityThan so it never compared the instructions/operands/predicates
inside nested instructions.

Fixes PR35926. Thanks to Diana Picus for the bug report.

llvm-svn: 322754
This commit is contained in:
Daniel Sanders 2018-01-17 20:34:29 +00:00
parent d703ec94a9
commit 12e6e709e9
2 changed files with 53 additions and 0 deletions

View File

@ -0,0 +1,40 @@
# RUN: llc -mtriple arm-gnueabihf -mattr=+vfp4 -run-pass=instruction-select -global-isel -o - %s | FileCheck %s
--- |
declare double @llvm.fma.f64(double, double, double) #0
define double @vfnmsd(double %x, double %y, double %z) #1 {
%minus.y = fsub double -0.000000e+00, %y
%fma = tail call double @llvm.fma.f64(double %x, double %minus.y, double %z)
%minus.fma = fsub double -0.000000e+00, %fma
ret double %minus.fma
}
; Function Attrs: nounwind
declare void @llvm.stackprotector(i8*, i8**) #2
attributes #0 = { nounwind readnone speculatable "target-features"="+vfp4" }
attributes #1 = { "target-features"="+vfp4" }
attributes #2 = { nounwind }
...
---
name: vfnmsd
legalized: true
regBankSelected: true
selected: false
body: |
bb.1 (%ir-block.0):
liveins: %d0, %d1, %d2
%0:fprb(s64) = COPY %d0
%1:fprb(s64) = COPY %d1
%2:fprb(s64) = COPY %d2
%3:fprb(s64) = G_FNEG %1
%4:fprb(s64) = G_FMA %0, %3, %2
%5:fprb(s64) = G_FNEG %4
%d0 = COPY %5(s64)
MOVPCLR 14, %noreg, implicit %d0
# CHECK: %{{[0-9]+}}:dpr = VFNMSD %{{[0-9]+}}, %{{[0-9]+}}, %{{[0-9]+}}, 14, %noreg
...

View File

@ -1692,6 +1692,19 @@ public:
RuleMatcher &Rule) const override {
InsnMatcher->emitPredicateOpcodes(Table, Rule);
}
bool isHigherPriorityThan(const OperandPredicateMatcher &B) const override {
if (OperandPredicateMatcher::isHigherPriorityThan(B))
return true;
if (B.OperandPredicateMatcher::isHigherPriorityThan(*this))
return false;
if (const InstructionOperandMatcher *BP =
dyn_cast<InstructionOperandMatcher>(&B))
if (InsnMatcher->isHigherPriorityThan(*BP->InsnMatcher))
return true;
return false;
}
};
//===- Actions ------------------------------------------------------------===//