llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang 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
