1// RUN: mlir-opt %s -test-pdl-bytecode-pass -split-input-file | FileCheck %s 2 3// Note: Tests here are written using the PDL Interpreter dialect to avoid 4// unnecessarily testing unnecessary aspects of the pattern compilation 5// pipeline. These tests are written such that we can focus solely on the 6// lowering/execution of the bytecode itself. 7 8//===----------------------------------------------------------------------===// 9// pdl_interp::ApplyConstraintOp 10//===----------------------------------------------------------------------===// 11 12module @patterns { 13 pdl_interp.func @matcher(%root : !pdl.operation) { 14 pdl_interp.apply_constraint "multi_entity_constraint"(%root, %root : !pdl.operation, !pdl.operation) -> ^pat, ^end 15 16 ^pat: 17 pdl_interp.apply_constraint "single_entity_constraint"(%root : !pdl.operation) -> ^pat2, ^end 18 19 ^pat2: 20 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 21 22 ^end: 23 pdl_interp.finalize 24 } 25 26 module @rewriters { 27 pdl_interp.func @success(%root : !pdl.operation) { 28 %op = pdl_interp.create_operation "test.replaced_by_pattern" 29 pdl_interp.erase %root 30 pdl_interp.finalize 31 } 32 } 33} 34 35// CHECK-LABEL: test.apply_constraint_1 36// CHECK: "test.replaced_by_pattern" 37module @ir attributes { test.apply_constraint_1 } { 38 "test.op"() { test_attr } : () -> () 39} 40 41// ----- 42 43module @patterns { 44 pdl_interp.func @matcher(%root : !pdl.operation) { 45 %results = pdl_interp.get_results of %root : !pdl.range<value> 46 %types = pdl_interp.get_value_type of %results : !pdl.range<type> 47 pdl_interp.apply_constraint "multi_entity_var_constraint"(%results, %types : !pdl.range<value>, !pdl.range<type>) -> ^pat, ^end 48 49 ^pat: 50 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 51 52 ^end: 53 pdl_interp.finalize 54 } 55 56 module @rewriters { 57 pdl_interp.func @success(%root : !pdl.operation) { 58 %op = pdl_interp.create_operation "test.replaced_by_pattern" 59 pdl_interp.erase %root 60 pdl_interp.finalize 61 } 62 } 63} 64 65// CHECK-LABEL: test.apply_constraint_2 66// CHECK-NOT: "test.replaced_by_pattern" 67// CHECK: "test.replaced_by_pattern" 68module @ir attributes { test.apply_constraint_2 } { 69 "test.failure_op"() { test_attr } : () -> () 70 "test.success_op"() : () -> (i32, i64) 71} 72 73// ----- 74 75// Test support for negated constraints. 76module @patterns { 77 pdl_interp.func @matcher(%root : !pdl.operation) { 78 %test_attr = pdl_interp.create_attribute unit 79 %attr = pdl_interp.get_attribute "test_attr" of %root 80 pdl_interp.are_equal %test_attr, %attr : !pdl.attribute -> ^pat, ^end 81 82 ^pat: 83 pdl_interp.apply_constraint "single_entity_constraint"(%root : !pdl.operation) {isNegated = true} -> ^pat1, ^end 84 85 ^pat1: 86 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 87 88 ^end: 89 pdl_interp.finalize 90 } 91 92 module @rewriters { 93 pdl_interp.func @success(%root : !pdl.operation) { 94 %op = pdl_interp.create_operation "test.replaced_by_pattern" 95 pdl_interp.erase %root 96 pdl_interp.finalize 97 } 98 } 99} 100 101// CHECK-LABEL: test.apply_constraint_3 102// CHECK-NEXT: "test.replaced_by_pattern" 103// CHECK-NOT: "test.replaced_by_pattern" 104 105module @ir attributes { test.apply_constraint_3 } { 106 "test.foo"() { test_attr } : () -> () 107 "test.op"() { test_attr } : () -> () 108} 109 110// ----- 111 112// Test returning a type from a native constraint. 113module @patterns { 114 pdl_interp.func @matcher(%root : !pdl.operation) { 115 pdl_interp.check_operation_name of %root is "test.success_op" -> ^pat, ^end 116 117 ^pat: 118 %new_type = pdl_interp.apply_constraint "op_constr_return_type"(%root : !pdl.operation) : !pdl.type -> ^pat2, ^end 119 120 ^pat2: 121 pdl_interp.record_match @rewriters::@success(%root, %new_type : !pdl.operation, !pdl.type) : benefit(1), loc([%root]) -> ^end 122 123 ^end: 124 pdl_interp.finalize 125 } 126 127 module @rewriters { 128 pdl_interp.func @success(%root : !pdl.operation, %new_type : !pdl.type) { 129 %op = pdl_interp.create_operation "test.replaced_by_pattern" -> (%new_type : !pdl.type) 130 pdl_interp.erase %root 131 pdl_interp.finalize 132 } 133 } 134} 135 136// CHECK-LABEL: test.apply_constraint_4 137// CHECK-NOT: "test.replaced_by_pattern" 138// CHECK: "test.replaced_by_pattern"() : () -> f32 139module @ir attributes { test.apply_constraint_4 } { 140 "test.failure_op"() : () -> () 141 "test.success_op"() : () -> () 142} 143 144// ----- 145 146// Test success and failure cases of native constraints with pdl.range results. 147module @patterns { 148 pdl_interp.func @matcher(%root : !pdl.operation) { 149 pdl_interp.check_operation_name of %root is "test.success_op" -> ^pat, ^end 150 151 ^pat: 152 %num_results = pdl_interp.create_attribute 2 : i32 153 %types = pdl_interp.apply_constraint "op_constr_return_type_range"(%root, %num_results : !pdl.operation, !pdl.attribute) : !pdl.range<type> -> ^pat1, ^end 154 155 ^pat1: 156 pdl_interp.record_match @rewriters::@success(%root, %types : !pdl.operation, !pdl.range<type>) : benefit(1), loc([%root]) -> ^end 157 158 ^end: 159 pdl_interp.finalize 160 } 161 162 module @rewriters { 163 pdl_interp.func @success(%root : !pdl.operation, %types : !pdl.range<type>) { 164 %op = pdl_interp.create_operation "test.replaced_by_pattern" -> (%types : !pdl.range<type>) 165 pdl_interp.erase %root 166 pdl_interp.finalize 167 } 168 } 169} 170 171// CHECK-LABEL: test.apply_constraint_5 172// CHECK-NOT: "test.replaced_by_pattern" 173// CHECK: "test.replaced_by_pattern"() : () -> (f32, f32) 174module @ir attributes { test.apply_constraint_5 } { 175 "test.failure_op"() : () -> () 176 "test.success_op"() : () -> () 177} 178 179// ----- 180 181//===----------------------------------------------------------------------===// 182// pdl_interp::ApplyRewriteOp 183//===----------------------------------------------------------------------===// 184 185module @patterns { 186 pdl_interp.func @matcher(%root : !pdl.operation) { 187 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 188 189 ^pat: 190 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 191 192 ^end: 193 pdl_interp.finalize 194 } 195 196 module @rewriters { 197 pdl_interp.func @success(%root : !pdl.operation) { 198 %operand = pdl_interp.get_operand 0 of %root 199 pdl_interp.apply_rewrite "rewriter"(%root, %operand : !pdl.operation, !pdl.value) 200 pdl_interp.finalize 201 } 202 } 203} 204 205// CHECK-LABEL: test.apply_rewrite_1 206// CHECK: %[[INPUT:.*]] = "test.op_input" 207// CHECK-NOT: "test.op" 208// CHECK: "test.success"(%[[INPUT]]) 209module @ir attributes { test.apply_rewrite_1 } { 210 %input = "test.op_input"() : () -> i32 211 "test.op"(%input) : (i32) -> () 212} 213 214// ----- 215 216module @patterns { 217 pdl_interp.func @matcher(%root : !pdl.operation) { 218 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 219 220 ^pat: 221 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 222 223 ^end: 224 pdl_interp.finalize 225 } 226 227 module @rewriters { 228 pdl_interp.func @success(%root : !pdl.operation) { 229 %op = pdl_interp.apply_rewrite "creator"(%root : !pdl.operation) : !pdl.operation 230 pdl_interp.erase %root 231 pdl_interp.finalize 232 } 233 } 234} 235 236// CHECK-LABEL: test.apply_rewrite_2 237// CHECK: "test.success" 238module @ir attributes { test.apply_rewrite_2 } { 239 "test.op"() : () -> () 240} 241 242// ----- 243 244module @patterns { 245 pdl_interp.func @matcher(%root : !pdl.operation) { 246 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 247 248 ^pat: 249 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 250 251 ^end: 252 pdl_interp.finalize 253 } 254 255 module @rewriters { 256 pdl_interp.func @success(%root : !pdl.operation) { 257 %operands, %types = pdl_interp.apply_rewrite "var_creator"(%root : !pdl.operation) : !pdl.range<value>, !pdl.range<type> 258 %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>) 259 pdl_interp.replace %root with (%operands : !pdl.range<value>) 260 pdl_interp.finalize 261 } 262 } 263} 264 265// CHECK-LABEL: test.apply_rewrite_3 266// CHECK: %[[OPERAND:.*]] = "test.producer" 267// CHECK: "test.success"(%[[OPERAND]]) : (i32) -> i32 268// CHECK: "test.consumer"(%[[OPERAND]]) 269module @ir attributes { test.apply_rewrite_3 } { 270 %first_operand = "test.producer"() : () -> (i32) 271 %operand = "test.op"(%first_operand) : (i32) -> (i32) 272 "test.consumer"(%operand) : (i32) -> () 273} 274 275// ----- 276 277module @patterns { 278 pdl_interp.func @matcher(%root : !pdl.operation) { 279 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 280 281 ^pat: 282 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 283 284 ^end: 285 pdl_interp.finalize 286 } 287 288 module @rewriters { 289 pdl_interp.func @success(%root : !pdl.operation) { 290 %attr = pdl_interp.apply_rewrite "str_creator" : !pdl.attribute 291 %type = pdl_interp.apply_rewrite "type_creator" : !pdl.type 292 %newOp = pdl_interp.create_operation "test.success" {"attr" = %attr} -> (%type : !pdl.type) 293 pdl_interp.erase %root 294 pdl_interp.finalize 295 } 296 } 297} 298 299// CHECK-LABEL: test.apply_rewrite_4 300// CHECK: "test.success"() {attr = "test.str"} : () -> f32 301module @ir attributes { test.apply_rewrite_4 } { 302 "test.op"() : () -> () 303} 304 305// ----- 306 307//===----------------------------------------------------------------------===// 308// pdl_interp::AreEqualOp 309//===----------------------------------------------------------------------===// 310 311module @patterns { 312 pdl_interp.func @matcher(%root : !pdl.operation) { 313 %test_attr = pdl_interp.create_attribute unit 314 %attr = pdl_interp.get_attribute "test_attr" of %root 315 pdl_interp.are_equal %test_attr, %attr : !pdl.attribute -> ^pat, ^end 316 317 ^pat: 318 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 319 320 ^end: 321 pdl_interp.finalize 322 } 323 324 module @rewriters { 325 pdl_interp.func @success(%root : !pdl.operation) { 326 %op = pdl_interp.create_operation "test.success" 327 pdl_interp.erase %root 328 pdl_interp.finalize 329 } 330 } 331} 332 333// CHECK-LABEL: test.are_equal_1 334// CHECK: "test.success" 335module @ir attributes { test.are_equal_1 } { 336 "test.op"() { test_attr } : () -> () 337} 338 339// ----- 340 341module @patterns { 342 pdl_interp.func @matcher(%root : !pdl.operation) { 343 %const_types = pdl_interp.create_types [i32, i64] 344 %results = pdl_interp.get_results of %root : !pdl.range<value> 345 %result_types = pdl_interp.get_value_type of %results : !pdl.range<type> 346 pdl_interp.are_equal %result_types, %const_types : !pdl.range<type> -> ^pat, ^end 347 348 ^pat: 349 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 350 351 ^end: 352 pdl_interp.finalize 353 } 354 355 module @rewriters { 356 pdl_interp.func @success(%root : !pdl.operation) { 357 %op = pdl_interp.create_operation "test.success" 358 pdl_interp.erase %root 359 pdl_interp.finalize 360 } 361 } 362} 363 364// CHECK-LABEL: test.are_equal_2 365// CHECK: "test.not_equal" 366// CHECK: "test.success" 367// CHECK-NOT: "test.op" 368module @ir attributes { test.are_equal_2 } { 369 "test.not_equal"() : () -> (i32) 370 "test.op"() : () -> (i32, i64) 371} 372 373// ----- 374 375//===----------------------------------------------------------------------===// 376// pdl_interp::BranchOp 377//===----------------------------------------------------------------------===// 378 379module @patterns { 380 pdl_interp.func @matcher(%root : !pdl.operation) { 381 pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end 382 383 ^pat1: 384 pdl_interp.branch ^pat2 385 386 ^pat2: 387 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end 388 389 ^end: 390 pdl_interp.finalize 391 } 392 393 module @rewriters { 394 pdl_interp.func @success(%root : !pdl.operation) { 395 %op = pdl_interp.create_operation "test.success" 396 pdl_interp.erase %root 397 pdl_interp.finalize 398 } 399 } 400} 401 402// CHECK-LABEL: test.branch_1 403// CHECK: "test.success" 404module @ir attributes { test.branch_1 } { 405 "test.op"() : () -> () 406} 407 408// ----- 409 410//===----------------------------------------------------------------------===// 411// pdl_interp::CheckAttributeOp 412//===----------------------------------------------------------------------===// 413 414module @patterns { 415 pdl_interp.func @matcher(%root : !pdl.operation) { 416 %attr = pdl_interp.get_attribute "test_attr" of %root 417 pdl_interp.check_attribute %attr is unit -> ^pat, ^end 418 419 ^pat: 420 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 421 422 ^end: 423 pdl_interp.finalize 424 } 425 426 module @rewriters { 427 pdl_interp.func @success(%root : !pdl.operation) { 428 %op = pdl_interp.create_operation "test.success" 429 pdl_interp.erase %root 430 pdl_interp.finalize 431 } 432 } 433} 434 435// CHECK-LABEL: test.check_attribute_1 436// CHECK: "test.success" 437module @ir attributes { test.check_attribute_1 } { 438 "test.op"() { test_attr } : () -> () 439} 440 441// ----- 442 443//===----------------------------------------------------------------------===// 444// pdl_interp::CheckOperandCountOp 445//===----------------------------------------------------------------------===// 446 447module @patterns { 448 pdl_interp.func @matcher(%root : !pdl.operation) { 449 pdl_interp.check_operand_count of %root is at_least 1 -> ^exact_check, ^end 450 451 ^exact_check: 452 pdl_interp.check_operand_count of %root is 2 -> ^pat, ^end 453 454 ^pat: 455 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 456 457 ^end: 458 pdl_interp.finalize 459 } 460 461 module @rewriters { 462 pdl_interp.func @success(%root : !pdl.operation) { 463 %op = pdl_interp.create_operation "test.success" 464 pdl_interp.erase %root 465 pdl_interp.finalize 466 } 467 } 468} 469 470// CHECK-LABEL: test.check_operand_count_1 471// CHECK: "test.op"() : () -> i32 472// CHECK: "test.success" 473module @ir attributes { test.check_operand_count_1 } { 474 %operand = "test.op"() : () -> i32 475 "test.op"(%operand, %operand) : (i32, i32) -> () 476} 477 478// ----- 479 480//===----------------------------------------------------------------------===// 481// pdl_interp::CheckOperationNameOp 482//===----------------------------------------------------------------------===// 483 484module @patterns { 485 pdl_interp.func @matcher(%root : !pdl.operation) { 486 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 487 488 ^pat: 489 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 490 491 ^end: 492 pdl_interp.finalize 493 } 494 495 module @rewriters { 496 pdl_interp.func @success(%root : !pdl.operation) { 497 %op = pdl_interp.create_operation "test.success" 498 pdl_interp.erase %root 499 pdl_interp.finalize 500 } 501 } 502} 503 504// CHECK-LABEL: test.check_operation_name_1 505// CHECK: "test.success" 506module @ir attributes { test.check_operation_name_1 } { 507 "test.op"() : () -> () 508} 509 510// ----- 511 512//===----------------------------------------------------------------------===// 513// pdl_interp::CheckResultCountOp 514//===----------------------------------------------------------------------===// 515 516module @patterns { 517 pdl_interp.func @matcher(%root : !pdl.operation) { 518 pdl_interp.check_result_count of %root is at_least 1 -> ^exact_check, ^end 519 520 ^exact_check: 521 pdl_interp.check_result_count of %root is 2 -> ^pat, ^end 522 523 ^pat: 524 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 525 526 ^end: 527 pdl_interp.finalize 528 } 529 530 module @rewriters { 531 pdl_interp.func @success(%root : !pdl.operation) { 532 %op = pdl_interp.create_operation "test.success" 533 pdl_interp.erase %root 534 pdl_interp.finalize 535 } 536 } 537} 538 539// CHECK-LABEL: test.check_result_count_1 540// CHECK: "test.op"() : () -> i32 541// CHECK: "test.success"() : () -> () 542// CHECK-NOT: "test.op"() : () -> (i32, i32) 543module @ir attributes { test.check_result_count_1 } { 544 "test.op"() : () -> i32 545 "test.op"() : () -> (i32, i32) 546} 547 548// ----- 549 550//===----------------------------------------------------------------------===// 551// pdl_interp::CheckTypeOp 552//===----------------------------------------------------------------------===// 553 554module @patterns { 555 pdl_interp.func @matcher(%root : !pdl.operation) { 556 %attr = pdl_interp.get_attribute "test_attr" of %root 557 pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end 558 559 ^pat1: 560 %type = pdl_interp.get_attribute_type of %attr 561 pdl_interp.check_type %type is i32 -> ^pat2, ^end 562 563 ^pat2: 564 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 565 566 ^end: 567 pdl_interp.finalize 568 } 569 570 module @rewriters { 571 pdl_interp.func @success(%root : !pdl.operation) { 572 %op = pdl_interp.create_operation "test.success" 573 pdl_interp.erase %root 574 pdl_interp.finalize 575 } 576 } 577} 578 579// CHECK-LABEL: test.check_type_1 580// CHECK: "test.success" 581module @ir attributes { test.check_type_1 } { 582 "test.op"() { test_attr = 10 : i32 } : () -> () 583} 584 585// ----- 586 587//===----------------------------------------------------------------------===// 588// pdl_interp::CheckTypesOp 589//===----------------------------------------------------------------------===// 590 591module @patterns { 592 pdl_interp.func @matcher(%root : !pdl.operation) { 593 %results = pdl_interp.get_results of %root : !pdl.range<value> 594 %result_types = pdl_interp.get_value_type of %results : !pdl.range<type> 595 pdl_interp.check_types %result_types are [i32] -> ^pat2, ^end 596 597 ^pat2: 598 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 599 600 ^end: 601 pdl_interp.finalize 602 } 603 604 module @rewriters { 605 pdl_interp.func @success(%root : !pdl.operation) { 606 %op = pdl_interp.create_operation "test.success" 607 pdl_interp.erase %root 608 pdl_interp.finalize 609 } 610 } 611} 612 613// CHECK-LABEL: test.check_types_1 614// CHECK: "test.op"() : () -> (i32, i64) 615// CHECK: "test.success" 616// CHECK-NOT: "test.op"() : () -> i32 617module @ir attributes { test.check_types_1 } { 618 "test.op"() : () -> (i32, i64) 619 "test.op"() : () -> i32 620} 621 622// ----- 623 624//===----------------------------------------------------------------------===// 625// pdl_interp::ContinueOp 626//===----------------------------------------------------------------------===// 627 628// Fully tested within the tests for other operations. 629 630//===----------------------------------------------------------------------===// 631// pdl_interp::CreateAttributeOp 632//===----------------------------------------------------------------------===// 633 634// Fully tested within the tests for other operations. 635 636//===----------------------------------------------------------------------===// 637// pdl_interp::CreateOperationOp 638//===----------------------------------------------------------------------===// 639 640// Unused operation to force loading the `arithmetic` dialect for the 641// test of type inferrence. 642arith.constant 10 643 644// Test support for inferring the types of an operation. 645module @patterns { 646 pdl_interp.func @matcher(%root : !pdl.operation) { 647 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 648 649 ^pat: 650 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 651 652 ^end: 653 pdl_interp.finalize 654 } 655 656 module @rewriters { 657 pdl_interp.func @success(%root : !pdl.operation) { 658 %attr = pdl_interp.create_attribute true 659 %cst = pdl_interp.create_operation "arith.constant" {"value" = %attr} -> <inferred> 660 %cstResults = pdl_interp.get_results of %cst : !pdl.range<value> 661 %op = pdl_interp.create_operation "test.success"(%cstResults : !pdl.range<value>) 662 pdl_interp.erase %root 663 pdl_interp.finalize 664 } 665 } 666} 667 668// CHECK-LABEL: test.create_op_infer_results 669// CHECK: %[[CST:.*]] = arith.constant true 670// CHECK: "test.success"(%[[CST]]) 671module @ir attributes { test.create_op_infer_results } { 672 %results:2 = "test.op"() : () -> (i64, i64) 673} 674 675// ----- 676 677//===----------------------------------------------------------------------===// 678// pdl_interp::CreateRangeOp 679//===----------------------------------------------------------------------===// 680 681module @patterns { 682 pdl_interp.func @matcher(%root : !pdl.operation) { 683 pdl_interp.check_operand_count of %root is 2 -> ^pat1, ^end 684 685 ^pat1: 686 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 687 688 ^end: 689 pdl_interp.finalize 690 } 691 692 module @rewriters { 693 pdl_interp.func @success(%root: !pdl.operation) { 694 %rootOperand = pdl_interp.get_operand 0 of %root 695 %rootOperands = pdl_interp.get_operands of %root : !pdl.range<value> 696 %operandRange = pdl_interp.create_range %rootOperand, %rootOperands : !pdl.value, !pdl.range<value> 697 698 %operandType = pdl_interp.get_value_type of %rootOperand : !pdl.type 699 %operandTypes = pdl_interp.get_value_type of %rootOperands : !pdl.range<type> 700 %typeRange = pdl_interp.create_range %operandType, %operandTypes : !pdl.type, !pdl.range<type> 701 702 %op = pdl_interp.create_operation "test.success"(%operandRange : !pdl.range<value>) -> (%typeRange : !pdl.range<type>) 703 pdl_interp.erase %root 704 pdl_interp.finalize 705 } 706 } 707} 708 709// CHECK-LABEL: test.create_range_1 710// CHECK: %[[INPUTS:.*]]:2 = "test.input"() 711// CHECK: "test.success"(%[[INPUTS]]#0, %[[INPUTS]]#0, %[[INPUTS]]#1) : (i32, i32, i32) -> (i32, i32, i32) 712module @ir attributes { test.create_range_1 } { 713 %values:2 = "test.input"() : () -> (i32, i32) 714 "test.op"(%values#0, %values#1) : (i32, i32) -> () 715} 716 717// ----- 718 719//===----------------------------------------------------------------------===// 720// pdl_interp::CreateTypeOp 721//===----------------------------------------------------------------------===// 722 723module @patterns { 724 pdl_interp.func @matcher(%root : !pdl.operation) { 725 %attr = pdl_interp.get_attribute "test_attr" of %root 726 pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end 727 728 ^pat1: 729 %test_type = pdl_interp.create_type i32 730 %type = pdl_interp.get_attribute_type of %attr 731 pdl_interp.are_equal %type, %test_type : !pdl.type -> ^pat2, ^end 732 733 ^pat2: 734 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 735 736 ^end: 737 pdl_interp.finalize 738 } 739 740 module @rewriters { 741 pdl_interp.func @success(%root : !pdl.operation) { 742 %op = pdl_interp.create_operation "test.success" 743 pdl_interp.erase %root 744 pdl_interp.finalize 745 } 746 } 747} 748 749// CHECK-LABEL: test.create_type_1 750// CHECK: "test.success" 751module @ir attributes { test.create_type_1 } { 752 "test.op"() { test_attr = 0 : i32 } : () -> () 753} 754 755// ----- 756 757//===----------------------------------------------------------------------===// 758// pdl_interp::CreateTypesOp 759//===----------------------------------------------------------------------===// 760 761// Fully tested within the tests for other operations. 762 763//===----------------------------------------------------------------------===// 764// pdl_interp::EraseOp 765//===----------------------------------------------------------------------===// 766 767// Fully tested within the tests for other operations. 768 769//===----------------------------------------------------------------------===// 770// pdl_interp::ExtractOp 771//===----------------------------------------------------------------------===// 772 773module @patterns { 774 pdl_interp.func @matcher(%root : !pdl.operation) { 775 %val = pdl_interp.get_result 0 of %root 776 %ops = pdl_interp.get_users of %val : !pdl.value 777 %op1 = pdl_interp.extract 1 of %ops : !pdl.operation 778 pdl_interp.is_not_null %op1 : !pdl.operation -> ^success, ^end 779 ^success: 780 pdl_interp.record_match @rewriters::@success(%op1 : !pdl.operation) : benefit(1), loc([%root]) -> ^end 781 ^end: 782 pdl_interp.finalize 783 } 784 785 module @rewriters { 786 pdl_interp.func @success(%matched : !pdl.operation) { 787 %op = pdl_interp.create_operation "test.success" 788 pdl_interp.erase %matched 789 pdl_interp.finalize 790 } 791 } 792} 793 794// CHECK-LABEL: test.extract_op 795// CHECK: "test.success" 796// CHECK: %[[OPERAND:.*]] = "test.op" 797// CHECK: "test.op"(%[[OPERAND]]) 798module @ir attributes { test.extract_op } { 799 %operand = "test.op"() : () -> i32 800 "test.op"(%operand) : (i32) -> (i32) 801 "test.op"(%operand, %operand) : (i32, i32) -> (i32) 802} 803 804// ----- 805 806module @patterns { 807 pdl_interp.func @matcher(%root : !pdl.operation) { 808 %vals = pdl_interp.get_results of %root : !pdl.range<value> 809 %types = pdl_interp.get_value_type of %vals : !pdl.range<type> 810 %type1 = pdl_interp.extract 1 of %types : !pdl.type 811 pdl_interp.is_not_null %type1 : !pdl.type -> ^success, ^end 812 ^success: 813 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 814 ^end: 815 pdl_interp.finalize 816 } 817 818 module @rewriters { 819 pdl_interp.func @success(%matched : !pdl.operation) { 820 %op = pdl_interp.create_operation "test.success" 821 pdl_interp.erase %matched 822 pdl_interp.finalize 823 } 824 } 825} 826 827// CHECK-LABEL: test.extract_type 828// CHECK: %[[OPERAND:.*]] = "test.op" 829// CHECK: "test.success" 830// CHECK: "test.op"(%[[OPERAND]]) 831module @ir attributes { test.extract_type } { 832 %operand = "test.op"() : () -> i32 833 "test.op"(%operand) : (i32) -> (i32, i32) 834 "test.op"(%operand) : (i32) -> (i32) 835} 836 837// ----- 838 839module @patterns { 840 pdl_interp.func @matcher(%root : !pdl.operation) { 841 %vals = pdl_interp.get_results of %root : !pdl.range<value> 842 %val1 = pdl_interp.extract 1 of %vals : !pdl.value 843 pdl_interp.is_not_null %val1 : !pdl.value -> ^success, ^end 844 ^success: 845 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 846 ^end: 847 pdl_interp.finalize 848 } 849 850 module @rewriters { 851 pdl_interp.func @success(%matched : !pdl.operation) { 852 %op = pdl_interp.create_operation "test.success" 853 pdl_interp.erase %matched 854 pdl_interp.finalize 855 } 856 } 857} 858 859// CHECK-LABEL: test.extract_value 860// CHECK: %[[OPERAND:.*]] = "test.op" 861// CHECK: "test.success" 862// CHECK: "test.op"(%[[OPERAND]]) 863module @ir attributes { test.extract_value } { 864 %operand = "test.op"() : () -> i32 865 "test.op"(%operand) : (i32) -> (i32, i32) 866 "test.op"(%operand) : (i32) -> (i32) 867} 868 869// ----- 870 871//===----------------------------------------------------------------------===// 872// pdl_interp::FinalizeOp 873//===----------------------------------------------------------------------===// 874 875// Fully tested within the tests for other operations. 876 877//===----------------------------------------------------------------------===// 878// pdl_interp::ForEachOp 879//===----------------------------------------------------------------------===// 880 881module @patterns { 882 pdl_interp.func @matcher(%root : !pdl.operation) { 883 %val1 = pdl_interp.get_result 0 of %root 884 %ops1 = pdl_interp.get_users of %val1 : !pdl.value 885 pdl_interp.foreach %op1 : !pdl.operation in %ops1 { 886 %val2 = pdl_interp.get_result 0 of %op1 887 %ops2 = pdl_interp.get_users of %val2 : !pdl.value 888 pdl_interp.foreach %op2 : !pdl.operation in %ops2 { 889 pdl_interp.record_match @rewriters::@success(%op2 : !pdl.operation) : benefit(1), loc([%root]) -> ^cont 890 ^cont: 891 pdl_interp.continue 892 } -> ^cont 893 ^cont: 894 pdl_interp.continue 895 } -> ^end 896 ^end: 897 pdl_interp.finalize 898 } 899 900 module @rewriters { 901 pdl_interp.func @success(%matched : !pdl.operation) { 902 %op = pdl_interp.create_operation "test.success" 903 pdl_interp.erase %matched 904 pdl_interp.finalize 905 } 906 } 907} 908 909// CHECK-LABEL: test.foreach 910// CHECK: "test.success" 911// CHECK: "test.success" 912// CHECK: "test.success" 913// CHECK: "test.success" 914// CHECK: %[[ROOT:.*]] = "test.op" 915// CHECK: %[[VALA:.*]] = "test.op"(%[[ROOT]]) 916// CHECK: %[[VALB:.*]] = "test.op"(%[[ROOT]]) 917module @ir attributes { test.foreach } { 918 %root = "test.op"() : () -> i32 919 %valA = "test.op"(%root) : (i32) -> (i32) 920 "test.op"(%valA) : (i32) -> (i32) 921 "test.op"(%valA) : (i32) -> (i32) 922 %valB = "test.op"(%root) : (i32) -> (i32) 923 "test.op"(%valB) : (i32) -> (i32) 924 "test.op"(%valB) : (i32) -> (i32) 925} 926 927// ----- 928 929//===----------------------------------------------------------------------===// 930// pdl_interp::GetUsersOp 931//===----------------------------------------------------------------------===// 932 933module @patterns { 934 pdl_interp.func @matcher(%root : !pdl.operation) { 935 %val = pdl_interp.get_result 0 of %root 936 %ops = pdl_interp.get_users of %val : !pdl.value 937 pdl_interp.foreach %op : !pdl.operation in %ops { 938 pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont 939 ^cont: 940 pdl_interp.continue 941 } -> ^end 942 ^end: 943 pdl_interp.finalize 944 } 945 946 module @rewriters { 947 pdl_interp.func @success(%matched : !pdl.operation) { 948 %op = pdl_interp.create_operation "test.success" 949 pdl_interp.erase %matched 950 pdl_interp.finalize 951 } 952 } 953} 954 955// CHECK-LABEL: test.get_users_of_value 956// CHECK: "test.success" 957// CHECK: "test.success" 958// CHECK: %[[OPERAND:.*]] = "test.op" 959module @ir attributes { test.get_users_of_value } { 960 %operand = "test.op"() : () -> i32 961 "test.op"(%operand) : (i32) -> (i32) 962 "test.op"(%operand, %operand) : (i32, i32) -> (i32) 963} 964 965// ----- 966 967module @patterns { 968 pdl_interp.func @matcher(%root : !pdl.operation) { 969 pdl_interp.check_result_count of %root is at_least 2 -> ^next, ^end 970 ^next: 971 %vals = pdl_interp.get_results of %root : !pdl.range<value> 972 %ops = pdl_interp.get_users of %vals : !pdl.range<value> 973 pdl_interp.foreach %op : !pdl.operation in %ops { 974 pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont 975 ^cont: 976 pdl_interp.continue 977 } -> ^end 978 ^end: 979 pdl_interp.finalize 980 } 981 982 module @rewriters { 983 pdl_interp.func @success(%matched : !pdl.operation) { 984 %op = pdl_interp.create_operation "test.success" 985 pdl_interp.erase %matched 986 pdl_interp.finalize 987 } 988 } 989} 990 991// CHECK-LABEL: test.get_all_users_of_range 992// CHECK: "test.success" 993// CHECK: "test.success" 994// CHECK: %[[OPERANDS:.*]]:2 = "test.op" 995module @ir attributes { test.get_all_users_of_range } { 996 %operands:2 = "test.op"() : () -> (i32, i32) 997 "test.op"(%operands#0) : (i32) -> (i32) 998 "test.op"(%operands#1) : (i32) -> (i32) 999} 1000 1001// ----- 1002 1003module @patterns { 1004 pdl_interp.func @matcher(%root : !pdl.operation) { 1005 pdl_interp.check_result_count of %root is at_least 2 -> ^next, ^end 1006 ^next: 1007 %vals = pdl_interp.get_results of %root : !pdl.range<value> 1008 %val = pdl_interp.extract 0 of %vals : !pdl.value 1009 %ops = pdl_interp.get_users of %val : !pdl.value 1010 pdl_interp.foreach %op : !pdl.operation in %ops { 1011 pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont 1012 ^cont: 1013 pdl_interp.continue 1014 } -> ^end 1015 ^end: 1016 pdl_interp.finalize 1017 } 1018 1019 module @rewriters { 1020 pdl_interp.func @success(%matched : !pdl.operation) { 1021 %op = pdl_interp.create_operation "test.success" 1022 pdl_interp.erase %matched 1023 pdl_interp.finalize 1024 } 1025 } 1026} 1027 1028// CHECK-LABEL: test.get_first_users_of_range 1029// CHECK: "test.success" 1030// CHECK: %[[OPERANDS:.*]]:2 = "test.op" 1031// CHECK: "test.op" 1032module @ir attributes { test.get_first_users_of_range } { 1033 %operands:2 = "test.op"() : () -> (i32, i32) 1034 "test.op"(%operands#0) : (i32) -> (i32) 1035 "test.op"(%operands#1) : (i32) -> (i32) 1036} 1037 1038// ----- 1039 1040//===----------------------------------------------------------------------===// 1041// pdl_interp::GetAttributeOp 1042//===----------------------------------------------------------------------===// 1043 1044// Fully tested within the tests for other operations. 1045 1046//===----------------------------------------------------------------------===// 1047// pdl_interp::GetAttributeTypeOp 1048//===----------------------------------------------------------------------===// 1049 1050// Fully tested within the tests for other operations. 1051 1052//===----------------------------------------------------------------------===// 1053// pdl_interp::GetDefiningOpOp 1054//===----------------------------------------------------------------------===// 1055 1056module @patterns { 1057 pdl_interp.func @matcher(%root : !pdl.operation) { 1058 pdl_interp.check_operand_count of %root is 5 -> ^pat1, ^end 1059 1060 ^pat1: 1061 %operand0 = pdl_interp.get_operand 0 of %root 1062 %operand4 = pdl_interp.get_operand 4 of %root 1063 %defOp0 = pdl_interp.get_defining_op of %operand0 : !pdl.value 1064 %defOp4 = pdl_interp.get_defining_op of %operand4 : !pdl.value 1065 pdl_interp.are_equal %defOp0, %defOp4 : !pdl.operation -> ^pat2, ^end 1066 1067 ^pat2: 1068 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1069 1070 ^end: 1071 pdl_interp.finalize 1072 } 1073 1074 module @rewriters { 1075 pdl_interp.func @success(%root : !pdl.operation) { 1076 %op = pdl_interp.create_operation "test.success" 1077 pdl_interp.erase %root 1078 pdl_interp.finalize 1079 } 1080 } 1081} 1082 1083// CHECK-LABEL: test.get_defining_op_1 1084// CHECK: %[[OPERAND0:.*]] = "test.op" 1085// CHECK: %[[OPERAND1:.*]] = "test.op" 1086// CHECK: "test.success" 1087// CHECK: "test.op"(%[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND1]]) 1088module @ir attributes { test.get_defining_op_1 } { 1089 %operand = "test.op"() : () -> i32 1090 %other_operand = "test.op"() : () -> i32 1091 "test.op"(%operand, %operand, %operand, %operand, %operand) : (i32, i32, i32, i32, i32) -> () 1092 "test.op"(%operand, %operand, %operand, %operand, %other_operand) : (i32, i32, i32, i32, i32) -> () 1093} 1094 1095// ----- 1096 1097//===----------------------------------------------------------------------===// 1098// pdl_interp::GetOperandOp 1099//===----------------------------------------------------------------------===// 1100 1101// Fully tested within the tests for other operations. 1102 1103//===----------------------------------------------------------------------===// 1104// pdl_interp::GetOperandsOp 1105//===----------------------------------------------------------------------===// 1106 1107module @patterns { 1108 pdl_interp.func @matcher(%root : !pdl.operation) { 1109 pdl_interp.check_operand_count of %root is 2 -> ^pat1, ^end 1110 1111 ^pat1: 1112 %operands = pdl_interp.get_operands 0 of %root : !pdl.range<value> 1113 %full_operands = pdl_interp.get_operands of %root : !pdl.range<value> 1114 pdl_interp.are_equal %operands, %full_operands : !pdl.range<value> -> ^pat2, ^end 1115 1116 ^pat2: 1117 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1118 1119 ^end: 1120 pdl_interp.finalize 1121 } 1122 1123 module @rewriters { 1124 pdl_interp.func @success(%root : !pdl.operation) { 1125 %op = pdl_interp.create_operation "test.success" 1126 pdl_interp.erase %root 1127 pdl_interp.finalize 1128 } 1129 } 1130} 1131 1132// CHECK-LABEL: test.get_operands_1 1133// CHECK: "test.success" 1134module @ir attributes { test.get_operands_1 } { 1135 %inputs:2 = "test.producer"() : () -> (i32, i32) 1136 "test.op"(%inputs#0, %inputs#1) : (i32, i32) -> () 1137} 1138 1139// ----- 1140 1141// Test all of the various combinations related to `AttrSizedOperandSegments`. 1142module @patterns { 1143 pdl_interp.func @matcher(%root : !pdl.operation) { 1144 pdl_interp.check_operation_name of %root is "test.attr_sized_operands" -> ^pat1, ^end 1145 1146 ^pat1: 1147 %operands_0 = pdl_interp.get_operands 0 of %root : !pdl.range<value> 1148 pdl_interp.is_not_null %operands_0 : !pdl.range<value> -> ^pat2, ^end 1149 1150 ^pat2: 1151 %operands_0_single = pdl_interp.get_operands 0 of %root : !pdl.value 1152 pdl_interp.is_not_null %operands_0_single : !pdl.value -> ^end, ^pat3 1153 1154 ^pat3: 1155 %operands_1 = pdl_interp.get_operands 1 of %root : !pdl.range<value> 1156 pdl_interp.is_not_null %operands_1 : !pdl.range<value> -> ^pat4, ^end 1157 1158 ^pat4: 1159 %operands_1_single = pdl_interp.get_operands 1 of %root : !pdl.value 1160 pdl_interp.is_not_null %operands_1_single : !pdl.value -> ^end, ^pat5 1161 1162 ^pat5: 1163 %operands_2 = pdl_interp.get_operands 2 of %root : !pdl.range<value> 1164 pdl_interp.is_not_null %operands_2 : !pdl.range<value> -> ^pat6, ^end 1165 1166 ^pat6: 1167 %operands_2_single = pdl_interp.get_operands 2 of %root : !pdl.value 1168 pdl_interp.is_not_null %operands_2_single : !pdl.value -> ^pat7, ^end 1169 1170 ^pat7: 1171 %invalid_operands = pdl_interp.get_operands 50 of %root : !pdl.value 1172 pdl_interp.is_not_null %invalid_operands : !pdl.value -> ^end, ^pat8 1173 1174 ^pat8: 1175 pdl_interp.record_match @rewriters::@success(%root, %operands_0, %operands_1, %operands_2, %operands_2_single : !pdl.operation, !pdl.range<value>, !pdl.range<value>, !pdl.range<value>, !pdl.value) : benefit(1), loc([%root]) -> ^end 1176 1177 1178 ^end: 1179 pdl_interp.finalize 1180 } 1181 1182 module @rewriters { 1183 pdl_interp.func @success(%root: !pdl.operation, %operands_0: !pdl.range<value>, %operands_1: !pdl.range<value>, %operands_2: !pdl.range<value>, %operands_2_single: !pdl.value) { 1184 %op0 = pdl_interp.create_operation "test.success"(%operands_0 : !pdl.range<value>) 1185 %op1 = pdl_interp.create_operation "test.success"(%operands_1 : !pdl.range<value>) 1186 %op2 = pdl_interp.create_operation "test.success"(%operands_2 : !pdl.range<value>) 1187 %op3 = pdl_interp.create_operation "test.success"(%operands_2_single : !pdl.value) 1188 pdl_interp.erase %root 1189 pdl_interp.finalize 1190 } 1191 } 1192} 1193 1194// CHECK-LABEL: test.get_operands_2 1195// CHECK-NEXT: %[[INPUTS:.*]]:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32) 1196// CHECK-NEXT: "test.success"() : () -> () 1197// CHECK-NEXT: "test.success"(%[[INPUTS]]#0, %[[INPUTS]]#1, %[[INPUTS]]#2, %[[INPUTS]]#3) : (i32, i32, i32, i32) -> () 1198// CHECK-NEXT: "test.success"(%[[INPUTS]]#4) : (i32) -> () 1199// CHECK-NEXT: "test.success"(%[[INPUTS]]#4) : (i32) -> () 1200module @ir attributes { test.get_operands_2 } { 1201 %inputs:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32) 1202 "test.attr_sized_operands"(%inputs#0, %inputs#1, %inputs#2, %inputs#3, %inputs#4) {operandSegmentSizes = array<i32: 0, 4, 1, 0>} : (i32, i32, i32, i32, i32) -> () 1203} 1204 1205// ----- 1206 1207//===----------------------------------------------------------------------===// 1208// pdl_interp::GetResultOp 1209//===----------------------------------------------------------------------===// 1210 1211module @patterns { 1212 pdl_interp.func @matcher(%root : !pdl.operation) { 1213 pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end 1214 1215 ^pat1: 1216 %result0 = pdl_interp.get_result 0 of %root 1217 %result4 = pdl_interp.get_result 4 of %root 1218 %result0_type = pdl_interp.get_value_type of %result0 : !pdl.type 1219 %result4_type = pdl_interp.get_value_type of %result4 : !pdl.type 1220 pdl_interp.are_equal %result0_type, %result4_type : !pdl.type -> ^pat2, ^end 1221 1222 ^pat2: 1223 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1224 1225 ^end: 1226 pdl_interp.finalize 1227 } 1228 1229 module @rewriters { 1230 pdl_interp.func @success(%root : !pdl.operation) { 1231 %op = pdl_interp.create_operation "test.success" 1232 pdl_interp.erase %root 1233 pdl_interp.finalize 1234 } 1235 } 1236} 1237 1238// CHECK-LABEL: test.get_result_1 1239// CHECK: "test.success" 1240// CHECK: "test.op"() : () -> (i32, i32, i32, i32, i64) 1241module @ir attributes { test.get_result_1 } { 1242 %a:5 = "test.op"() : () -> (i32, i32, i32, i32, i32) 1243 %b:5 = "test.op"() : () -> (i32, i32, i32, i32, i64) 1244} 1245 1246// ----- 1247 1248//===----------------------------------------------------------------------===// 1249// pdl_interp::GetResultsOp 1250//===----------------------------------------------------------------------===// 1251 1252module @patterns { 1253 pdl_interp.func @matcher(%root : !pdl.operation) { 1254 pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end 1255 1256 ^pat1: 1257 %results = pdl_interp.get_results 0 of %root : !pdl.range<value> 1258 %full_results = pdl_interp.get_results of %root : !pdl.range<value> 1259 pdl_interp.are_equal %results, %full_results : !pdl.range<value> -> ^pat2, ^end 1260 1261 ^pat2: 1262 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1263 1264 ^end: 1265 pdl_interp.finalize 1266 } 1267 1268 module @rewriters { 1269 pdl_interp.func @success(%root : !pdl.operation) { 1270 %op = pdl_interp.create_operation "test.success" 1271 pdl_interp.erase %root 1272 pdl_interp.finalize 1273 } 1274 } 1275} 1276 1277// CHECK-LABEL: test.get_results_1 1278// CHECK: "test.success" 1279module @ir attributes { test.get_results_1 } { 1280 %a:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32) 1281} 1282 1283// ----- 1284 1285// Test all of the various combinations related to `AttrSizedResultSegments`. 1286module @patterns { 1287 pdl_interp.func @matcher(%root : !pdl.operation) { 1288 pdl_interp.check_operation_name of %root is "test.attr_sized_results" -> ^pat1, ^end 1289 1290 ^pat1: 1291 %results_0 = pdl_interp.get_results 0 of %root : !pdl.range<value> 1292 pdl_interp.is_not_null %results_0 : !pdl.range<value> -> ^pat2, ^end 1293 1294 ^pat2: 1295 %results_0_single = pdl_interp.get_results 0 of %root : !pdl.value 1296 pdl_interp.is_not_null %results_0_single : !pdl.value -> ^end, ^pat3 1297 1298 ^pat3: 1299 %results_1 = pdl_interp.get_results 1 of %root : !pdl.range<value> 1300 pdl_interp.is_not_null %results_1 : !pdl.range<value> -> ^pat4, ^end 1301 1302 ^pat4: 1303 %results_1_single = pdl_interp.get_results 1 of %root : !pdl.value 1304 pdl_interp.is_not_null %results_1_single : !pdl.value -> ^end, ^pat5 1305 1306 ^pat5: 1307 %results_2 = pdl_interp.get_results 2 of %root : !pdl.range<value> 1308 pdl_interp.is_not_null %results_2 : !pdl.range<value> -> ^pat6, ^end 1309 1310 ^pat6: 1311 %results_2_single = pdl_interp.get_results 2 of %root : !pdl.value 1312 pdl_interp.is_not_null %results_2_single : !pdl.value -> ^pat7, ^end 1313 1314 ^pat7: 1315 %invalid_results = pdl_interp.get_results 50 of %root : !pdl.value 1316 pdl_interp.is_not_null %invalid_results : !pdl.value -> ^end, ^pat8 1317 1318 ^pat8: 1319 pdl_interp.record_match @rewriters::@success(%root, %results_0, %results_1, %results_2, %results_2_single : !pdl.operation, !pdl.range<value>, !pdl.range<value>, !pdl.range<value>, !pdl.value) : benefit(1), loc([%root]) -> ^end 1320 1321 1322 ^end: 1323 pdl_interp.finalize 1324 } 1325 1326 module @rewriters { 1327 pdl_interp.func @success(%root: !pdl.operation, %results_0: !pdl.range<value>, %results_1: !pdl.range<value>, %results_2: !pdl.range<value>, %results_2_single: !pdl.value) { 1328 %results_0_types = pdl_interp.get_value_type of %results_0 : !pdl.range<type> 1329 %results_1_types = pdl_interp.get_value_type of %results_1 : !pdl.range<type> 1330 %results_2_types = pdl_interp.get_value_type of %results_2 : !pdl.range<type> 1331 %results_2_single_types = pdl_interp.get_value_type of %results_2_single : !pdl.type 1332 1333 %op0 = pdl_interp.create_operation "test.success" -> (%results_0_types : !pdl.range<type>) 1334 %op1 = pdl_interp.create_operation "test.success" -> (%results_1_types : !pdl.range<type>) 1335 %op2 = pdl_interp.create_operation "test.success" -> (%results_2_types : !pdl.range<type>) 1336 %op3 = pdl_interp.create_operation "test.success" -> (%results_2_single_types : !pdl.type) 1337 1338 %new_results_0 = pdl_interp.get_results of %op0 : !pdl.range<value> 1339 %new_results_1 = pdl_interp.get_results of %op1 : !pdl.range<value> 1340 %new_results_2 = pdl_interp.get_results of %op2 : !pdl.range<value> 1341 1342 pdl_interp.replace %root with (%new_results_0, %new_results_1, %new_results_2 : !pdl.range<value>, !pdl.range<value>, !pdl.range<value>) 1343 pdl_interp.finalize 1344 } 1345 } 1346} 1347 1348// CHECK-LABEL: test.get_results_2 1349// CHECK: "test.success"() : () -> () 1350// CHECK: %[[RESULTS_1:.*]]:4 = "test.success"() : () -> (i32, i32, i32, i32) 1351// CHECK: %[[RESULTS_2:.*]] = "test.success"() : () -> i32 1352// CHECK: %[[RESULTS_2_SINGLE:.*]] = "test.success"() : () -> i32 1353// CHECK: "test.consumer"(%[[RESULTS_1]]#0, %[[RESULTS_1]]#1, %[[RESULTS_1]]#2, %[[RESULTS_1]]#3, %[[RESULTS_2]]) : (i32, i32, i32, i32, i32) -> () 1354module @ir attributes { test.get_results_2 } { 1355 %results:5 = "test.attr_sized_results"() {resultSegmentSizes = array<i32: 0, 4, 1, 0>} : () -> (i32, i32, i32, i32, i32) 1356 "test.consumer"(%results#0, %results#1, %results#2, %results#3, %results#4) : (i32, i32, i32, i32, i32) -> () 1357} 1358 1359// ----- 1360 1361//===----------------------------------------------------------------------===// 1362// pdl_interp::GetValueTypeOp 1363//===----------------------------------------------------------------------===// 1364 1365// Fully tested within the tests for other operations. 1366 1367//===----------------------------------------------------------------------===// 1368// pdl_interp::IsNotNullOp 1369//===----------------------------------------------------------------------===// 1370 1371// Fully tested within the tests for other operations. 1372 1373//===----------------------------------------------------------------------===// 1374// pdl_interp::RecordMatchOp 1375//===----------------------------------------------------------------------===// 1376 1377// Check that the highest benefit pattern is selected. 1378module @patterns { 1379 pdl_interp.func @matcher(%root : !pdl.operation) { 1380 pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end 1381 1382 ^pat1: 1383 pdl_interp.record_match @rewriters::@failure(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^pat2 1384 1385 ^pat2: 1386 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end 1387 1388 ^end: 1389 pdl_interp.finalize 1390 } 1391 1392 module @rewriters { 1393 pdl_interp.func @failure(%root : !pdl.operation) { 1394 pdl_interp.erase %root 1395 pdl_interp.finalize 1396 } 1397 pdl_interp.func @success(%root : !pdl.operation) { 1398 %op = pdl_interp.create_operation "test.success" 1399 pdl_interp.erase %root 1400 pdl_interp.finalize 1401 } 1402 } 1403} 1404 1405// CHECK-LABEL: test.record_match_1 1406// CHECK: "test.success" 1407module @ir attributes { test.record_match_1 } { 1408 "test.op"() : () -> () 1409} 1410 1411// ----- 1412 1413// Check that ranges are properly forwarded to the result. 1414module @patterns { 1415 pdl_interp.func @matcher(%root : !pdl.operation) { 1416 pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end 1417 1418 ^pat1: 1419 %operands = pdl_interp.get_operands of %root : !pdl.range<value> 1420 %results = pdl_interp.get_results of %root : !pdl.range<value> 1421 %types = pdl_interp.get_value_type of %results : !pdl.range<type> 1422 pdl_interp.record_match @rewriters::@success(%operands, %types, %root : !pdl.range<value>, !pdl.range<type>, !pdl.operation) : benefit(1), loc([%root]) -> ^end 1423 1424 ^end: 1425 pdl_interp.finalize 1426 } 1427 1428 module @rewriters { 1429 pdl_interp.func @success(%operands: !pdl.range<value>, %types: !pdl.range<type>, %root: !pdl.operation) { 1430 %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>) 1431 %results = pdl_interp.get_results of %op : !pdl.range<value> 1432 pdl_interp.replace %root with (%results : !pdl.range<value>) 1433 pdl_interp.finalize 1434 } 1435 } 1436} 1437 1438// CHECK-LABEL: test.record_match_2 1439// CHECK: %[[OPERAND:.*]] = "test.producer"() : () -> i32 1440// CHECK: %[[RESULTS:.*]]:2 = "test.success"(%[[OPERAND]]) : (i32) -> (i64, i32) 1441// CHECK: "test.consumer"(%[[RESULTS]]#0, %[[RESULTS]]#1) : (i64, i32) -> () 1442module @ir attributes { test.record_match_2 } { 1443 %input = "test.producer"() : () -> i32 1444 %results:2 = "test.op"(%input) : (i32) -> (i64, i32) 1445 "test.consumer"(%results#0, %results#1) : (i64, i32) -> () 1446} 1447 1448// ----- 1449 1450//===----------------------------------------------------------------------===// 1451// pdl_interp::ReplaceOp 1452//===----------------------------------------------------------------------===// 1453 1454module @patterns { 1455 pdl_interp.func @matcher(%root : !pdl.operation) { 1456 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 1457 1458 ^pat: 1459 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1460 1461 ^end: 1462 pdl_interp.finalize 1463 } 1464 1465 module @rewriters { 1466 pdl_interp.func @success(%root : !pdl.operation) { 1467 %operand = pdl_interp.get_operand 0 of %root 1468 pdl_interp.replace %root with (%operand : !pdl.value) 1469 pdl_interp.finalize 1470 } 1471 } 1472} 1473 1474// CHECK-LABEL: test.replace_op_1 1475// CHECK: %[[INPUT:.*]] = "test.op_input" 1476// CHECK-NOT: "test.op" 1477// CHECK: "test.op_consumer"(%[[INPUT]]) 1478module @ir attributes { test.replace_op_1 } { 1479 %input = "test.op_input"() : () -> i32 1480 %result = "test.op"(%input) : (i32) -> i32 1481 "test.op_consumer"(%result) : (i32) -> () 1482} 1483 1484// ----- 1485 1486//===----------------------------------------------------------------------===// 1487// pdl_interp::SwitchAttributeOp 1488//===----------------------------------------------------------------------===// 1489 1490module @patterns { 1491 pdl_interp.func @matcher(%root : !pdl.operation) { 1492 %attr = pdl_interp.get_attribute "test_attr" of %root 1493 pdl_interp.switch_attribute %attr to [0, unit](^end, ^pat) -> ^end 1494 1495 ^pat: 1496 %attr_2 = pdl_interp.get_attribute "test_attr_2" of %root 1497 pdl_interp.switch_attribute %attr_2 to [0, unit](^end, ^end) -> ^pat2 1498 1499 ^pat2: 1500 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1501 1502 ^end: 1503 pdl_interp.finalize 1504 } 1505 1506 module @rewriters { 1507 pdl_interp.func @success(%root : !pdl.operation) { 1508 %op = pdl_interp.create_operation "test.success" 1509 pdl_interp.erase %root 1510 pdl_interp.finalize 1511 } 1512 } 1513} 1514 1515// CHECK-LABEL: test.switch_attribute_1 1516// CHECK: "test.success" 1517module @ir attributes { test.switch_attribute_1 } { 1518 "test.op"() { test_attr } : () -> () 1519} 1520 1521// ----- 1522 1523//===----------------------------------------------------------------------===// 1524// pdl_interp::SwitchOperandCountOp 1525//===----------------------------------------------------------------------===// 1526 1527module @patterns { 1528 pdl_interp.func @matcher(%root : !pdl.operation) { 1529 pdl_interp.switch_operand_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end 1530 1531 ^pat: 1532 pdl_interp.switch_operand_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2 1533 1534 ^pat2: 1535 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1536 1537 ^end: 1538 pdl_interp.finalize 1539 } 1540 1541 module @rewriters { 1542 pdl_interp.func @success(%root : !pdl.operation) { 1543 %op = pdl_interp.create_operation "test.success" 1544 pdl_interp.erase %root 1545 pdl_interp.finalize 1546 } 1547 } 1548} 1549 1550// CHECK-LABEL: test.switch_operand_1 1551// CHECK: "test.success" 1552module @ir attributes { test.switch_operand_1 } { 1553 %input = "test.op_input"() : () -> i32 1554 "test.op"(%input) : (i32) -> () 1555} 1556 1557// ----- 1558 1559//===----------------------------------------------------------------------===// 1560// pdl_interp::SwitchOperationNameOp 1561//===----------------------------------------------------------------------===// 1562 1563module @patterns { 1564 pdl_interp.func @matcher(%root : !pdl.operation) { 1565 pdl_interp.switch_operation_name of %root to ["foo.op", "test.op"](^end, ^pat1) -> ^end 1566 1567 ^pat1: 1568 pdl_interp.switch_operation_name of %root to ["foo.op", "bar.op"](^end, ^end) -> ^pat2 1569 1570 ^pat2: 1571 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1572 1573 ^end: 1574 pdl_interp.finalize 1575 } 1576 1577 module @rewriters { 1578 pdl_interp.func @success(%root : !pdl.operation) { 1579 %op = pdl_interp.create_operation "test.success" 1580 pdl_interp.erase %root 1581 pdl_interp.finalize 1582 } 1583 } 1584} 1585 1586// CHECK-LABEL: test.switch_operation_name_1 1587// CHECK: "test.success" 1588module @ir attributes { test.switch_operation_name_1 } { 1589 "test.op"() : () -> () 1590} 1591 1592// ----- 1593 1594//===----------------------------------------------------------------------===// 1595// pdl_interp::SwitchResultCountOp 1596//===----------------------------------------------------------------------===// 1597 1598module @patterns { 1599 pdl_interp.func @matcher(%root : !pdl.operation) { 1600 pdl_interp.switch_result_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end 1601 1602 ^pat: 1603 pdl_interp.switch_result_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2 1604 1605 ^pat2: 1606 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1607 1608 ^end: 1609 pdl_interp.finalize 1610 } 1611 1612 module @rewriters { 1613 pdl_interp.func @success(%root : !pdl.operation) { 1614 %op = pdl_interp.create_operation "test.success" 1615 pdl_interp.erase %root 1616 pdl_interp.finalize 1617 } 1618 } 1619} 1620 1621// CHECK-LABEL: test.switch_result_1 1622// CHECK: "test.success" 1623module @ir attributes { test.switch_result_1 } { 1624 "test.op"() : () -> i32 1625} 1626 1627// ----- 1628 1629//===----------------------------------------------------------------------===// 1630// pdl_interp::SwitchTypeOp 1631//===----------------------------------------------------------------------===// 1632 1633module @patterns { 1634 pdl_interp.func @matcher(%root : !pdl.operation) { 1635 %attr = pdl_interp.get_attribute "test_attr" of %root 1636 pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end 1637 1638 ^pat1: 1639 %type = pdl_interp.get_attribute_type of %attr 1640 pdl_interp.switch_type %type to [i32, i64](^pat2, ^end) -> ^end 1641 1642 ^pat2: 1643 pdl_interp.switch_type %type to [i16, i64](^end, ^end) -> ^pat3 1644 1645 ^pat3: 1646 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1647 1648 ^end: 1649 pdl_interp.finalize 1650 } 1651 1652 module @rewriters { 1653 pdl_interp.func @success(%root : !pdl.operation) { 1654 %op = pdl_interp.create_operation "test.success" 1655 pdl_interp.erase %root 1656 pdl_interp.finalize 1657 } 1658 } 1659} 1660 1661// CHECK-LABEL: test.switch_type_1 1662// CHECK: "test.success" 1663module @ir attributes { test.switch_type_1 } { 1664 "test.op"() { test_attr = 10 : i32 } : () -> () 1665} 1666 1667// ----- 1668 1669//===----------------------------------------------------------------------===// 1670// pdl_interp::SwitchTypesOp 1671//===----------------------------------------------------------------------===// 1672 1673module @patterns { 1674 pdl_interp.func @matcher(%root : !pdl.operation) { 1675 %results = pdl_interp.get_results of %root : !pdl.range<value> 1676 %types = pdl_interp.get_value_type of %results : !pdl.range<type> 1677 pdl_interp.switch_types %types to [[i64, i64], [i32]](^pat2, ^end) -> ^end 1678 1679 ^pat2: 1680 pdl_interp.switch_types %types to [[i32], [i64, i32]](^end, ^end) -> ^pat3 1681 1682 ^pat3: 1683 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1684 1685 ^end: 1686 pdl_interp.finalize 1687 } 1688 1689 module @rewriters { 1690 pdl_interp.func @success(%root : !pdl.operation) { 1691 %op = pdl_interp.create_operation "test.success" 1692 pdl_interp.erase %root 1693 pdl_interp.finalize 1694 } 1695 } 1696} 1697 1698// CHECK-LABEL: test.switch_types_1 1699// CHECK: "test.success" 1700module @ir attributes { test.switch_types_1 } { 1701 %results:2 = "test.op"() : () -> (i64, i64) 1702} 1703