llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Henrich Lauko (xlauko)

<details>
<summary>Changes</summary>

LLVM lowering uses per-op patterns generated by the CIRLowering.inc TableGen
infrastructure instead of a monolithic TypeSwitch dispatch.

---

Patch is 817.97 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/184227.diff


108 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+49-28) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+236-51) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td (+18) 
- (modified) clang/include/clang/CIR/Interfaces/CIROpInterfaces.td (+26) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+4-4) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+10-16) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp (+14-14) 
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+11-23) 
- (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp (+2-2) 
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+30-22) 
- (modified) clang/lib/CIR/Dialect/Transforms/FlattenCFG.cpp (+2-3) 
- (modified) clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp (+40-59) 
- (modified) 
clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerItaniumCXXABI.cpp (+28-14) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+126-103) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (+1) 
- (modified) clang/test/CIR/CodeGen/assign-operator.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/atomic.c (+49-49) 
- (modified) clang/test/CIR/CodeGen/basic.c (+3-3) 
- (modified) clang/test/CIR/CodeGen/basic.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/binop.cpp (+12-12) 
- (modified) clang/test/CIR/CodeGen/bitfields.c (+1-1) 
- (modified) clang/test/CIR/CodeGen/complex-compound-assignment.cpp (+29-29) 
- (modified) clang/test/CIR/CodeGen/complex-mul-div.cpp (+124-124) 
- (modified) clang/test/CIR/CodeGen/complex.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/compound_assign.cpp (+8-8) 
- (modified) clang/test/CIR/CodeGen/if.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/integer-overflow.c (+6-6) 
- (modified) clang/test/CIR/CodeGen/lambda.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/namespace.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/new.cpp (+5-5) 
- (modified) clang/test/CIR/CodeGen/no-odr-use.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/non-type-template-param.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/opaque.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/pointer-to-data-member-cast.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/pointer-to-member-func-cast.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/pointer-to-member-func-cmp.cpp (+4-4) 
- (modified) clang/test/CIR/CodeGen/pointer-to-member-func.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/requires-expr.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/size-of-vla.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/struct-init.cpp (+3-3) 
- (modified) clang/test/CIR/CodeGen/switch_flat_op.cpp (+4-4) 
- (modified) clang/test/CIR/CodeGen/ternary.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/throws.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/try-catch.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/variable-decomposition.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/vector-ext-element.cpp (+4-4) 
- (modified) clang/test/CIR/CodeGen/vector-ext.cpp (+15-15) 
- (modified) clang/test/CIR/CodeGen/vector.cpp (+17-17) 
- (modified) clang/test/CIR/CodeGen/vla.c (+3-3) 
- (modified) clang/test/CIR/CodeGenBuiltins/AArch64/acle_sve_len.c (+12-12) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx10_2_512bf16-builtins.c 
(+1-1) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx10_2bf16-builtins.c (+2-2) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx2-builtins.c (+4-4) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512bw-builtins.c (+14-14) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512dq-builtins.c (+491-491) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c (+11-11) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512fp16-builtins.c (+1-1) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512vldq-builtins.c (+4-4) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/cmp-builtins.c (+23-23) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/sse2-builtins.c (+3-3) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/sse41-builtins.c (+92-92) 
- (modified) clang/test/CIR/CodeGenOpenACC/atomic-capture.cpp (+18-18) 
- (modified) clang/test/CIR/CodeGenOpenACC/atomic-update.cpp (+5-5) 
- (modified) clang/test/CIR/CodeGenOpenACC/atomic-write.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp 
(+1-1) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined-private-clause.cpp (+1-1) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp 
(+57-57) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-float.cpp 
(+6-6) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-inline-ops.cpp (+9-9) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-int.cpp 
(+15-15) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-outline-ops.cpp (+9-9) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined.cpp (+6-6) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp 
(+1-1) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-private-clause.cpp (+1-1) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.c (+57-57) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.cpp (+57-57) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.c 
(+6-6) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.cpp 
(+6-6) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-inline-ops.cpp (+9-9) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.c 
(+15-15) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.cpp 
(+15-15) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-outline-ops.cpp (+9-9) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-unsigned-int.c (+15-15) 
- (modified) clang/test/CIR/CodeGenOpenACC/firstprivate-clause-recipes.cpp 
(+23-23) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop-private-clause.cpp (+1-1) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-default-ops.cpp (+57-57) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-float.cpp 
(+6-6) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-inline-ops.cpp 
(+9-9) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-int.cpp 
(+15-15) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-outline-ops.cpp (+9-9) 
- (modified) clang/test/CIR/CodeGenOpenACC/loop.cpp (+6-6) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-CtorDtor.cpp (+8-8) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/private-clause-pointer-array-recipes-CtorDtor.cpp 
(+73-73) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/private-clause-pointer-array-recipes-NoOps.cpp 
(+52-52) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/private-clause-pointer-array-recipes-int.cpp 
(+52-52) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/private-clause-pointer-recipes-CtorDtor.cpp 
(+30-30) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/private-clause-pointer-recipes-NoOps.cpp (+24-24) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/private-clause-pointer-recipes-int.cpp (+24-24) 
- (modified) clang/test/CIR/CodeGenOpenACC/reduction-clause-recipes.cpp 
(+25-25) 
- (modified) clang/test/CIR/CodeGenOpenMP/omp-llvmir.c (+1-1) 
- (modified) clang/test/CIR/CodeGenOpenMP/parallel.c (+2-2) 
- (modified) clang/test/CIR/IR/throw.cir (+2-2) 
- (modified) clang/test/CIR/IR/vector.cir (+2-2) 
- (modified) clang/test/CIR/Lowering/binop-bool.cir (+3-3) 
- (modified) clang/test/CIR/Lowering/binop-fp.cir (+8-8) 
- (modified) clang/test/CIR/Lowering/binop-signed-int.cir (+11-11) 
- (modified) clang/test/CIR/Lowering/binop-unsigned-int.cir (+11-11) 
- (modified) clang/test/CIR/Transforms/switch.cir (+2-2) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 32d0921d15363..117ee06a16714 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -544,11 +544,36 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
   // Binary Operators
   
