forked from OSchip/llvm-project
[TableGen] Fix infinite loop in SubstLeaves substitution
Previously we have `auto pos = std::string::find(...) != std::string::npos` as if condition to control substring substitution. Instead of the position for the found substring, `pos` will be a boolean value indicating found nor not. Then used as the replace start position, we were always replacing starting from 0 or 1. If the replaced substring also has the pattern to be matched, we'll see an infinite loop. PiperOrigin-RevId: 235504681
This commit is contained in:
parent
dfe07b7bf6
commit
4887e45546
|
@ -150,11 +150,14 @@ static PredNode *buildPredicateTree(const tblgen::Pred &root,
|
||||||
rootNode->expr = root.getCondition();
|
rootNode->expr = root.getCondition();
|
||||||
// Apply all parent substitutions from innermost to outermost.
|
// Apply all parent substitutions from innermost to outermost.
|
||||||
for (const auto &subst : llvm::reverse(substitutions)) {
|
for (const auto &subst : llvm::reverse(substitutions)) {
|
||||||
size_t start = 0;
|
auto pos = rootNode->expr.find(subst.first);
|
||||||
while (auto pos =
|
while (pos != std::string::npos) {
|
||||||
rootNode->expr.find(subst.first, start) != std::string::npos) {
|
|
||||||
rootNode->expr.replace(pos, subst.first.size(), subst.second);
|
rootNode->expr.replace(pos, subst.first.size(), subst.second);
|
||||||
start = pos + subst.second.size();
|
// Skip the newly inserted substring, which itself may consider the
|
||||||
|
// pattern to match.
|
||||||
|
pos += subst.second.size();
|
||||||
|
// Find the next possible match position.
|
||||||
|
pos = rootNode->expr.find(subst.first, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rootNode;
|
return rootNode;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// RUN: mlir-tblgen -gen-op-definitions -I %S/../../include %s | FileCheck %s
|
||||||
|
|
||||||
|
include "mlir/IR/op_base.td"
|
||||||
|
|
||||||
|
def I32OrF32 : Type<CPred<"{0}.isInteger(32) || {0}.isF32()">,
|
||||||
|
"32-bit integer or floating-point type">;
|
||||||
|
def I32OrF32Tensor : TypedTensor<I32OrF32>;
|
||||||
|
|
||||||
|
def Identity : Op<"identity", []> {
|
||||||
|
let arguments = (ins
|
||||||
|
I32OrF32Tensor:$x);
|
||||||
|
let results = (outs
|
||||||
|
I32OrF32Tensor:$y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK: this->getInstruction()->getOperand(0)->getType().cast<TensorType>().getElementType().isInteger(32) ||
|
||||||
|
// CHECK-SAME: this->getInstruction()->getOperand(0)->getType().cast<TensorType>().getElementType().isF32()
|
Loading…
Reference in New Issue