diff --git a/test/TableGen/NegativeAddedComplexity.ll b/test/TableGen/NegativeAddedComplexity.ll new file mode 100644 index 00000000000..54c52ab3b64 --- /dev/null +++ b/test/TableGen/NegativeAddedComplexity.ll @@ -0,0 +1,41 @@ +// RUN: llvm-tblgen -I../../include -gen-dag-isel %s | FileCheck %s +// XFAIL: vg_leak + +include "llvm/Target/Target.td" + +// Make sure the higher complexity pattern comes first +// CHECK: TARGET_VAL(::ADD0) +// CHECK: Complexity = {{[^-]}} +// Make sure the ADD1 pattern has a negative complexity +// CHECK: TARGET_VAL(::ADD1) +// CHECK: Complexity = -{{[0-9]+}} + +def TestRC : RegisterClass<"TEST", [i32], 32, (add)>; + +def TestInstrInfo : InstrInfo; + +def Test : Target { + let InstructionSet = TestInstrInfo; +} + +def ADD0 : Instruction { + let OutOperandList = (outs TestRC:$dst); + let InOperandList = (ins TestRC:$src0, TestRC:$src1); +} + +def ADD1 : Instruction { + let OutOperandList = (outs TestRC:$dst); + let InOperandList = (ins TestRC:$src0, TestRC:$src1); +} + +def : Pat < + (add i32:$src0, i32:$src1), + (ADD1 $src0, $src1) +> { + let AddedComplexity = -1000; +} + +def : Pat < + (add i32:$src0, i32:$src1), + (ADD0 $src0, $src1) +>; diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 2602bbcf6f6..d195ba823b5 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -771,7 +771,7 @@ static unsigned getPatternSize(const TreePatternNode *P, /// Compute the complexity metric for the input pattern. This roughly /// corresponds to the number of nodes that are covered. -unsigned PatternToMatch:: +int PatternToMatch:: getPatternComplexity(const CodeGenDAGPatterns &CGP) const { return getPatternSize(getSrcPattern(), CGP) + getAddedComplexity(); } diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index fb30cdd9485..ef6c787c3e0 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -667,7 +667,7 @@ public: PatternToMatch(Record *srcrecord, ListInit *preds, TreePatternNode *src, TreePatternNode *dst, const std::vector &dstregs, - unsigned complexity, unsigned uid) + int complexity, unsigned uid) : SrcRecord(srcrecord), Predicates(preds), SrcPattern(src), DstPattern(dst), Dstregs(dstregs), AddedComplexity(complexity), ID(uid) {} @@ -676,7 +676,7 @@ public: TreePatternNode *SrcPattern; // Source pattern to match. TreePatternNode *DstPattern; // Resulting pattern. std::vector Dstregs; // Physical register defs being matched. - unsigned AddedComplexity; // Add to matching pattern complexity. + int AddedComplexity; // Add to matching pattern complexity. unsigned ID; // Unique ID for the record. Record *getSrcRecord() const { return SrcRecord; } @@ -684,13 +684,13 @@ public: TreePatternNode *getSrcPattern() const { return SrcPattern; } TreePatternNode *getDstPattern() const { return DstPattern; } const std::vector &getDstRegs() const { return Dstregs; } - unsigned getAddedComplexity() const { return AddedComplexity; } + int getAddedComplexity() const { return AddedComplexity; } std::string getPredicateCheck() const; /// Compute the complexity metric for the input pattern. This roughly /// corresponds to the number of nodes that are covered. - unsigned getPatternComplexity(const CodeGenDAGPatterns &CGP) const; + int getPatternComplexity(const CodeGenDAGPatterns &CGP) const; }; class CodeGenDAGPatterns { diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 82682cd5a5a..e2e6ab19cba 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -94,8 +94,8 @@ struct PatternSortingPredicate { // Otherwise, if the patterns might both match, sort based on complexity, // which means that we prefer to match patterns that cover more nodes in the // input over nodes that cover fewer. - unsigned LHSSize = LHS->getPatternComplexity(CGP); - unsigned RHSSize = RHS->getPatternComplexity(CGP); + int LHSSize = LHS->getPatternComplexity(CGP); + int RHSSize = RHS->getPatternComplexity(CGP); if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost if (LHSSize < RHSSize) return false;