Previously when we bind a symbol to an op in DRR, it means to capture
the op's result(s) and later references will be expanded to result(s).
This means for ops without result, we are replacing the symbol with
nothing. This CL treats non-result op capturing and referencing as a
special case to mean the op itself.
PiperOrigin-RevId:
275269702
return repl;
}
+ // If this op has no result at all but still we bind a symbol to it, it
+ // means we want to capture the op itself.
+ if (op->getNumResults() == 0) {
+ LLVM_DEBUG(llvm::dbgs() << name << " (Op)\n");
+ return name;
+ }
+
// We are referencing all results of the multi-result op. A specific result
// can either be a value or a range. Then join them with `separator`.
SmallVector<std::string, 4> values;
// Use bound symbols in additional constraints
[(HasOneUse $res_a)]>;
+def OpSymbolBindingNoResult : TEST_Op<"symbol_binding_no_result", []> {
+ let arguments = (ins I32:$operand);
+}
+
+// Test that we can bind to an op without results and reference it later.
+def : Pat<(OpSymbolBindingNoResult:$op $operand),
+ (NativeCodeCall<"handleNoResultOp($_builder, $0)"> $op)>;
+
//===----------------------------------------------------------------------===//
// Test Patterns (Attributes)
rewriter.create<OpI>(rewriter.getUnknownLoc(), input);
}
+void handleNoResultOp(PatternRewriter &rewriter, OpSymbolBindingNoResult op) {
+ // Turn the no result op to a one-result op.
+ rewriter.create<OpSymbolBindingB>(op.getLoc(), op.operand()->getType(),
+ op.operand());
+}
+
namespace {
#include "TestPatterns.inc"
} // end anonymous namespace
return %0: i32
}
+// CHECK-LABEL: symbolBindingNoResult
+func @symbolBindingNoResult(%arg0: i32) {
+ // CHECK: test.symbol_binding_b
+ "test.symbol_binding_no_result"(%arg0) : (i32) -> ()
+ return
+}
+
//===----------------------------------------------------------------------===//
// Test Attributes
//===----------------------------------------------------------------------===//