llvm/mlir/test/Dialect/PDL/ops.mlir

// RUN: mlir-opt -split-input-file %s | mlir-opt
// RUN: mlir-opt -split-input-file -mlir-print-op-generic -mlir-print-local-scope %s | FileCheck %s --check-prefix=CHECK-GENERIC

// -----

pdl.pattern @operations : benefit(1) {
  // Operation with attributes and results.
  %attribute = attribute
  %type = type
  %op0 = operation {"attr" = %attribute} -> (%type : !pdl.type)
  %op0_result = pdl.result 0 of %op0

  // Operation with input.
  %input = operand
  %root = operation(%op0_result, %input : !pdl.value, !pdl.value)
  rewrite %root with "rewriter"
}

// -----

pdl.pattern @rewrite_with_args : benefit(1) {
  %input = operand
  %root = operation(%input : !pdl.value)
  rewrite %root with "rewriter"(%input : !pdl.value)
}

// -----

pdl.pattern @rewrite_multi_root_optimal : benefit(2) {
  %input1 = operand
  %input2 = operand
  %type = type
  %op1 = operation(%input1 : !pdl.value) -> (%type : !pdl.type)
  %val1 = result 0 of %op1
  %root1 = operation(%val1 : !pdl.value)
  %op2 = operation(%input2 : !pdl.value) -> (%type : !pdl.type)
  %val2 = result 0 of %op2
  %root2 = operation(%val1, %val2 : !pdl.value, !pdl.value)
  rewrite with "rewriter"(%root1, %root2 : !pdl.operation, !pdl.operation)
}

// -----

pdl.pattern @rewrite_multi_root_forced : benefit(2) {
  %input1 = operand
  %input2 = operand
  %type = type
  %op1 = operation(%input1 : !pdl.value) -> (%type : !pdl.type)
  %val1 = result 0 of %op1
  %root1 = operation(%val1 : !pdl.value)
  %op2 = operation(%input2 : !pdl.value) -> (%type : !pdl.type)
  %val2 = result 0 of %op2
  %root2 = operation(%val1, %val2 : !pdl.value, !pdl.value)
  rewrite %root1 with "rewriter"(%root2 : !pdl.operation)
}

// -----

// Check that the result type of an operation within a rewrite can be inferred
// from a pdl.replace.
pdl.pattern @infer_type_from_operation_replace : benefit(1) {
  %type1 = type : i32
  %type2 = type
  %root = operation -> (%type1, %type2 : !pdl.type, !pdl.type)
  rewrite %root {
    %type3 = type
    %newOp = operation "foo.op" -> (%type1, %type3 : !pdl.type, !pdl.type)
    replace %root with %newOp
  }
}

// -----

// Check that the result type of an operation within a rewrite can be inferred
// from the result types of an operation within the match block.
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
  %type1 = type : i32
  %type2 = type
  %root = operation -> (%type1, %type2 : !pdl.type, !pdl.type)
  rewrite %root {
    %newOp = operation "foo.op" -> (%type1, %type2 : !pdl.type, !pdl.type)
  }
}

// -----

// Check that the result type of an operation within a rewrite can be inferred
// from the result types of an operation within the match block.
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
  %types = types
  %root = operation -> (%types : !pdl.range<type>)
  rewrite %root {
    %otherTypes = types : [i32, i64]
    %newOp = operation "foo.op" -> (%types, %otherTypes : !pdl.range<type>, !pdl.range<type>)
  }
}

// -----

// Check that the result type of an operation within a rewrite can be inferred
// from the type of an operand within the match block.
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
  %type1 = type
  %type2 = type
  %operand1 = operand : %type1
  %operand2 = operand : %type2
  %root = operation (%operand1, %operand2 : !pdl.value, !pdl.value)
  rewrite %root {
    %newOp = operation "foo.op" -> (%type1, %type2 : !pdl.type, !pdl.type)
  }
}

// -----

// Check that the result type of an operation within a rewrite can be inferred
// from the types of operands within the match block.
pdl.pattern @infer_type_from_type_used_in_match : benefit(1) {
  %types = types
  %operands = operands : %types
  %root = operation (%operands : !pdl.range<value>)
  rewrite %root {
    %newOp = operation "foo.op" -> (%types : !pdl.range<type>)
  }
}

// -----

pdl.pattern @apply_rewrite_with_no_results : benefit(1) {
  %root = operation
  rewrite %root {
    apply_native_rewrite "NativeRewrite"(%root : !pdl.operation)
  }
}

// -----

pdl.pattern @apply_constraint_with_no_results : benefit(1) {
  %root = operation
  apply_native_constraint "NativeConstraint"(%root : !pdl.operation)
  rewrite %root with "rewriter"
}

// -----

pdl.pattern @apply_constraint_with_results : benefit(1) {
  %root = operation
  %attr = apply_native_constraint "NativeConstraint"(%root : !pdl.operation) : !pdl.attribute
  rewrite %root {
    apply_native_rewrite "NativeRewrite"(%attr : !pdl.attribute)
  }
}

// -----

pdl.pattern @attribute_with_dict : benefit(1) {
  %root = operation
  rewrite %root {
    %attr = attribute = {some_unit_attr} attributes {pdl.special_attribute}
    apply_native_rewrite "NativeRewrite"(%attr : !pdl.attribute)
  }
}

// -----

// Check that we don't treat the trailing location of a pdl.attribute as the
// attribute value.

pdl.pattern @attribute_with_loc : benefit(1) {
  // CHECK-GENERIC: "pdl.attribute"
  // CHECK-GENERIC-NOT: value = loc
  %attr = attribute loc("bar")

  %root = operation {"attribute" = %attr}
  rewrite %root with "rewriter"
}