//===--------------------------------------------------------------------===//
 
-  mlir::Value createBinop(mlir::Location loc, mlir::Value lhs,
-                          cir::BinOpKind kind, mlir::Value rhs) {
-    return cir::BinOp::create(*this, loc, lhs.getType(), kind, lhs, rhs);
+private:
+  // Builds a simple binary op whose result type equals the operand type.
+  template <typename Op>
+  mlir::Value createBinaryOp(mlir::Location loc, mlir::Value lhs,
+                             mlir::Value rhs) {
+    return Op::create(*this, loc, lhs, rhs);
+  }
+
+  // Builds a binary op with nsw/nuw overflow flags (no sat, e.g. Mul).
+  template <typename Op>
+  mlir::Value createOverflowOp(mlir::Location loc, mlir::Value lhs,
+                               mlir::Value rhs, OverflowBehavior ob) {
+    auto op = Op::create(*this, loc, lhs, rhs);
+    op.setNoUnsignedWrap(ob & OverflowBehavior::NoUnsignedWrap);
+    op.setNoSignedWrap(ob & OverflowBehavior::NoSignedWrap);
+    return op;
+  }
+
+  // Builds a binary op with nsw/nuw overflow flags and saturation (Add, Sub).
+  template <typename Op>
+  mlir::Value createOverflowSatOp(mlir::Location loc, mlir::Value lhs,
+                                  mlir::Value rhs, OverflowBehavior ob) {
+    auto op = Op::create(*this, loc, lhs, rhs);
+    op.setNoUnsignedWrap(ob & OverflowBehavior::NoUnsignedWrap);
+    op.setNoSignedWrap(ob & OverflowBehavior::NoSignedWrap);
+    op.setSaturated(ob & OverflowBehavior::Saturated);
+    return op;
   }
 
+public:
   mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
                                unsigned bits) {
     llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
@@ -557,11 +582,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
   }
 
   mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
-    return createBinop(loc, lhs, cir::BinOpKind::And, rhs);
+    return createBinaryOp<cir::AndOp>(loc, lhs, rhs);
   }
 
   mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
