Index: include/llvm/Target/GlobalISel/SelectionDAGCompat.td =================================================================== --- include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -42,4 +42,10 @@ def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; + def : GINodeEquiv; Index: lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- lib/Target/AArch64/AArch64InstructionSelector.cpp +++ lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -154,29 +154,8 @@ } case AArch64::FPRRegBankID: switch (OpSize) { - case 32: - switch (GenericOpc) { - case TargetOpcode::G_FADD: - return AArch64::FADDSrr; - case TargetOpcode::G_FSUB: - return AArch64::FSUBSrr; - case TargetOpcode::G_FMUL: - return AArch64::FMULSrr; - case TargetOpcode::G_FDIV: - return AArch64::FDIVSrr; - default: - return GenericOpc; - } case 64: switch (GenericOpc) { - case TargetOpcode::G_FADD: - return AArch64::FADDDrr; - case TargetOpcode::G_FSUB: - return AArch64::FSUBDrr; - case TargetOpcode::G_FMUL: - return AArch64::FMULDrr; - case TargetOpcode::G_FDIV: - return AArch64::FDIVDrr; case TargetOpcode::G_OR: return AArch64::ORRv8i8; default: @@ -719,11 +698,6 @@ return constrainSelectedInstRegOperands(I, TII, TRI, RBI); } - case TargetOpcode::G_FADD: - case TargetOpcode::G_FSUB: - case TargetOpcode::G_FMUL: - case TargetOpcode::G_FDIV: - case TargetOpcode::G_OR: case TargetOpcode::G_SHL: case TargetOpcode::G_LSHR: Index: utils/TableGen/GlobalISelEmitter.cpp =================================================================== --- utils/TableGen/GlobalISelEmitter.cpp +++ utils/TableGen/GlobalISelEmitter.cpp @@ -312,6 +312,7 @@ class RuleMatcher { const PatternToMatch &P; + Optional Predicate; std::vector> Matchers; std::vector> Actions; @@ -319,6 +320,17 @@ RuleMatcher(const PatternToMatch &P) : P(P) {} + /// Set the rule-level predicate check code string, if any. + /// This includes: + /// * Target features + /// * Function attributes (e.g., minsize) + /// * Other subtarget flags + void setPredicate(std::string PredString) { + assert(!Predicate && "Rules can only have one predicate"); + if (!PredString.empty()) + Predicate = PredString; + } + InstructionMatcher &addInstructionMatcher() { Matchers.emplace_back(new InstructionMatcher()); return *Matchers.back(); @@ -337,6 +349,12 @@ OS << " // Src: " << *P.getSrcPattern() << "\n" << " // Dst: " << *P.getDstPattern() << "\n"; + OS << " if ("; + + // Emit the rule-level predicates, if any. + if (Predicate) + OS << *Predicate << " && "; + // The representation supports rules that require multiple roots such as: // %ptr(p0) = ... // %elt0(s32) = G_LOAD %ptr @@ -347,7 +365,6 @@ // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr // on some targets but we don't need to make use of that yet. assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet"); - OS << " if ("; Matchers.front()->emitCxxPredicateExpr(OS, "I"); OS << ") {\n"; @@ -388,9 +405,11 @@ RuleMatcher M(P); // First, analyze the whole pattern. - // If the entire pattern has a predicate (e.g., target features), ignore it. + + // If the pattern has predicates (e.g., target features), keep track of the + // aggregate check code. if (!P.getPredicates()->getValues().empty()) - return SkipReason{"Pattern has a predicate"}; + M.setPredicate(P.getPredicateCheck()); // Physreg imp-defs require additional logic. Ignore the pattern. if (!P.getDstRegs().empty())