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 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 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 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 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//===----------------------------------------------------------------------===// 76// pdl_interp::ApplyRewriteOp 77//===----------------------------------------------------------------------===// 78 79module @patterns { 80 func @matcher(%root : !pdl.operation) { 81 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 82 83 ^pat: 84 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 85 86 ^end: 87 pdl_interp.finalize 88 } 89 90 module @rewriters { 91 func @success(%root : !pdl.operation) { 92 %operand = pdl_interp.get_operand 0 of %root 93 pdl_interp.apply_rewrite "rewriter"[42](%root, %operand : !pdl.operation, !pdl.value) 94 pdl_interp.finalize 95 } 96 } 97} 98 99// CHECK-LABEL: test.apply_rewrite_1 100// CHECK: %[[INPUT:.*]] = "test.op_input" 101// CHECK-NOT: "test.op" 102// CHECK: "test.success"(%[[INPUT]]) {constantParams = [42]} 103module @ir attributes { test.apply_rewrite_1 } { 104 %input = "test.op_input"() : () -> i32 105 "test.op"(%input) : (i32) -> () 106} 107 108// ----- 109 110module @patterns { 111 func @matcher(%root : !pdl.operation) { 112 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 113 114 ^pat: 115 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 116 117 ^end: 118 pdl_interp.finalize 119 } 120 121 module @rewriters { 122 func @success(%root : !pdl.operation) { 123 %op = pdl_interp.apply_rewrite "creator"(%root : !pdl.operation) : !pdl.operation 124 pdl_interp.erase %root 125 pdl_interp.finalize 126 } 127 } 128} 129 130// CHECK-LABEL: test.apply_rewrite_2 131// CHECK: "test.success" 132module @ir attributes { test.apply_rewrite_2 } { 133 "test.op"() : () -> () 134} 135 136// ----- 137 138module @patterns { 139 func @matcher(%root : !pdl.operation) { 140 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 141 142 ^pat: 143 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 144 145 ^end: 146 pdl_interp.finalize 147 } 148 149 module @rewriters { 150 func @success(%root : !pdl.operation) { 151 %operands, %types = pdl_interp.apply_rewrite "var_creator"(%root : !pdl.operation) : !pdl.range<value>, !pdl.range<type> 152 %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>) 153 pdl_interp.replace %root with (%operands : !pdl.range<value>) 154 pdl_interp.finalize 155 } 156 } 157} 158 159// CHECK-LABEL: test.apply_rewrite_3 160// CHECK: %[[OPERAND:.*]] = "test.producer" 161// CHECK: "test.success"(%[[OPERAND]]) : (i32) -> i32 162// CHECK: "test.consumer"(%[[OPERAND]]) 163module @ir attributes { test.apply_rewrite_3 } { 164 %first_operand = "test.producer"() : () -> (i32) 165 %operand = "test.op"(%first_operand) : (i32) -> (i32) 166 "test.consumer"(%operand) : (i32) -> () 167} 168 169// ----- 170 171module @patterns { 172 func @matcher(%root : !pdl.operation) { 173 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 174 175 ^pat: 176 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 177 178 ^end: 179 pdl_interp.finalize 180 } 181 182 module @rewriters { 183 func @success(%root : !pdl.operation) { 184 %type = pdl_interp.apply_rewrite "type_creator" : !pdl.type 185 %newOp = pdl_interp.create_operation "test.success" -> (%type : !pdl.type) 186 pdl_interp.erase %root 187 pdl_interp.finalize 188 } 189 } 190} 191 192// CHECK-LABEL: test.apply_rewrite_4 193// CHECK: "test.success"() : () -> f32 194module @ir attributes { test.apply_rewrite_4 } { 195 "test.op"() : () -> () 196} 197 198// ----- 199 200//===----------------------------------------------------------------------===// 201// pdl_interp::AreEqualOp 202//===----------------------------------------------------------------------===// 203 204module @patterns { 205 func @matcher(%root : !pdl.operation) { 206 %test_attr = pdl_interp.create_attribute unit 207 %attr = pdl_interp.get_attribute "test_attr" of %root 208 pdl_interp.are_equal %test_attr, %attr : !pdl.attribute -> ^pat, ^end 209 210 ^pat: 211 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 212 213 ^end: 214 pdl_interp.finalize 215 } 216 217 module @rewriters { 218 func @success(%root : !pdl.operation) { 219 %op = pdl_interp.create_operation "test.success" 220 pdl_interp.erase %root 221 pdl_interp.finalize 222 } 223 } 224} 225 226// CHECK-LABEL: test.are_equal_1 227// CHECK: "test.success" 228module @ir attributes { test.are_equal_1 } { 229 "test.op"() { test_attr } : () -> () 230} 231 232// ----- 233 234module @patterns { 235 func @matcher(%root : !pdl.operation) { 236 %const_types = pdl_interp.create_types [i32, i64] 237 %results = pdl_interp.get_results of %root : !pdl.range<value> 238 %result_types = pdl_interp.get_value_type of %results : !pdl.range<type> 239 pdl_interp.are_equal %result_types, %const_types : !pdl.range<type> -> ^pat, ^end 240 241 ^pat: 242 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 243 244 ^end: 245 pdl_interp.finalize 246 } 247 248 module @rewriters { 249 func @success(%root : !pdl.operation) { 250 %op = pdl_interp.create_operation "test.success" 251 pdl_interp.erase %root 252 pdl_interp.finalize 253 } 254 } 255} 256 257// CHECK-LABEL: test.are_equal_2 258// CHECK: "test.not_equal" 259// CHECK: "test.success" 260// CHECK-NOT: "test.op" 261module @ir attributes { test.are_equal_2 } { 262 "test.not_equal"() : () -> (i32) 263 "test.op"() : () -> (i32, i64) 264} 265 266// ----- 267 268//===----------------------------------------------------------------------===// 269// pdl_interp::BranchOp 270//===----------------------------------------------------------------------===// 271 272module @patterns { 273 func @matcher(%root : !pdl.operation) { 274 pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end 275 276 ^pat1: 277 pdl_interp.branch ^pat2 278 279 ^pat2: 280 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end 281 282 ^end: 283 pdl_interp.finalize 284 } 285 286 module @rewriters { 287 func @success(%root : !pdl.operation) { 288 %op = pdl_interp.create_operation "test.success" 289 pdl_interp.erase %root 290 pdl_interp.finalize 291 } 292 } 293} 294 295// CHECK-LABEL: test.branch_1 296// CHECK: "test.success" 297module @ir attributes { test.branch_1 } { 298 "test.op"() : () -> () 299} 300 301// ----- 302 303//===----------------------------------------------------------------------===// 304// pdl_interp::CheckAttributeOp 305//===----------------------------------------------------------------------===// 306 307module @patterns { 308 func @matcher(%root : !pdl.operation) { 309 %attr = pdl_interp.get_attribute "test_attr" of %root 310 pdl_interp.check_attribute %attr is unit -> ^pat, ^end 311 312 ^pat: 313 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 314 315 ^end: 316 pdl_interp.finalize 317 } 318 319 module @rewriters { 320 func @success(%root : !pdl.operation) { 321 %op = pdl_interp.create_operation "test.success" 322 pdl_interp.erase %root 323 pdl_interp.finalize 324 } 325 } 326} 327 328// CHECK-LABEL: test.check_attribute_1 329// CHECK: "test.success" 330module @ir attributes { test.check_attribute_1 } { 331 "test.op"() { test_attr } : () -> () 332} 333 334// ----- 335 336//===----------------------------------------------------------------------===// 337// pdl_interp::CheckOperandCountOp 338//===----------------------------------------------------------------------===// 339 340module @patterns { 341 func @matcher(%root : !pdl.operation) { 342 pdl_interp.check_operand_count of %root is at_least 1 -> ^exact_check, ^end 343 344 ^exact_check: 345 pdl_interp.check_operand_count of %root is 2 -> ^pat, ^end 346 347 ^pat: 348 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 349 350 ^end: 351 pdl_interp.finalize 352 } 353 354 module @rewriters { 355 func @success(%root : !pdl.operation) { 356 %op = pdl_interp.create_operation "test.success" 357 pdl_interp.erase %root 358 pdl_interp.finalize 359 } 360 } 361} 362 363// CHECK-LABEL: test.check_operand_count_1 364// CHECK: "test.op"() : () -> i32 365// CHECK: "test.success" 366module @ir attributes { test.check_operand_count_1 } { 367 %operand = "test.op"() : () -> i32 368 "test.op"(%operand, %operand) : (i32, i32) -> () 369} 370 371// ----- 372 373//===----------------------------------------------------------------------===// 374// pdl_interp::CheckOperationNameOp 375//===----------------------------------------------------------------------===// 376 377module @patterns { 378 func @matcher(%root : !pdl.operation) { 379 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 380 381 ^pat: 382 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 383 384 ^end: 385 pdl_interp.finalize 386 } 387 388 module @rewriters { 389 func @success(%root : !pdl.operation) { 390 %op = pdl_interp.create_operation "test.success" 391 pdl_interp.erase %root 392 pdl_interp.finalize 393 } 394 } 395} 396 397// CHECK-LABEL: test.check_operation_name_1 398// CHECK: "test.success" 399module @ir attributes { test.check_operation_name_1 } { 400 "test.op"() : () -> () 401} 402 403// ----- 404 405//===----------------------------------------------------------------------===// 406// pdl_interp::CheckResultCountOp 407//===----------------------------------------------------------------------===// 408 409module @patterns { 410 func @matcher(%root : !pdl.operation) { 411 pdl_interp.check_result_count of %root is at_least 1 -> ^exact_check, ^end 412 413 ^exact_check: 414 pdl_interp.check_result_count of %root is 2 -> ^pat, ^end 415 416 ^pat: 417 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 418 419 ^end: 420 pdl_interp.finalize 421 } 422 423 module @rewriters { 424 func @success(%root : !pdl.operation) { 425 %op = pdl_interp.create_operation "test.success" 426 pdl_interp.erase %root 427 pdl_interp.finalize 428 } 429 } 430} 431 432// CHECK-LABEL: test.check_result_count_1 433// CHECK: "test.op"() : () -> i32 434// CHECK: "test.success"() : () -> () 435// CHECK-NOT: "test.op"() : () -> (i32, i32) 436module @ir attributes { test.check_result_count_1 } { 437 "test.op"() : () -> i32 438 "test.op"() : () -> (i32, i32) 439} 440 441// ----- 442 443//===----------------------------------------------------------------------===// 444// pdl_interp::CheckTypeOp 445//===----------------------------------------------------------------------===// 446 447module @patterns { 448 func @matcher(%root : !pdl.operation) { 449 %attr = pdl_interp.get_attribute "test_attr" of %root 450 pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end 451 452 ^pat1: 453 %type = pdl_interp.get_attribute_type of %attr 454 pdl_interp.check_type %type is i32 -> ^pat2, ^end 455 456 ^pat2: 457 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 458 459 ^end: 460 pdl_interp.finalize 461 } 462 463 module @rewriters { 464 func @success(%root : !pdl.operation) { 465 %op = pdl_interp.create_operation "test.success" 466 pdl_interp.erase %root 467 pdl_interp.finalize 468 } 469 } 470} 471 472// CHECK-LABEL: test.check_type_1 473// CHECK: "test.success" 474module @ir attributes { test.check_type_1 } { 475 "test.op"() { test_attr = 10 : i32 } : () -> () 476} 477 478// ----- 479 480//===----------------------------------------------------------------------===// 481// pdl_interp::CheckTypesOp 482//===----------------------------------------------------------------------===// 483 484module @patterns { 485 func @matcher(%root : !pdl.operation) { 486 %results = pdl_interp.get_results of %root : !pdl.range<value> 487 %result_types = pdl_interp.get_value_type of %results : !pdl.range<type> 488 pdl_interp.check_types %result_types are [i32] -> ^pat2, ^end 489 490 ^pat2: 491 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 492 493 ^end: 494 pdl_interp.finalize 495 } 496 497 module @rewriters { 498 func @success(%root : !pdl.operation) { 499 %op = pdl_interp.create_operation "test.success" 500 pdl_interp.erase %root 501 pdl_interp.finalize 502 } 503 } 504} 505 506// CHECK-LABEL: test.check_types_1 507// CHECK: "test.op"() : () -> (i32, i64) 508// CHECK: "test.success" 509// CHECK-NOT: "test.op"() : () -> i32 510module @ir attributes { test.check_types_1 } { 511 "test.op"() : () -> (i32, i64) 512 "test.op"() : () -> i32 513} 514 515// ----- 516 517//===----------------------------------------------------------------------===// 518// pdl_interp::CreateAttributeOp 519//===----------------------------------------------------------------------===// 520 521// Fully tested within the tests for other operations. 522 523//===----------------------------------------------------------------------===// 524// pdl_interp::CreateOperationOp 525//===----------------------------------------------------------------------===// 526 527// ----- 528 529//===----------------------------------------------------------------------===// 530// pdl_interp::CreateTypeOp 531//===----------------------------------------------------------------------===// 532 533module @patterns { 534 func @matcher(%root : !pdl.operation) { 535 %attr = pdl_interp.get_attribute "test_attr" of %root 536 pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end 537 538 ^pat1: 539 %test_type = pdl_interp.create_type i32 540 %type = pdl_interp.get_attribute_type of %attr 541 pdl_interp.are_equal %type, %test_type : !pdl.type -> ^pat2, ^end 542 543 ^pat2: 544 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 545 546 ^end: 547 pdl_interp.finalize 548 } 549 550 module @rewriters { 551 func @success(%root : !pdl.operation) { 552 %op = pdl_interp.create_operation "test.success" 553 pdl_interp.erase %root 554 pdl_interp.finalize 555 } 556 } 557} 558 559// CHECK-LABEL: test.create_type_1 560// CHECK: "test.success" 561module @ir attributes { test.create_type_1 } { 562 "test.op"() { test_attr = 0 : i32 } : () -> () 563} 564 565// ----- 566 567//===----------------------------------------------------------------------===// 568// pdl_interp::CreateTypesOp 569//===----------------------------------------------------------------------===// 570 571// Fully tested within the tests for other operations. 572 573//===----------------------------------------------------------------------===// 574// pdl_interp::EraseOp 575//===----------------------------------------------------------------------===// 576 577// Fully tested within the tests for other operations. 578 579//===----------------------------------------------------------------------===// 580// pdl_interp::FinalizeOp 581//===----------------------------------------------------------------------===// 582 583// Fully tested within the tests for other operations. 584 585//===----------------------------------------------------------------------===// 586// pdl_interp::GetAttributeOp 587//===----------------------------------------------------------------------===// 588 589// Fully tested within the tests for other operations. 590 591//===----------------------------------------------------------------------===// 592// pdl_interp::GetAttributeTypeOp 593//===----------------------------------------------------------------------===// 594 595// Fully tested within the tests for other operations. 596 597//===----------------------------------------------------------------------===// 598// pdl_interp::GetDefiningOpOp 599//===----------------------------------------------------------------------===// 600 601module @patterns { 602 func @matcher(%root : !pdl.operation) { 603 pdl_interp.check_operand_count of %root is 5 -> ^pat1, ^end 604 605 ^pat1: 606 %operand0 = pdl_interp.get_operand 0 of %root 607 %operand4 = pdl_interp.get_operand 4 of %root 608 %defOp0 = pdl_interp.get_defining_op of %operand0 : !pdl.value 609 %defOp4 = pdl_interp.get_defining_op of %operand4 : !pdl.value 610 pdl_interp.are_equal %defOp0, %defOp4 : !pdl.operation -> ^pat2, ^end 611 612 ^pat2: 613 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 614 615 ^end: 616 pdl_interp.finalize 617 } 618 619 module @rewriters { 620 func @success(%root : !pdl.operation) { 621 %op = pdl_interp.create_operation "test.success" 622 pdl_interp.erase %root 623 pdl_interp.finalize 624 } 625 } 626} 627 628// CHECK-LABEL: test.get_defining_op_1 629// CHECK: %[[OPERAND0:.*]] = "test.op" 630// CHECK: %[[OPERAND1:.*]] = "test.op" 631// CHECK: "test.success" 632// CHECK: "test.op"(%[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND1]]) 633module @ir attributes { test.get_defining_op_1 } { 634 %operand = "test.op"() : () -> i32 635 %other_operand = "test.op"() : () -> i32 636 "test.op"(%operand, %operand, %operand, %operand, %operand) : (i32, i32, i32, i32, i32) -> () 637 "test.op"(%operand, %operand, %operand, %operand, %other_operand) : (i32, i32, i32, i32, i32) -> () 638} 639 640// ----- 641 642//===----------------------------------------------------------------------===// 643// pdl_interp::GetOperandOp 644//===----------------------------------------------------------------------===// 645 646// Fully tested within the tests for other operations. 647 648//===----------------------------------------------------------------------===// 649// pdl_interp::GetOperandsOp 650//===----------------------------------------------------------------------===// 651 652module @patterns { 653 func @matcher(%root : !pdl.operation) { 654 pdl_interp.check_operand_count of %root is 2 -> ^pat1, ^end 655 656 ^pat1: 657 %operands = pdl_interp.get_operands 0 of %root : !pdl.range<value> 658 %full_operands = pdl_interp.get_operands of %root : !pdl.range<value> 659 pdl_interp.are_equal %operands, %full_operands : !pdl.range<value> -> ^pat2, ^end 660 661 ^pat2: 662 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 663 664 ^end: 665 pdl_interp.finalize 666 } 667 668 module @rewriters { 669 func @success(%root : !pdl.operation) { 670 %op = pdl_interp.create_operation "test.success" 671 pdl_interp.erase %root 672 pdl_interp.finalize 673 } 674 } 675} 676 677// CHECK-LABEL: test.get_operands_1 678// CHECK: "test.success" 679module @ir attributes { test.get_operands_1 } { 680 %inputs:2 = "test.producer"() : () -> (i32, i32) 681 "test.op"(%inputs#0, %inputs#1) : (i32, i32) -> () 682} 683 684// ----- 685 686// Test all of the various combinations related to `AttrSizedOperandSegments`. 687module @patterns { 688 func @matcher(%root : !pdl.operation) { 689 pdl_interp.check_operation_name of %root is "test.attr_sized_operands" -> ^pat1, ^end 690 691 ^pat1: 692 %operands_0 = pdl_interp.get_operands 0 of %root : !pdl.range<value> 693 pdl_interp.is_not_null %operands_0 : !pdl.range<value> -> ^pat2, ^end 694 695 ^pat2: 696 %operands_0_single = pdl_interp.get_operands 0 of %root : !pdl.value 697 pdl_interp.is_not_null %operands_0_single : !pdl.value -> ^end, ^pat3 698 699 ^pat3: 700 %operands_1 = pdl_interp.get_operands 1 of %root : !pdl.range<value> 701 pdl_interp.is_not_null %operands_1 : !pdl.range<value> -> ^pat4, ^end 702 703 ^pat4: 704 %operands_1_single = pdl_interp.get_operands 1 of %root : !pdl.value 705 pdl_interp.is_not_null %operands_1_single : !pdl.value -> ^end, ^pat5 706 707 ^pat5: 708 %operands_2 = pdl_interp.get_operands 2 of %root : !pdl.range<value> 709 pdl_interp.is_not_null %operands_2 : !pdl.range<value> -> ^pat6, ^end 710 711 ^pat6: 712 %operands_2_single = pdl_interp.get_operands 2 of %root : !pdl.value 713 pdl_interp.is_not_null %operands_2_single : !pdl.value -> ^pat7, ^end 714 715 ^pat7: 716 %invalid_operands = pdl_interp.get_operands 50 of %root : !pdl.value 717 pdl_interp.is_not_null %invalid_operands : !pdl.value -> ^end, ^pat8 718 719 ^pat8: 720 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 721 722 723 ^end: 724 pdl_interp.finalize 725 } 726 727 module @rewriters { 728 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) { 729 %op0 = pdl_interp.create_operation "test.success"(%operands_0 : !pdl.range<value>) 730 %op1 = pdl_interp.create_operation "test.success"(%operands_1 : !pdl.range<value>) 731 %op2 = pdl_interp.create_operation "test.success"(%operands_2 : !pdl.range<value>) 732 %op3 = pdl_interp.create_operation "test.success"(%operands_2_single : !pdl.value) 733 pdl_interp.erase %root 734 pdl_interp.finalize 735 } 736 } 737} 738 739// CHECK-LABEL: test.get_operands_2 740// CHECK-NEXT: %[[INPUTS:.*]]:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32) 741// CHECK-NEXT: "test.success"() : () -> () 742// CHECK-NEXT: "test.success"(%[[INPUTS]]#0, %[[INPUTS]]#1, %[[INPUTS]]#2, %[[INPUTS]]#3) : (i32, i32, i32, i32) -> () 743// CHECK-NEXT: "test.success"(%[[INPUTS]]#4) : (i32) -> () 744// CHECK-NEXT: "test.success"(%[[INPUTS]]#4) : (i32) -> () 745module @ir attributes { test.get_operands_2 } { 746 %inputs:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32) 747 "test.attr_sized_operands"(%inputs#0, %inputs#1, %inputs#2, %inputs#3, %inputs#4) {operand_segment_sizes = dense<[0, 4, 1, 0]> : vector<4xi32>} : (i32, i32, i32, i32, i32) -> () 748} 749 750// ----- 751 752//===----------------------------------------------------------------------===// 753// pdl_interp::GetResultOp 754//===----------------------------------------------------------------------===// 755 756module @patterns { 757 func @matcher(%root : !pdl.operation) { 758 pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end 759 760 ^pat1: 761 %result0 = pdl_interp.get_result 0 of %root 762 %result4 = pdl_interp.get_result 4 of %root 763 %result0_type = pdl_interp.get_value_type of %result0 : !pdl.type 764 %result4_type = pdl_interp.get_value_type of %result4 : !pdl.type 765 pdl_interp.are_equal %result0_type, %result4_type : !pdl.type -> ^pat2, ^end 766 767 ^pat2: 768 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 769 770 ^end: 771 pdl_interp.finalize 772 } 773 774 module @rewriters { 775 func @success(%root : !pdl.operation) { 776 %op = pdl_interp.create_operation "test.success" 777 pdl_interp.erase %root 778 pdl_interp.finalize 779 } 780 } 781} 782 783// CHECK-LABEL: test.get_result_1 784// CHECK: "test.success" 785// CHECK: "test.op"() : () -> (i32, i32, i32, i32, i64) 786module @ir attributes { test.get_result_1 } { 787 %a:5 = "test.op"() : () -> (i32, i32, i32, i32, i32) 788 %b:5 = "test.op"() : () -> (i32, i32, i32, i32, i64) 789} 790 791// ----- 792 793//===----------------------------------------------------------------------===// 794// pdl_interp::GetResultsOp 795//===----------------------------------------------------------------------===// 796 797module @patterns { 798 func @matcher(%root : !pdl.operation) { 799 pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end 800 801 ^pat1: 802 %results = pdl_interp.get_results 0 of %root : !pdl.range<value> 803 %full_results = pdl_interp.get_results of %root : !pdl.range<value> 804 pdl_interp.are_equal %results, %full_results : !pdl.range<value> -> ^pat2, ^end 805 806 ^pat2: 807 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 808 809 ^end: 810 pdl_interp.finalize 811 } 812 813 module @rewriters { 814 func @success(%root : !pdl.operation) { 815 %op = pdl_interp.create_operation "test.success" 816 pdl_interp.erase %root 817 pdl_interp.finalize 818 } 819 } 820} 821 822// CHECK-LABEL: test.get_results_1 823// CHECK: "test.success" 824module @ir attributes { test.get_results_1 } { 825 %a:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32) 826} 827 828// ----- 829 830// Test all of the various combinations related to `AttrSizedResultSegments`. 831module @patterns { 832 func @matcher(%root : !pdl.operation) { 833 pdl_interp.check_operation_name of %root is "test.attr_sized_results" -> ^pat1, ^end 834 835 ^pat1: 836 %results_0 = pdl_interp.get_results 0 of %root : !pdl.range<value> 837 pdl_interp.is_not_null %results_0 : !pdl.range<value> -> ^pat2, ^end 838 839 ^pat2: 840 %results_0_single = pdl_interp.get_results 0 of %root : !pdl.value 841 pdl_interp.is_not_null %results_0_single : !pdl.value -> ^end, ^pat3 842 843 ^pat3: 844 %results_1 = pdl_interp.get_results 1 of %root : !pdl.range<value> 845 pdl_interp.is_not_null %results_1 : !pdl.range<value> -> ^pat4, ^end 846 847 ^pat4: 848 %results_1_single = pdl_interp.get_results 1 of %root : !pdl.value 849 pdl_interp.is_not_null %results_1_single : !pdl.value -> ^end, ^pat5 850 851 ^pat5: 852 %results_2 = pdl_interp.get_results 2 of %root : !pdl.range<value> 853 pdl_interp.is_not_null %results_2 : !pdl.range<value> -> ^pat6, ^end 854 855 ^pat6: 856 %results_2_single = pdl_interp.get_results 2 of %root : !pdl.value 857 pdl_interp.is_not_null %results_2_single : !pdl.value -> ^pat7, ^end 858 859 ^pat7: 860 %invalid_results = pdl_interp.get_results 50 of %root : !pdl.value 861 pdl_interp.is_not_null %invalid_results : !pdl.value -> ^end, ^pat8 862 863 ^pat8: 864 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 865 866 867 ^end: 868 pdl_interp.finalize 869 } 870 871 module @rewriters { 872 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) { 873 %results_0_types = pdl_interp.get_value_type of %results_0 : !pdl.range<type> 874 %results_1_types = pdl_interp.get_value_type of %results_1 : !pdl.range<type> 875 %results_2_types = pdl_interp.get_value_type of %results_2 : !pdl.range<type> 876 %results_2_single_types = pdl_interp.get_value_type of %results_2_single : !pdl.type 877 878 %op0 = pdl_interp.create_operation "test.success" -> (%results_0_types : !pdl.range<type>) 879 %op1 = pdl_interp.create_operation "test.success" -> (%results_1_types : !pdl.range<type>) 880 %op2 = pdl_interp.create_operation "test.success" -> (%results_2_types : !pdl.range<type>) 881 %op3 = pdl_interp.create_operation "test.success" -> (%results_2_single_types : !pdl.type) 882 883 %new_results_0 = pdl_interp.get_results of %op0 : !pdl.range<value> 884 %new_results_1 = pdl_interp.get_results of %op1 : !pdl.range<value> 885 %new_results_2 = pdl_interp.get_results of %op2 : !pdl.range<value> 886 887 pdl_interp.replace %root with (%new_results_0, %new_results_1, %new_results_2 : !pdl.range<value>, !pdl.range<value>, !pdl.range<value>) 888 pdl_interp.finalize 889 } 890 } 891} 892 893// CHECK-LABEL: test.get_results_2 894// CHECK: "test.success"() : () -> () 895// CHECK: %[[RESULTS_1:.*]]:4 = "test.success"() : () -> (i32, i32, i32, i32) 896// CHECK: %[[RESULTS_2:.*]] = "test.success"() : () -> i32 897// CHECK: %[[RESULTS_2_SINGLE:.*]] = "test.success"() : () -> i32 898// CHECK: "test.consumer"(%[[RESULTS_1]]#0, %[[RESULTS_1]]#1, %[[RESULTS_1]]#2, %[[RESULTS_1]]#3, %[[RESULTS_2]]) : (i32, i32, i32, i32, i32) -> () 899module @ir attributes { test.get_results_2 } { 900 %results:5 = "test.attr_sized_results"() {result_segment_sizes = dense<[0, 4, 1, 0]> : vector<4xi32>} : () -> (i32, i32, i32, i32, i32) 901 "test.consumer"(%results#0, %results#1, %results#2, %results#3, %results#4) : (i32, i32, i32, i32, i32) -> () 902} 903 904// ----- 905 906//===----------------------------------------------------------------------===// 907// pdl_interp::GetValueTypeOp 908//===----------------------------------------------------------------------===// 909 910// Fully tested within the tests for other operations. 911 912//===----------------------------------------------------------------------===// 913// pdl_interp::InferredTypesOp 914//===----------------------------------------------------------------------===// 915 916// Fully tested within the tests for other operations. 917 918//===----------------------------------------------------------------------===// 919// pdl_interp::IsNotNullOp 920//===----------------------------------------------------------------------===// 921 922// Fully tested within the tests for other operations. 923 924//===----------------------------------------------------------------------===// 925// pdl_interp::RecordMatchOp 926//===----------------------------------------------------------------------===// 927 928// Check that the highest benefit pattern is selected. 929module @patterns { 930 func @matcher(%root : !pdl.operation) { 931 pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end 932 933 ^pat1: 934 pdl_interp.record_match @rewriters::@failure(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^pat2 935 936 ^pat2: 937 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end 938 939 ^end: 940 pdl_interp.finalize 941 } 942 943 module @rewriters { 944 func @failure(%root : !pdl.operation) { 945 pdl_interp.erase %root 946 pdl_interp.finalize 947 } 948 func @success(%root : !pdl.operation) { 949 %op = pdl_interp.create_operation "test.success" 950 pdl_interp.erase %root 951 pdl_interp.finalize 952 } 953 } 954} 955 956// CHECK-LABEL: test.record_match_1 957// CHECK: "test.success" 958module @ir attributes { test.record_match_1 } { 959 "test.op"() : () -> () 960} 961 962// ----- 963 964// Check that ranges are properly forwarded to the result. 965module @patterns { 966 func @matcher(%root : !pdl.operation) { 967 pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end 968 969 ^pat1: 970 %operands = pdl_interp.get_operands of %root : !pdl.range<value> 971 %results = pdl_interp.get_results of %root : !pdl.range<value> 972 %types = pdl_interp.get_value_type of %results : !pdl.range<type> 973 pdl_interp.record_match @rewriters::@success(%operands, %types, %root : !pdl.range<value>, !pdl.range<type>, !pdl.operation) : benefit(1), loc([%root]) -> ^end 974 975 ^end: 976 pdl_interp.finalize 977 } 978 979 module @rewriters { 980 func @success(%operands: !pdl.range<value>, %types: !pdl.range<type>, %root: !pdl.operation) { 981 %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>) 982 %results = pdl_interp.get_results of %op : !pdl.range<value> 983 pdl_interp.replace %root with (%results : !pdl.range<value>) 984 pdl_interp.finalize 985 } 986 } 987} 988 989// CHECK-LABEL: test.record_match_2 990// CHECK: %[[OPERAND:.*]] = "test.producer"() : () -> i32 991// CHECK: %[[RESULTS:.*]]:2 = "test.success"(%[[OPERAND]]) : (i32) -> (i64, i32) 992// CHECK: "test.consumer"(%[[RESULTS]]#0, %[[RESULTS]]#1) : (i64, i32) -> () 993module @ir attributes { test.record_match_2 } { 994 %input = "test.producer"() : () -> i32 995 %results:2 = "test.op"(%input) : (i32) -> (i64, i32) 996 "test.consumer"(%results#0, %results#1) : (i64, i32) -> () 997} 998 999// ----- 1000 1001//===----------------------------------------------------------------------===// 1002// pdl_interp::ReplaceOp 1003//===----------------------------------------------------------------------===// 1004 1005module @patterns { 1006 func @matcher(%root : !pdl.operation) { 1007 pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end 1008 1009 ^pat: 1010 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1011 1012 ^end: 1013 pdl_interp.finalize 1014 } 1015 1016 module @rewriters { 1017 func @success(%root : !pdl.operation) { 1018 %operand = pdl_interp.get_operand 0 of %root 1019 pdl_interp.replace %root with (%operand : !pdl.value) 1020 pdl_interp.finalize 1021 } 1022 } 1023} 1024 1025// CHECK-LABEL: test.replace_op_1 1026// CHECK: %[[INPUT:.*]] = "test.op_input" 1027// CHECK-NOT: "test.op" 1028// CHECK: "test.op_consumer"(%[[INPUT]]) 1029module @ir attributes { test.replace_op_1 } { 1030 %input = "test.op_input"() : () -> i32 1031 %result = "test.op"(%input) : (i32) -> i32 1032 "test.op_consumer"(%result) : (i32) -> () 1033} 1034 1035// ----- 1036 1037//===----------------------------------------------------------------------===// 1038// pdl_interp::SwitchAttributeOp 1039//===----------------------------------------------------------------------===// 1040 1041module @patterns { 1042 func @matcher(%root : !pdl.operation) { 1043 %attr = pdl_interp.get_attribute "test_attr" of %root 1044 pdl_interp.switch_attribute %attr to [0, unit](^end, ^pat) -> ^end 1045 1046 ^pat: 1047 %attr_2 = pdl_interp.get_attribute "test_attr_2" of %root 1048 pdl_interp.switch_attribute %attr_2 to [0, unit](^end, ^end) -> ^pat2 1049 1050 ^pat2: 1051 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1052 1053 ^end: 1054 pdl_interp.finalize 1055 } 1056 1057 module @rewriters { 1058 func @success(%root : !pdl.operation) { 1059 %op = pdl_interp.create_operation "test.success" 1060 pdl_interp.erase %root 1061 pdl_interp.finalize 1062 } 1063 } 1064} 1065 1066// CHECK-LABEL: test.switch_attribute_1 1067// CHECK: "test.success" 1068module @ir attributes { test.switch_attribute_1 } { 1069 "test.op"() { test_attr } : () -> () 1070} 1071 1072// ----- 1073 1074//===----------------------------------------------------------------------===// 1075// pdl_interp::SwitchOperandCountOp 1076//===----------------------------------------------------------------------===// 1077 1078module @patterns { 1079 func @matcher(%root : !pdl.operation) { 1080 pdl_interp.switch_operand_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end 1081 1082 ^pat: 1083 pdl_interp.switch_operand_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2 1084 1085 ^pat2: 1086 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1087 1088 ^end: 1089 pdl_interp.finalize 1090 } 1091 1092 module @rewriters { 1093 func @success(%root : !pdl.operation) { 1094 %op = pdl_interp.create_operation "test.success" 1095 pdl_interp.erase %root 1096 pdl_interp.finalize 1097 } 1098 } 1099} 1100 1101// CHECK-LABEL: test.switch_operand_1 1102// CHECK: "test.success" 1103module @ir attributes { test.switch_operand_1 } { 1104 %input = "test.op_input"() : () -> i32 1105 "test.op"(%input) : (i32) -> () 1106} 1107 1108// ----- 1109 1110//===----------------------------------------------------------------------===// 1111// pdl_interp::SwitchOperationNameOp 1112//===----------------------------------------------------------------------===// 1113 1114module @patterns { 1115 func @matcher(%root : !pdl.operation) { 1116 pdl_interp.switch_operation_name of %root to ["foo.op", "test.op"](^end, ^pat1) -> ^end 1117 1118 ^pat1: 1119 pdl_interp.switch_operation_name of %root to ["foo.op", "bar.op"](^end, ^end) -> ^pat2 1120 1121 ^pat2: 1122 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1123 1124 ^end: 1125 pdl_interp.finalize 1126 } 1127 1128 module @rewriters { 1129 func @success(%root : !pdl.operation) { 1130 %op = pdl_interp.create_operation "test.success" 1131 pdl_interp.erase %root 1132 pdl_interp.finalize 1133 } 1134 } 1135} 1136 1137// CHECK-LABEL: test.switch_operation_name_1 1138// CHECK: "test.success" 1139module @ir attributes { test.switch_operation_name_1 } { 1140 "test.op"() : () -> () 1141} 1142 1143// ----- 1144 1145//===----------------------------------------------------------------------===// 1146// pdl_interp::SwitchResultCountOp 1147//===----------------------------------------------------------------------===// 1148 1149module @patterns { 1150 func @matcher(%root : !pdl.operation) { 1151 pdl_interp.switch_result_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end 1152 1153 ^pat: 1154 pdl_interp.switch_result_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2 1155 1156 ^pat2: 1157 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1158 1159 ^end: 1160 pdl_interp.finalize 1161 } 1162 1163 module @rewriters { 1164 func @success(%root : !pdl.operation) { 1165 %op = pdl_interp.create_operation "test.success" 1166 pdl_interp.erase %root 1167 pdl_interp.finalize 1168 } 1169 } 1170} 1171 1172// CHECK-LABEL: test.switch_result_1 1173// CHECK: "test.success" 1174module @ir attributes { test.switch_result_1 } { 1175 "test.op"() : () -> i32 1176} 1177 1178// ----- 1179 1180//===----------------------------------------------------------------------===// 1181// pdl_interp::SwitchTypeOp 1182//===----------------------------------------------------------------------===// 1183 1184module @patterns { 1185 func @matcher(%root : !pdl.operation) { 1186 %attr = pdl_interp.get_attribute "test_attr" of %root 1187 pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end 1188 1189 ^pat1: 1190 %type = pdl_interp.get_attribute_type of %attr 1191 pdl_interp.switch_type %type to [i32, i64](^pat2, ^end) -> ^end 1192 1193 ^pat2: 1194 pdl_interp.switch_type %type to [i16, i64](^end, ^end) -> ^pat3 1195 1196 ^pat3: 1197 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1198 1199 ^end: 1200 pdl_interp.finalize 1201 } 1202 1203 module @rewriters { 1204 func @success(%root : !pdl.operation) { 1205 %op = pdl_interp.create_operation "test.success" 1206 pdl_interp.erase %root 1207 pdl_interp.finalize 1208 } 1209 } 1210} 1211 1212// CHECK-LABEL: test.switch_type_1 1213// CHECK: "test.success" 1214module @ir attributes { test.switch_type_1 } { 1215 "test.op"() { test_attr = 10 : i32 } : () -> () 1216} 1217 1218// ----- 1219 1220//===----------------------------------------------------------------------===// 1221// pdl_interp::SwitchTypesOp 1222//===----------------------------------------------------------------------===// 1223 1224module @patterns { 1225 func @matcher(%root : !pdl.operation) { 1226 %results = pdl_interp.get_results of %root : !pdl.range<value> 1227 %types = pdl_interp.get_value_type of %results : !pdl.range<type> 1228 pdl_interp.switch_types %types to [[i64, i64], [i32]](^pat2, ^end) -> ^end 1229 1230 ^pat2: 1231 pdl_interp.switch_types %types to [[i32], [i64, i32]](^end, ^end) -> ^pat3 1232 1233 ^pat3: 1234 pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end 1235 1236 ^end: 1237 pdl_interp.finalize 1238 } 1239 1240 module @rewriters { 1241 func @success(%root : !pdl.operation) { 1242 %op = pdl_interp.create_operation "test.success" 1243 pdl_interp.erase %root 1244 pdl_interp.finalize 1245 } 1246 } 1247} 1248 1249// CHECK-LABEL: test.switch_types_1 1250// CHECK: "test.success" 1251module @ir attributes { test.switch_types_1 } { 1252 %results:2 = "test.op"() : () -> (i64, i64) 1253} 1254