-    return createBinop(loc, lhs, cir::BinOpKind::Or, rhs);
+    return createBinaryOp<cir::OrOp>(loc, lhs, rhs);
   }
 
   mlir::Value createSelect(mlir::Location loc, mlir::Value condition,
@@ -584,13 +609,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 
   mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
                         OverflowBehavior ob = OverflowBehavior::None) {
-    auto op = cir::BinOp::create(*this, loc, lhs.getType(), 
cir::BinOpKind::Mul,
-                                 lhs, rhs);
-    op.setNoUnsignedWrap(
-        llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
-    op.setNoSignedWrap(
-        llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
-    return op;
+    return createOverflowOp<cir::MulOp>(loc, lhs, rhs, ob);
   }
   mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs,
                            mlir::Value rhs) {
@@ -603,14 +622,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 
   mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
                         OverflowBehavior ob = OverflowBehavior::None) {
-    auto op = cir::BinOp::create(*this, loc, lhs.getType(), 
cir::BinOpKind::Sub,
-                                 lhs, rhs);
-    op.setNoUnsignedWrap(
-        llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
-    op.setNoSignedWrap(
-        llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
-    op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated));
-    return op;
+    return createOverflowSatOp<cir::SubOp>(loc, lhs, rhs, ob);
   }
 
   mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs,
@@ -625,14 +637,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 
   mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
                         OverflowBehavior ob = OverflowBehavior::None) {
-    auto op = cir::BinOp::create(*this, loc, lhs.getType(), 
cir::BinOpKind::Add,
-                                 lhs, rhs);
-    op.setNoUnsignedWrap(
-        llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
-    op.setNoSignedWrap(
-        llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
-    op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated));
-    return op;
+    return createOverflowSatOp<cir::AddOp>(loc, lhs, rhs, ob);
   }
 
   mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs,
@@ -645,6 +650,22 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
   }
 
