1//===-- SPIRVLogicalOps.td - MLIR SPIR-V Logical Ops -------*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file contains arithmetic ops for the SPIR-V dialect. It corresponds 10// to "3.32.15. Relational and Logical Instructions" of the SPIR-V spec. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef MLIR_DIALECT_SPIRV_IR_LOGICAL_OPS 15#define MLIR_DIALECT_SPIRV_IR_LOGICAL_OPS 16 17include "mlir/Dialect/SPIRV/IR/SPIRVBase.td" 18include "mlir/Interfaces/SideEffectInterfaces.td" 19 20class SPIRV_LogicalBinaryOp<string mnemonic, Type operandsType, 21 list<Trait> traits = []> : 22 // Result type is SPIRV_Bool. 23 SPIRV_BinaryOp<mnemonic, SPIRV_Bool, operandsType, 24 !listconcat(traits, [ 25 Pure, SameTypeOperands, 26 SameOperandsAndResultShape, 27 TypesMatchWith<"type of result to correspond to the `i1` " 28 "equivalent of the operand", 29 "operand1", "result", 30 "getUnaryOpResultType($_self)" 31 >])> { 32 let assemblyFormat = "$operand1 `,` $operand2 `:` type($operand1) attr-dict"; 33} 34 35class SPIRV_LogicalUnaryOp<string mnemonic, Type operandType, 36 list<Trait> traits = []> : 37 // Result type is SPIRV_Bool. 38 SPIRV_UnaryOp<mnemonic, SPIRV_Bool, operandType, 39 !listconcat(traits, [ 40 Pure, SameTypeOperands, SameOperandsAndResultShape, 41 TypesMatchWith<"type of result to correspond to the `i1` " 42 "equivalent of the operand", 43 "operand", "result", 44 "getUnaryOpResultType($_self)" 45 >])> { 46 let assemblyFormat = "$operand `:` type($operand) attr-dict"; 47} 48 49// ----- 50 51def SPIRV_FOrdEqualOp : SPIRV_LogicalBinaryOp<"FOrdEqual", SPIRV_Float, [Commutative]> { 52 let summary = "Floating-point comparison for being ordered and equal."; 53 54 let description = [{ 55 Result Type must be a scalar or vector of Boolean type. 56 57 The type of Operand 1 and Operand 2 must be a scalar or vector of 58 floating-point type. They must have the same type, and they must have 59 the same number of components as Result Type. 60 61 Results are computed per component. 62 63 #### Example: 64 65 ```mlir 66 %4 = spirv.FOrdEqual %0, %1 : f32 67 %5 = spirv.FOrdEqual %2, %3 : vector<4xf32> 68 ``` 69 }]; 70} 71 72// ----- 73 74def SPIRV_FOrdGreaterThanOp : SPIRV_LogicalBinaryOp<"FOrdGreaterThan", SPIRV_Float, []> { 75 let summary = [{ 76 Floating-point comparison if operands are ordered and Operand 1 is 77 greater than Operand 2. 78 }]; 79 80 let description = [{ 81 Result Type must be a scalar or vector of Boolean type. 82 83 The type of Operand 1 and Operand 2 must be a scalar or vector of 84 floating-point type. They must have the same type, and they must have 85 the same number of components as Result Type. 86 87 Results are computed per component. 88 89 #### Example: 90 91 ```mlir 92 %4 = spirv.FOrdGreaterThan %0, %1 : f32 93 %5 = spirv.FOrdGreaterThan %2, %3 : vector<4xf32> 94 ``` 95 }]; 96} 97 98// ----- 99 100def SPIRV_FOrdGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"FOrdGreaterThanEqual", SPIRV_Float, []> { 101 let summary = [{ 102 Floating-point comparison if operands are ordered and Operand 1 is 103 greater than or equal to Operand 2. 104 }]; 105 106 let description = [{ 107 Result Type must be a scalar or vector of Boolean type. 108 109 The type of Operand 1 and Operand 2 must be a scalar or vector of 110 floating-point type. They must have the same type, and they must have 111 the same number of components as Result Type. 112 113 Results are computed per component. 114 115 #### Example: 116 117 ```mlir 118 %4 = spirv.FOrdGreaterThanEqual %0, %1 : f32 119 %5 = spirv.FOrdGreaterThanEqual %2, %3 : vector<4xf32> 120 ``` 121 }]; 122} 123 124// ----- 125 126def SPIRV_FOrdLessThanOp : SPIRV_LogicalBinaryOp<"FOrdLessThan", SPIRV_Float, []> { 127 let summary = [{ 128 Floating-point comparison if operands are ordered and Operand 1 is less 129 than Operand 2. 130 }]; 131 132 let description = [{ 133 Result Type must be a scalar or vector of Boolean type. 134 135 The type of Operand 1 and Operand 2 must be a scalar or vector of 136 floating-point type. They must have the same type, and they must have 137 the same number of components as Result Type. 138 139 Results are computed per component. 140 141 #### Example: 142 143 ```mlir 144 %4 = spirv.FOrdLessThan %0, %1 : f32 145 %5 = spirv.FOrdLessThan %2, %3 : vector<4xf32> 146 ``` 147 }]; 148} 149 150// ----- 151 152def SPIRV_FOrdLessThanEqualOp : SPIRV_LogicalBinaryOp<"FOrdLessThanEqual", SPIRV_Float, []> { 153 let summary = [{ 154 Floating-point comparison if operands are ordered and Operand 1 is less 155 than or equal to Operand 2. 156 }]; 157 158 let description = [{ 159 Result Type must be a scalar or vector of Boolean type. 160 161 The type of Operand 1 and Operand 2 must be a scalar or vector of 162 floating-point type. They must have the same type, and they must have 163 the same number of components as Result Type. 164 165 Results are computed per component. 166 167 #### Example: 168 169 ```mlir 170 %4 = spirv.FOrdLessThanEqual %0, %1 : f32 171 %5 = spirv.FOrdLessThanEqual %2, %3 : vector<4xf32> 172 ``` 173 }]; 174} 175 176// ----- 177 178def SPIRV_FOrdNotEqualOp : SPIRV_LogicalBinaryOp<"FOrdNotEqual", SPIRV_Float, [Commutative]> { 179 let summary = "Floating-point comparison for being ordered and not equal."; 180 181 let description = [{ 182 Result Type must be a scalar or vector of Boolean type. 183 184 The type of Operand 1 and Operand 2 must be a scalar or vector of 185 floating-point type. They must have the same type, and they must have 186 the same number of components as Result Type. 187 188 Results are computed per component. 189 190 #### Example: 191 192 ```mlir 193 %4 = spirv.FOrdNotEqual %0, %1 : f32 194 %5 = spirv.FOrdNotEqual %2, %3 : vector<4xf32> 195 ``` 196 }]; 197} 198 199// ----- 200 201def SPIRV_FUnordEqualOp : SPIRV_LogicalBinaryOp<"FUnordEqual", SPIRV_Float, [Commutative]> { 202 let summary = "Floating-point comparison for being unordered or equal."; 203 204 let description = [{ 205 Result Type must be a scalar or vector of Boolean type. 206 207 The type of Operand 1 and Operand 2 must be a scalar or vector of 208 floating-point type. They must have the same type, and they must have 209 the same number of components as Result Type. 210 211 Results are computed per component. 212 213 #### Example: 214 215 ```mlir 216 %4 = spirv.FUnordEqual %0, %1 : f32 217 %5 = spirv.FUnordEqual %2, %3 : vector<4xf32> 218 ``` 219 }]; 220} 221 222// ----- 223 224def SPIRV_FUnordGreaterThanOp : SPIRV_LogicalBinaryOp<"FUnordGreaterThan", SPIRV_Float, []> { 225 let summary = [{ 226 Floating-point comparison if operands are unordered or Operand 1 is 227 greater than Operand 2. 228 }]; 229 230 let description = [{ 231 Result Type must be a scalar or vector of Boolean type. 232 233 The type of Operand 1 and Operand 2 must be a scalar or vector of 234 floating-point type. They must have the same type, and they must have 235 the same number of components as Result Type. 236 237 Results are computed per component. 238 239 #### Example: 240 241 ```mlir 242 %4 = spirv.FUnordGreaterThan %0, %1 : f32 243 %5 = spirv.FUnordGreaterThan %2, %3 : vector<4xf32> 244 ``` 245 }]; 246} 247 248// ----- 249 250def SPIRV_FUnordGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"FUnordGreaterThanEqual", SPIRV_Float, []> { 251 let summary = [{ 252 Floating-point comparison if operands are unordered or Operand 1 is 253 greater than or equal to Operand 2. 254 }]; 255 256 let description = [{ 257 Result Type must be a scalar or vector of Boolean type. 258 259 The type of Operand 1 and Operand 2 must be a scalar or vector of 260 floating-point type. They must have the same type, and they must have 261 the same number of components as Result Type. 262 263 Results are computed per component. 264 265 #### Example: 266 267 ```mlir 268 %4 = spirv.FUnordGreaterThanEqual %0, %1 : f32 269 %5 = spirv.FUnordGreaterThanEqual %2, %3 : vector<4xf32> 270 ``` 271 }]; 272} 273 274// ----- 275 276def SPIRV_FUnordLessThanOp : SPIRV_LogicalBinaryOp<"FUnordLessThan", SPIRV_Float, []> { 277 let summary = [{ 278 Floating-point comparison if operands are unordered or Operand 1 is less 279 than Operand 2. 280 }]; 281 282 let description = [{ 283 Result Type must be a scalar or vector of Boolean type. 284 285 The type of Operand 1 and Operand 2 must be a scalar or vector of 286 floating-point type. They must have the same type, and they must have 287 the same number of components as Result Type. 288 289 Results are computed per component. 290 291 #### Example: 292 293 ```mlir 294 %4 = spirv.FUnordLessThan %0, %1 : f32 295 %5 = spirv.FUnordLessThan %2, %3 : vector<4xf32> 296 ``` 297 }]; 298} 299 300// ----- 301 302def SPIRV_FUnordLessThanEqualOp : SPIRV_LogicalBinaryOp<"FUnordLessThanEqual", SPIRV_Float, []> { 303 let summary = [{ 304 Floating-point comparison if operands are unordered or Operand 1 is less 305 than or equal to Operand 2. 306 }]; 307 308 let description = [{ 309 Result Type must be a scalar or vector of Boolean type. 310 311 The type of Operand 1 and Operand 2 must be a scalar or vector of 312 floating-point type. They must have the same type, and they must have 313 the same number of components as Result Type. 314 315 Results are computed per component. 316 317 #### Example: 318 319 ```mlir 320 %4 = spirv.FUnordLessThanEqual %0, %1 : f32 321 %5 = spirv.FUnordLessThanEqual %2, %3 : vector<4xf32> 322 ``` 323 }]; 324} 325 326// ----- 327 328def SPIRV_FUnordNotEqualOp : SPIRV_LogicalBinaryOp<"FUnordNotEqual", SPIRV_Float, [Commutative]> { 329 let summary = "Floating-point comparison for being unordered or not equal."; 330 331 let description = [{ 332 Result Type must be a scalar or vector of Boolean type. 333 334 The type of Operand 1 and Operand 2 must be a scalar or vector of 335 floating-point type. They must have the same type, and they must have 336 the same number of components as Result Type. 337 338 Results are computed per component. 339 340 #### Example: 341 342 ```mlir 343 %4 = spirv.FUnordNotEqual %0, %1 : f32 344 %5 = spirv.FUnordNotEqual %2, %3 : vector<4xf32> 345 ``` 346 }]; 347} 348 349// ----- 350 351def SPIRV_IEqualOp : SPIRV_LogicalBinaryOp<"IEqual", 352 SPIRV_Integer, 353 [Commutative, UsableInSpecConstantOp]> { 354 let summary = "Integer comparison for equality."; 355 356 let description = [{ 357 Result Type must be a scalar or vector of Boolean type. 358 359 The type of Operand 1 and Operand 2 must be a scalar or vector of 360 integer type. They must have the same component width, and they must 361 have the same number of components as Result Type. 362 363 Results are computed per component. 364 365 #### Example: 366 367 ```mlir 368 %4 = spirv.IEqual %0, %1 : i32 369 %5 = spirv.IEqual %2, %3 : vector<4xi32> 370 ``` 371 }]; 372 373 let hasFolder = 1; 374} 375 376// ----- 377 378def SPIRV_INotEqualOp : SPIRV_LogicalBinaryOp<"INotEqual", 379 SPIRV_Integer, 380 [Commutative, UsableInSpecConstantOp]> { 381 let summary = "Integer comparison for inequality."; 382 383 let description = [{ 384 Result Type must be a scalar or vector of Boolean type. 385 386 The type of Operand 1 and Operand 2 must be a scalar or vector of 387 integer type. They must have the same component width, and they must 388 have the same number of components as Result Type. 389 390 Results are computed per component. 391 392 #### Example: 393 394 ```mlir 395 %4 = spirv.INotEqual %0, %1 : i32 396 %5 = spirv.INotEqual %2, %3 : vector<4xi32> 397 398 ``` 399 }]; 400 401 let hasFolder = 1; 402} 403 404// ----- 405 406def SPIRV_IsInfOp : SPIRV_LogicalUnaryOp<"IsInf", SPIRV_Float, []> { 407 let summary = "Result is true if x is an IEEE Inf, otherwise result is false"; 408 409 let description = [{ 410 Result Type must be a scalar or vector of Boolean type. 411 412 x must be a scalar or vector of floating-point type. It must have the 413 same number of components as Result Type. 414 415 Results are computed per component. 416 417 #### Example: 418 419 ```mlir 420 %2 = spirv.IsInf %0: f32 421 %3 = spirv.IsInf %1: vector<4xi32> 422 ``` 423 }]; 424} 425 426// ----- 427 428def SPIRV_IsNanOp : SPIRV_LogicalUnaryOp<"IsNan", SPIRV_Float, []> { 429 let summary = [{ 430 Result is true if x is an IEEE NaN, otherwise result is false. 431 }]; 432 433 let description = [{ 434 Result Type must be a scalar or vector of Boolean type. 435 436 x must be a scalar or vector of floating-point type. It must have the 437 same number of components as Result Type. 438 439 Results are computed per component. 440 441 #### Example: 442 443 ```mlir 444 %2 = spirv.IsNan %0: f32 445 %3 = spirv.IsNan %1: vector<4xi32> 446 ``` 447 }]; 448} 449 450// ----- 451 452def SPIRV_LogicalAndOp : SPIRV_LogicalBinaryOp<"LogicalAnd", 453 SPIRV_Bool, 454 [Commutative, 455 UsableInSpecConstantOp]> { 456 let summary = [{ 457 Result is true if both Operand 1 and Operand 2 are true. Result is false 458 if either Operand 1 or Operand 2 are false. 459 }]; 460 461 let description = [{ 462 Result Type must be a scalar or vector of Boolean type. 463 464 The type of Operand 1 must be the same as Result Type. 465 466 The type of Operand 2 must be the same as Result Type. 467 468 Results are computed per component. 469 470 #### Example: 471 472 ```mlir 473 %2 = spirv.LogicalAnd %0, %1 : i1 474 %2 = spirv.LogicalAnd %0, %1 : vector<4xi1> 475 ``` 476 }]; 477 478 let hasFolder = 1; 479} 480 481// ----- 482 483def SPIRV_LogicalEqualOp : SPIRV_LogicalBinaryOp<"LogicalEqual", 484 SPIRV_Bool, 485 [Commutative, 486 UsableInSpecConstantOp]> { 487 let summary = [{ 488 Result is true if Operand 1 and Operand 2 have the same value. Result is 489 false if Operand 1 and Operand 2 have different values. 490 }]; 491 492 let description = [{ 493 Result Type must be a scalar or vector of Boolean type. 494 495 The type of Operand 1 must be the same as Result Type. 496 497 The type of Operand 2 must be the same as Result Type. 498 499 Results are computed per component. 500 501 #### Example: 502 503 ```mlir 504 %2 = spirv.LogicalEqual %0, %1 : i1 505 %2 = spirv.LogicalEqual %0, %1 : vector<4xi1> 506 ``` 507 }]; 508 509 let hasFolder = 1; 510} 511 512// ----- 513 514def SPIRV_LogicalNotOp : SPIRV_LogicalUnaryOp<"LogicalNot", 515 SPIRV_Bool, 516 [UsableInSpecConstantOp]> { 517 let summary = [{ 518 Result is true if Operand is false. Result is false if Operand is true. 519 }]; 520 521 let description = [{ 522 Result Type must be a scalar or vector of Boolean type. 523 524 The type of Operand must be the same as Result Type. 525 526 Results are computed per component. 527 528 #### Example: 529 530 ```mlir 531 %2 = spirv.LogicalNot %0 : i1 532 %2 = spirv.LogicalNot %0 : vector<4xi1> 533 ``` 534 }]; 535 536 let hasCanonicalizer = 1; 537 let hasFolder = 1; 538} 539 540// ----- 541 542def SPIRV_LogicalNotEqualOp : SPIRV_LogicalBinaryOp<"LogicalNotEqual", 543 SPIRV_Bool, 544 [Commutative, 545 UsableInSpecConstantOp]> { 546 let summary = [{ 547 Result is true if Operand 1 and Operand 2 have different values. Result 548 is false if Operand 1 and Operand 2 have the same value. 549 }]; 550 551 let description = [{ 552 Result Type must be a scalar or vector of Boolean type. 553 554 The type of Operand 1 must be the same as Result Type. 555 556 The type of Operand 2 must be the same as Result Type. 557 558 Results are computed per component. 559 560 #### Example: 561 562 ```mlir 563 %2 = spirv.LogicalNotEqual %0, %1 : i1 564 %2 = spirv.LogicalNotEqual %0, %1 : vector<4xi1> 565 ``` 566 }]; 567 568 let hasFolder = 1; 569} 570 571// ----- 572 573def SPIRV_LogicalOrOp : SPIRV_LogicalBinaryOp<"LogicalOr", 574 SPIRV_Bool, 575 [Commutative, 576 UsableInSpecConstantOp]> { 577 let summary = [{ 578 Result is true if either Operand 1 or Operand 2 is true. Result is false 579 if both Operand 1 and Operand 2 are false. 580 }]; 581 582 let description = [{ 583 Result Type must be a scalar or vector of Boolean type. 584 585 The type of Operand 1 must be the same as Result Type. 586 587 The type of Operand 2 must be the same as Result Type. 588 589 Results are computed per component. 590 591 #### Example: 592 593 ```mlir 594 %2 = spirv.LogicalOr %0, %1 : i1 595 %2 = spirv.LogicalOr %0, %1 : vector<4xi1> 596 ``` 597 }]; 598 599 let hasFolder = 1; 600} 601 602// ----- 603 604def SPIRV_OrderedOp : SPIRV_LogicalBinaryOp<"Ordered", SPIRV_Float, [Commutative]> { 605 let summary = [{ 606 Result is true if both x == x and y == y are true, where IEEE comparison 607 is used, otherwise result is false. 608 }]; 609 610 let description = [{ 611 Result Type must be a scalar or vector of Boolean type. 612 613 x must be a scalar or vector of floating-point type. It must have the 614 same number of components as Result Type. 615 616 y must have the same type as x. 617 618 Results are computed per component. 619 620 #### Example: 621 622 ```mlir 623 %4 = spirv.Ordered %0, %1 : f32 624 %5 = spirv.Ordered %2, %3 : vector<4xf32> 625 ``` 626 }]; 627 628 let availability = [ 629 MinVersion<SPIRV_V_1_0>, 630 MaxVersion<SPIRV_V_1_6>, 631 Extension<[]>, 632 Capability<[SPIRV_C_Kernel]> 633 ]; 634} 635 636// ----- 637 638def SPIRV_SGreaterThanOp : SPIRV_LogicalBinaryOp<"SGreaterThan", 639 SPIRV_Integer, 640 [UsableInSpecConstantOp, SignedOp]> { 641 let summary = [{ 642 Signed-integer comparison if Operand 1 is greater than Operand 2. 643 }]; 644 645 let description = [{ 646 Result Type must be a scalar or vector of Boolean type. 647 648 The type of Operand 1 and Operand 2 must be a scalar or vector of 649 integer type. They must have the same component width, and they must 650 have the same number of components as Result Type. 651 652 Results are computed per component. 653 654 #### Example: 655 656 ```mlir 657 %4 = spirv.SGreaterThan %0, %1 : i32 658 %5 = spirv.SGreaterThan %2, %3 : vector<4xi32> 659 660 ``` 661 }]; 662 663 let hasFolder = 1; 664} 665 666// ----- 667 668def SPIRV_SGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"SGreaterThanEqual", 669 SPIRV_Integer, 670 [UsableInSpecConstantOp, 671 SignedOp]> { 672 let summary = [{ 673 Signed-integer comparison if Operand 1 is greater than or equal to 674 Operand 2. 675 }]; 676 677 let description = [{ 678 Result Type must be a scalar or vector of Boolean type. 679 680 The type of Operand 1 and Operand 2 must be a scalar or vector of 681 integer type. They must have the same component width, and they must 682 have the same number of components as Result Type. 683 684 Results are computed per component. 685 686 #### Example: 687 688 ```mlir 689 %4 = spirv.SGreaterThanEqual %0, %1 : i32 690 %5 = spirv.SGreaterThanEqual %2, %3 : vector<4xi32> 691 ``` 692 }]; 693 694 let hasFolder = 1; 695} 696 697// ----- 698 699def SPIRV_SLessThanOp : SPIRV_LogicalBinaryOp<"SLessThan", 700 SPIRV_Integer, 701 [UsableInSpecConstantOp, SignedOp]> { 702 let summary = [{ 703 Signed-integer comparison if Operand 1 is less than Operand 2. 704 }]; 705 706 let description = [{ 707 Result Type must be a scalar or vector of Boolean type. 708 709 The type of Operand 1 and Operand 2 must be a scalar or vector of 710 integer type. They must have the same component width, and they must 711 have the same number of components as Result Type. 712 713 Results are computed per component. 714 715 #### Example: 716 717 ```mlir 718 %4 = spirv.SLessThan %0, %1 : i32 719 %5 = spirv.SLessThan %2, %3 : vector<4xi32> 720 721 ``` 722 }]; 723 724 let hasFolder = 1; 725} 726 727// ----- 728 729def SPIRV_SLessThanEqualOp : SPIRV_LogicalBinaryOp<"SLessThanEqual", 730 SPIRV_Integer, 731 [UsableInSpecConstantOp, 732 SignedOp]> { 733 let summary = [{ 734 Signed-integer comparison if Operand 1 is less than or equal to Operand 735 2. 736 }]; 737 738 let description = [{ 739 Result Type must be a scalar or vector of Boolean type. 740 741 The type of Operand 1 and Operand 2 must be a scalar or vector of 742 integer type. They must have the same component width, and they must 743 have the same number of components as Result Type. 744 745 Results are computed per component. 746 747 #### Example: 748 749 ```mlir 750 %4 = spirv.SLessThanEqual %0, %1 : i32 751 %5 = spirv.SLessThanEqual %2, %3 : vector<4xi32> 752 ``` 753 }]; 754 755 let hasFolder = 1; 756} 757 758// ----- 759 760def SPIRV_SelectOp : SPIRV_Op<"Select", 761 [Pure, 762 AllTypesMatch<["true_value", "false_value", "result"]>, 763 UsableInSpecConstantOp, 764 DeclareOpInterfaceMethods<SelectLikeOpInterface>]> { 765 let summary = [{ 766 Select between two objects. Before version 1.4, results are only 767 computed per component. 768 }]; 769 770 let description = [{ 771 Before version 1.4, Result Type must be a pointer, scalar, or vector. 772 773 The types of Object 1 and Object 2 must be the same as Result Type. 774 775 Condition must be a scalar or vector of Boolean type. 776 777 If Condition is a scalar and true, the result is Object 1. If Condition 778 is a scalar and false, the result is Object 2. 779 780 If Condition is a vector, Result Type must be a vector with the same 781 number of components as Condition and the result is a mix of Object 1 782 and Object 2: When a component of Condition is true, the corresponding 783 component in the result is taken from Object 1, otherwise it is taken 784 from Object 2. 785 786 #### Example: 787 788 ```mlir 789 %3 = spirv.Select %0, %1, %2 : i1, f32 790 %3 = spirv.Select %0, %1, %2 : i1, vector<3xi32> 791 %3 = spirv.Select %0, %1, %2 : vector<3xi1>, vector<3xf32> 792 ``` 793 }]; 794 795 let arguments = (ins 796 SPIRV_ScalarOrVectorOf<SPIRV_Bool>:$condition, 797 SPIRV_SelectType:$true_value, 798 SPIRV_SelectType:$false_value 799 ); 800 801 let results = (outs 802 SPIRV_SelectType:$result 803 ); 804 805 let assemblyFormat = [{ 806 operands attr-dict `:` type($condition) `,` type($result) 807 }]; 808 809 // These ops require dynamic availability specification based on operand and 810 // result types. 811 bit autogenAvailability = 0; 812 813 let hasFolder = 1; 814} 815 816// ----- 817 818def SPIRV_UGreaterThanOp : SPIRV_LogicalBinaryOp<"UGreaterThan", 819 SPIRV_Integer, 820 [UnsignedOp, 821 UsableInSpecConstantOp]> { 822 let summary = [{ 823 Unsigned-integer comparison if Operand 1 is greater than Operand 2. 824 }]; 825 826 let description = [{ 827 Result Type must be a scalar or vector of Boolean type. 828 829 The type of Operand 1 and Operand 2 must be a scalar or vector of 830 integer type. They must have the same component width, and they must 831 have the same number of components as Result Type. 832 833 Results are computed per component. 834 835 #### Example: 836 837 ```mlir 838 %4 = spirv.UGreaterThan %0, %1 : i32 839 %5 = spirv.UGreaterThan %2, %3 : vector<4xi32> 840 ``` 841 }]; 842 843 let hasFolder = 1; 844} 845 846// ----- 847 848def SPIRV_UGreaterThanEqualOp : SPIRV_LogicalBinaryOp<"UGreaterThanEqual", 849 SPIRV_Integer, 850 [UnsignedOp, 851 UsableInSpecConstantOp]> { 852 let summary = [{ 853 Unsigned-integer comparison if Operand 1 is greater than or equal to 854 Operand 2. 855 }]; 856 857 let description = [{ 858 Result Type must be a scalar or vector of Boolean type. 859 860 The type of Operand 1 and Operand 2 must be a scalar or vector of 861 integer type. They must have the same component width, and they must 862 have the same number of components as Result Type. 863 864 Results are computed per component. 865 866 #### Example: 867 868 ```mlir 869 %4 = spirv.UGreaterThanEqual %0, %1 : i32 870 %5 = spirv.UGreaterThanEqual %2, %3 : vector<4xi32> 871 ``` 872 }]; 873 874 let hasFolder = 1; 875} 876 877// ----- 878 879def SPIRV_ULessThanOp : SPIRV_LogicalBinaryOp<"ULessThan", 880 SPIRV_Integer, 881 [UnsignedOp, UsableInSpecConstantOp]> { 882 let summary = [{ 883 Unsigned-integer comparison if Operand 1 is less than Operand 2. 884 }]; 885 886 let description = [{ 887 Result Type must be a scalar or vector of Boolean type. 888 889 The type of Operand 1 and Operand 2 must be a scalar or vector of 890 integer type. They must have the same component width, and they must 891 have the same number of components as Result Type. 892 893 Results are computed per component. 894 895 #### Example: 896 897 ```mlir 898 %4 = spirv.ULessThan %0, %1 : i32 899 %5 = spirv.ULessThan %2, %3 : vector<4xi32> 900 ``` 901 }]; 902 903 let hasFolder = 1; 904} 905 906// ----- 907 908def SPIRV_UnorderedOp : SPIRV_LogicalBinaryOp<"Unordered", SPIRV_Float, [Commutative]> { 909 let summary = [{ 910 Result is true if either x or y is an IEEE NaN, otherwise result is 911 false. 912 }]; 913 914 let description = [{ 915 Result Type must be a scalar or vector of Boolean type. 916 917 x must be a scalar or vector of floating-point type. It must have the 918 same number of components as Result Type. 919 920 y must have the same type as x. 921 922 Results are computed per component. 923 924 #### Example: 925 926 ```mlir 927 %4 = spirv.Unordered %0, %1 : f32 928 %5 = spirv.Unordered %2, %3 : vector<4xf32> 929 ``` 930 }]; 931 932 let availability = [ 933 MinVersion<SPIRV_V_1_0>, 934 MaxVersion<SPIRV_V_1_6>, 935 Extension<[]>, 936 Capability<[SPIRV_C_Kernel]> 937 ]; 938} 939 940// ----- 941 942def SPIRV_ULessThanEqualOp : SPIRV_LogicalBinaryOp<"ULessThanEqual", 943 SPIRV_Integer, 944 [UnsignedOp, 945 UsableInSpecConstantOp]> { 946 let summary = [{ 947 Unsigned-integer comparison if Operand 1 is less than or equal to 948 Operand 2. 949 }]; 950 951 let description = [{ 952 Result Type must be a scalar or vector of Boolean type. 953 954 The type of Operand 1 and Operand 2 must be a scalar or vector of 955 integer type. They must have the same component width, and they must 956 have the same number of components as Result Type. 957 958 Results are computed per component. 959 960 #### Example: 961 962 ```mlir 963 %4 = spirv.ULessThanEqual %0, %1 : i32 964 %5 = spirv.ULessThanEqual %2, %3 : vector<4xi32> 965 ``` 966 }]; 967 968 let hasFolder = 1; 969} 970 971#endif // MLIR_DIALECT_SPIRV_IR_LOGICAL_OPS 972