[llvm] 94d08fe - TableGen: Fix assert on PatFrags with predicate code
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 30 11:24:58 PST 2019
Author: Matt Arsenault
Date: 2019-12-30T14:24:25-05:00
New Revision: 94d08feaeff3591a36ed548ba7c732ddedd6f983
URL: https://github.com/llvm/llvm-project/commit/94d08feaeff3591a36ed548ba7c732ddedd6f983
DIFF: https://github.com/llvm/llvm-project/commit/94d08feaeff3591a36ed548ba7c732ddedd6f983.diff
LOG: TableGen: Fix assert on PatFrags with predicate code
This assumed a single pattern if there was a predicate. Relax this a
bit, and allow multiple patterns as long as they have the same class.
This was only broken for the DAG path. GlobalISel seems to have
handled this correctly already.
Added:
llvm/test/TableGen/predicate-patfags.td
Modified:
llvm/utils/TableGen/CodeGenDAGPatterns.cpp
Removed:
################################################################################
diff --git a/llvm/test/TableGen/predicate-patfags.td b/llvm/test/TableGen/predicate-patfags.td
new file mode 100644
index 000000000000..a6a44ff6938f
--- /dev/null
+++ b/llvm/test/TableGen/predicate-patfags.td
@@ -0,0 +1,63 @@
+// RUN: llvm-tblgen -gen-dag-isel -I %p/../../include -I %p/Common %s 2>&1 | FileCheck -check-prefix=SDAG %s
+// RUN: llvm-tblgen -gen-global-isel -I %p/../../include -I %p/Common %s 2>&1 | FileCheck -check-prefix=GISEL %s
+
+include "llvm/Target/Target.td"
+include "GlobalISelEmitterCommon.td"
+
+// Test that a predicate works when there are multiple pattern trees
+// in a PatFrags.
+
+def int_tgt_mul24 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty]>;
+def int_tgt_mul24_2 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty]>;
+
+def TGTmul24_impl : SDNode<"TargetISD::MUL24", SDTIntBinOp>;
+
+def TGTmul24 : PatFrags<(ops node:$src0, node:$src1),
+ [(int_tgt_mul24 node:$src0, node:$src1),
+ (TGTmul24_impl node:$src0, node:$src1)]>;
+
+
+def G_TGT_MUL24 : GenericInstruction {
+ let Namespace = "MyTarget";
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 1;
+}
+
+
+def : GINodeEquiv<G_TGT_MUL24, TGTmul24_impl>;
+
+
+def TGTmul24_oneuse : PatFrag<
+ (ops node:$src0, node:$src1),
+ (TGTmul24 $src0, $src1),
+ [{ return N->hasOneUse(); }]> {
+ let GISelPredicateCode = [{
+ return MRI->hasOneNonDBGUse(MI.getOperand(0).getReg());
+ }];
+}
+
+// SDAG: OPC_CheckOpcode, TARGET_VAL(ISD::INTRINSIC_W_CHAIN),
+// SDAG: OPC_CheckPredicate, 0, // Predicate_TGTmul24_oneuse
+
+// SDAG: OPC_CheckOpcode, TARGET_VAL(TargetISD::MUL24),
+// SDAG: OPC_CheckPredicate, 0, // Predicate_TGTmul24_oneuse
+
+// GISEL: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS,
+// GISEL: GIM_CheckIntrinsicID, /*MI*/1, /*Op*/1, Intrinsic::tgt_mul24,
+// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse,
+
+// GISEL: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS,
+// GISEL: GIM_CheckIntrinsicID, /*MI*/1, /*Op*/1, Intrinsic::tgt_mul24,
+// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse,
+
+// GISEL: GIM_CheckOpcode, /*MI*/1, MyTarget::G_TGT_MUL24,
+// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse,
+
+// GISEL: GIM_CheckOpcode, /*MI*/1, MyTarget::G_TGT_MUL24,
+// GISEL: GIM_CheckCxxInsnPredicate, /*MI*/1, /*FnId*/GIPFP_MI_Predicate_TGTmul24_oneuse,
+def inst_mad24 : I<
+ (outs GPR32:$dst),
+ (ins GPR32:$src0, GPR32:$src1, GPR32:$src2),
+ [(set GPR32:$dst, (add (TGTmul24_oneuse i32:$src0, i32:$src1), i32:$src2))]>;
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index d01de3317ff4..7e0ba98da94a 100644
--- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1315,13 +1315,29 @@ std::string TreePredicateFn::getCodeToRunOnSDNode() const {
// Handle arbitrary node predicates.
assert(hasPredCode() && "Don't have any predicate code!");
+
+ // If this is using PatFrags, there are multiple trees to search. They should
+ // all have the same class. FIXME: Is there a way to find a common
+ // superclass?
StringRef ClassName;
- if (PatFragRec->getOnlyTree()->isLeaf())
- ClassName = "SDNode";
- else {
- Record *Op = PatFragRec->getOnlyTree()->getOperator();
- ClassName = PatFragRec->getDAGPatterns().getSDNodeInfo(Op).getSDClassName();
+ for (const auto &Tree : PatFragRec->getTrees()) {
+ StringRef TreeClassName;
+ if (Tree->isLeaf())
+ TreeClassName = "SDNode";
+ else {
+ Record *Op = Tree->getOperator();
+ const SDNodeInfo &Info = PatFragRec->getDAGPatterns().getSDNodeInfo(Op);
+ TreeClassName = Info.getSDClassName();
+ }
+
+ if (ClassName.empty())
+ ClassName = TreeClassName;
+ else if (ClassName != TreeClassName) {
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "PatFrags trees do not have consistent class");
+ }
}
+
std::string Result;
if (ClassName == "SDNode")
Result = " SDNode *N = Node;\n";
More information about the llvm-commits
mailing list