+  mlir::Value createDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
+    return createBinaryOp<cir::DivOp>(loc, lhs, rhs);
+  }
+
+  mlir::Value createRem(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
+    return createBinaryOp<cir::RemOp>(loc, lhs, rhs);
+  }
+
+  mlir::Value createXor(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
+    return createBinaryOp<cir::XorOp>(loc, lhs, rhs);
+  }
+
+  mlir::Value createMax(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
+    return createBinaryOp<cir::MaxOp>(loc, lhs, rhs);
+  }
+
   cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind,
                            mlir::Value lhs, mlir::Value rhs) {
     return cir::CmpOp::create(*this, loc, kind, lhs, rhs);
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index a5a5197cd3ea6..1315cde17f946 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2119,76 +2119,261 @@ def CIR_BinOpOverflowOp : CIR_Op<"binop.overflow", 
[Pure, SameTypeOperands]> {
 
 
 
//===----------------------------------------------------------------------===//
-// BinOp
-//===----------------------------------------------------------------------===//
-
-// FIXME: represent Commutative, Idempotent traits for appropriate binops
-def CIR_BinOpKind : CIR_I32EnumAttr<
-  "BinOpKind", "binary operation (arith and logic) kind", [
-    I32EnumAttrCase<"Mul", 0, "mul">,
-    I32EnumAttrCase<"Div", 1, "div">,
-    I32EnumAttrCase<"Rem", 2, "rem">,
-    I32EnumAttrCase<"Add", 3, "add">,
-    I32EnumAttrCase<"Sub", 4, "sub">,
-    I32EnumAttrCase<"And", 5, "and">,
-    I32EnumAttrCase<"Xor", 6, "xor">,
-    I32EnumAttrCase<"Or", 7, "or">,
-    I32EnumAttrCase<"Max", 8, "max">
-]>;
+// Binary Arithmetic and Logic Operations
+//===----------------------------------------------------------------------===//
 
-def CIR_BinOp : CIR_Op<"binop", [
-  Pure, SameTypeOperands, SameOperandsAndResultType
-]> {
-  let summary = "Binary operations (arith and logic)";
+// Base class for all CIR binary arithmetic/logic operations.
+// `type` constrains the lhs/rhs/result type.
+class CIR_BinaryOp<string mnemonic, Type type, list<Trait> traits = []>
+    : CIR_Op<mnemonic, !listconcat([
+        NoMemoryEffect, SameOperandsAndResultType,
+        DeclareOpInterfaceMethods<CIR_BinaryOpInterface>
+      ], traits)>
+{
+  let arguments = (ins
+    type:$lhs,
+    type:$rhs
+  );
+
+  let results = (outs type:$result);
+
+  let assemblyFormat = [{
+    $lhs `,` $rhs `:` type($lhs) attr-dict
+  }];
+}
+
+// Base class for binary ops that support integer overflow flags (nsw/nuw)
+// and saturated arithmetic.
+class CIR_BinaryOverflowOp<string mnemonic, Type type, list<Trait> traits = []>
+    : CIR_BinaryOp<mnemonic, type, !listconcat([Pure], traits)>
+{
+  let arguments = (ins
+    type:$lhs, type:$rhs,
+    UnitProp:$no_signed_wrap,
+    UnitProp:$no_unsigned_wrap,
+    UnitProp:$saturated
+  );
+
+  let assemblyFormat = [{
+    (`nsw` $no_signed_wrap^)?
+    (`nuw` $no_unsigned_wrap^)?
+    (`sat` $saturated^)?
+    $lhs `,` $rhs `:` type($lhs) attr-dict
+  }];
+
+  let hasVerifier = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// AddOp
+//===----------------------------------------------------------------------===//
+
+def CIR_AddOp : CIR_BinaryOverflowOp<"add", CIR_AnyArithType> {
+  let summary = "Integer or floating-point addition";
   let description = [{
-    cir.binop performs the binary operation according to
-    the specified opcode kind: [mul, div, rem, add, sub,
-    and, xor, or, max].
+    The `cir.add` operation performs addition on integer or floating-point
+    operands. Both operands and the result must have the same type.
 
-    It requires two input operands and has one result, all types
-    should be the same.
+    For integer types, the optional `nsw` (no signed wrap) and `nuw` (no
+    unsigned wrap) unit attributes indicate that the result is poison if signed
+    or unsigned overflow occurs, respectively. The optional `sat` (saturated)
+    attribute clamps the result to the type's representable range instead of
+    wrapping. The `nsw`/`nuw` flags and `sat` are mutually exclusive.
+    
+    Example:
+
+    ```mlir
+    %0 = cir.add %a, %b : !s32i
+    %1 = cir.add %a, %b nsw : !s32i
+    %2 = cir.add %a, %b nuw : !u32i
+    %3 = cir.add %a, %b sat : !s32i
+    %4 = cir.add %a, %b : !cir.float
+    ```
+  }];
+}
 
-    If the `nsw` (no signed wrap) or `nuw` (no unsigned wrap) attributes are
-    present, the result is poison if signed or unsigned overflow occurs
-    (respectively).
+//===----------------------------------------------------------------------===//
+// SubOp
+//===----------------------------------------------------------------------===//
 
-    If the `sat` (saturated) attribute is present, the result is clamped to
-    the maximum value representatable by the type if it would otherwise
-    exceed that value and is clamped to the minimum representable value if
-    it would otherwise be below that value.
+def CIR_SubOp : CIR_BinaryOverflowOp<"sub", CIR_AnyArithType> {
+  let summary = "Integer or floating-point subtraction";
+  let description = [{
+    The `cir.sub` operation performs subtraction on integer or floating-point
+    operands. Both operands and the result must have the same type.
+
+    For integer types, the optional `nsw` (no signed wrap) and `nuw` (no
+    unsigned wrap) unit attributes indicate that the result is poison if signed
+    or unsigned overflow occurs, respectively. The optional `sat` (saturated)
+    attribute clamps the result to the type's representable range. The
+    `nsw`/`nuw` flags and `sat` are mutually exclusive.
+    
+    Example:
 
     ```mlir
-    %5 = cir.binop(add, %1, %2) : !s32i
-    %6 = cir.binop(mul, %1, %2) : !u8i
-    %7 = cir.binop(add, %1, %2) nsw : !s32i
-    %8 = cir.binop(add, %3, %4) nuw : !u32i
-    %9 = cir.binop(add, %1, %2) sat : !s32i
+    %0 = cir.sub %a, %b : !s32i
+    %1 = cir.sub %a, %b nsw : !s32i
+    %2 = cir.sub %a, %b sat : !s32i
+    %3 = cir.sub %a, %b : !cir.float
     ```
   }];
+}
+
+//===----------------------------------------------------------------------===//
+// MulOp
+//===----------------------------------------------------------------------===//
 
+def CIR_MulOp : CIR_BinaryOp<"mul", CIR_AnyArithType> {
+  let summary = "Integer or floating-point multiplication";
+  let description = [{
+    The `cir.mul` operation performs multiplication on integer or 
floating-point
+    operands. Both operands and the result must have the same type.
+
+    For integer types, the optional `nsw` (no signed wrap) and `nuw` (no
+    unsigned wrap) unit attributes indicate that the result is poison if signed
+    or unsigned overflow occurs, respectively.
+
+    Example:
+
+    ```mlir
+    %0 = cir.mul %a, %b : !s32i
+    %1 = cir.mul %a, %b nsw : !s32i
+    %2 = cir.mul %a, %b nuw : !u32i
+    %3 = cir.mul %a, %b : !cir.float
+    ```
+  }];
+  
   let arguments = (ins
-    CIR_BinOpKind:$kind,
-    CIR_AnyType:$lhs, CIR_AnyType:$rhs,
-    UnitAttr:$no_unsigned_wrap,
-    UnitAttr:$no_signed_wrap,
-    UnitAttr:$saturated
+    CIR_AnyArithType:$lhs, CIR_AnyArithType:$rhs,
+    UnitProp:$no_signed_wrap,
+    UnitProp:$no_unsigned_wrap
   );
 
-  // TODO: get more accurate than CIR_AnyType
-  let results = (outs CIR_AnyType:$result);
-
   let assemblyFormat = [{
-    `(` $kind `,` $lhs `,` $rhs  `)`
     (`nsw` $no_signed_wrap^)?
     (`nuw` $no_unsigned_wrap^)?
-    (`sat` $saturated^)?
-    `:` type($lhs) attr-dict
+    $lhs `,` $rhs `:` type($lhs) attr-dict
   }];
 
   let hasVerifier = 1;
+}
 
-  let extraLLVMLoweringPatternDecl = [{
-    mlir::LLVM::IntegerOverflowFlags getIntOverflowFlag(cir::BinOp op) const;
+//===----------------------------------------------------------------------===//
+// DivOp
+//===----------------------------------------------------------------------===//
+
+def CIR_DivOp : CIR_BinaryOp<"div", CIR_AnyArithType> {
+  let summary = "Integer or floating-point division";
+  let description = [{
+    The `cir.div` operation performs division on integer or floating-point
+    operands. Both operands and the result must have the same type.
+
+    Example:
+
+    ```mlir
+    %0 = cir.div %a, %b : !s32i
+    %1 = cir.div %a, %b : !u32i
+    %2 = cir.div %a, %b : !cir.float
+    ```
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// RemOp
+//===----------------------------------------------------------------------===//
+
+def CIR_RemOp : CIR_BinaryOp<"rem", CIR_AnyArithType> {
+  let summary = "Integer or floating-point remainder";
+  let description = [{
+    The `cir.rem` operation computes the remainder of division on integer or
+    floating-point operands. Both operands and the result must have the same
+    type.
+    
+    Example:
+
+    ```mlir
+    %0 = cir.rem %a, %b : !s32i
+    %1 = cir.rem %a, %b : !u32i
+    %2 = cir.rem %a, %b : !cir.float
+    ```
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// AndOp
+//===----------------------------------------------------------------------===//
+
+// FIXME: Commutative, Idempotent traits
+def CIR_AndOp : CIR_BinaryOp<"and", CIR_AnyBitwiseType> {
+  let summary = "Bitwise AND";
+  let description = [{
+    The `cir.and` operation performs a bitwise AND on integer operands.
+    Both operands and the result must have the same integer type.
+    
+    Example:
+
+    ```mlir
+    %0 = cir.and %a, %b : !s32i
+    %1 = cir.and %a, %b : !cir.bool
+    ```
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// OrOp
+//===----------------------------------------------------------------------===//
+
+// FIXME: Commutative, Idempotent traits
+def CIR_OrOp : CIR_BinaryOp<"or", CIR_AnyBitwiseType> {
+  let summary = "Bitwise OR";
+  let description = [{
+    The `cir.or` operation performs a bitwise OR on integer operands.
+    Both operands and the result must have the same integer type.
+    
+    Example:
+
+    ```mlir
+    %0 = cir.or %a, %b : !s32i
+    %1 = cir.or %a, %b : !cir.bool
+    ```
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// XorOp
+//===----------------------------------------------------------------------===//
+
+def CIR_XorOp : CIR_BinaryOp<"xor", CIR_AnyBitwiseType> {
+  let summary = "Bitwise XOR";
+  let description = [{
+    The `cir.xor` operation performs a bitwise XOR on integer operands.
+    Both operands and the result must have the same integer type.
+
+    Example:
+
+    ```mlir
+    %0 = cir.xor %a, %b : !s32i
+    %1 = cir.xor %a, %b : !cir.bool
+    ```
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// MaxOp
+//===----------------------------------------------------------------------===//
+
+def CIR_MaxOp : CIR_BinaryOp<"max", CIR_AnyIntOrVecOfIntType> {
+  let summary = "Integer maximum";
+  let description = [{
+    The `cir.max` operation computes the maximum of two integer operands.
+    Both operands and the result must have the same integer type.
+
+    Example:
+
+    ```mlir
+    %0 = cir.max %a, %b : !s32i
+    %1 = cir.max %a, %b : !u32i
+    ```
   }];
 }
 
@@ -2206,7 +2391,7 @@ def CIR_ShiftOp : CIR_Op<"shift", [Pure]> {
     integer type, or all integer type. If they are vectors, each vector 
element of
     the shift target is shifted by the corresponding shift amount in
     the shift amount vector.
-
+    
     ```mlir
     %res = cir.shift(left, %lhs : !u64i, %amount : !s32i) -> !u64i
     %new_vec = cir.shift(left, %lhs : !cir.vector<2 x !s32i>, %rhs :
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
index 1a5bae13c96df..f48b13ff9718b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
@@ -167,6 +167,11 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, 
CIR_AnyIntType],
     let cppFunctionName = "isAnyIntegerOrFloatingPointType";
 }
 
+def CIR_AnyIntOrBoolType
+    : AnyTypeOf<[CIR_AnyIntType, CIR_AnyBoolType], "integer or boolean type"> {
+  let cppFunctionName = "isIntOrBoolType";
+}
+
 def CIR_AnyIntOrBoolOrFloatType
     : AnyTypeOf<[CIR_AnyBoolType, CIR_AnyFloatType, CIR_AnyIntType],
                 "integer, boolean or floating point type"> {
@@ -331,6 +336,19 @@ def CIR_AnyFloatOrVecOfFloatType
     let cppFunctionName = "isFPOrVectorOfFPType";
 }
 
+// Types valid for arithmetic ops (add/sub/mul/div/rem):
+// scalar or vector of integer, boolean, or floating-point.
+def CIR_AnyArithType
+    : AnyTypeOf<[CIR_AnyIntType, CIR_AnyBoolType, CIR_AnyFloatType,
+                 CIR_VectorOfIntType, CIR_VectorOfFloatType],
+                "integer, boolean, floating-point, or vector of 
integer/float">;
+
+// Types valid for bitwise ops (and/or/xor):
+// integer, boolean, or vector of integer (no floating-point).
+def CIR_AnyBitwiseType
+    : AnyTypeOf<[CIR_AnyIntType, CIR_AnyBoolType, CIR_VectorOfIntType],
+                "integer, boolean, or vector of integer">;
+
 
//===----------------------------------------------------------------------===//
 // Data member type predicates
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td 
b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
index c73eadaff6f3e..c715e2e03a7b9 100644
--- a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
+++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
@@ -163,6 +163,32 @@ let cppNamespace = "::cir" in {
     }];
   }
 
+  def CIR_BinaryOpInterface : OpInterface<"BinaryOpInterface"> {
+    let description = [{
+      Common interface for CIR binary arithmetic and logic operations.
+      Provides uniform access to the left-hand side operand, right-hand side
+      operand, and result of any binary operation in the CIR dialect.
+    }];
+
+    let methods = [
+      InterfaceMethod<"Return the left-hand side operand.",
+        "mlir::Value", "getLhs", (ins), [{}],
+        /*defaultImplementation=*/[{
+          return $_op.getLhs();
+        }]>,
+      InterfaceMethod<"Return the right-hand side operand.",
+        "mlir::Value", "getRhs", (ins), [{}],
+        /*defaultImplementation=*/[{
+          return $_op.getRhs();
+        }]>,
+      InterfaceMethod<"Return the result value.",
+        "mlir::Value", "getResult", (ins), [{}],
+        /*defaultImplementation=*/[{
+          return $_op.getResult();
+        }]>,
+    ];
+  }
+
 } // namespace cir
 
 #endif // CLANG_CIR_INTERFACES_CIROPINTERFACES_TD
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index cd13c9578adf7..cbb6a78d5212b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -449,7 +449,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
     assert(!cir::MissingFeatures::fpConstraints());
     assert(!cir::MissingFeatures::fastMathFlags());
 
-    return cir::BinOp::create(*this, loc...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/184227
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to