@@ -1991,6 +1991,7 @@ class CIR_CallOpBase<string mnemonic, list<Trait> extra_traits = []>
19911991
19921992 dag commonArgs = (ins OptionalAttr<FlatSymbolRefAttr>:$callee,
19931993 Variadic<CIR_AnyType>:$args,
1994+ UnitAttr:$nothrow,
19941995 DefaultValuedAttr<CIR_SideEffect, "SideEffect::All">:$side_effect);
19951996}
19961997
@@ -2020,29 +2021,14 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> {
20202021 let arguments = commonArgs;
20212022
20222023 let builders = [
2023- // Build a call op for a direct call
20242024 OpBuilder<(ins "mlir::SymbolRefAttr":$callee, "mlir::Type":$resType,
2025- "mlir::ValueRange":$operands,
2026- CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
2027- assert(callee && "callee attribute is required for direct call");
2025+ "mlir::ValueRange":$operands), [{
20282026 $_state.addOperands(operands);
2029- $_state.addAttribute("callee", callee);
2030- $_state.addAttribute("side_effect",
2031- SideEffectAttr::get($_builder.getContext(), sideEffect));
2027+ if (callee)
2028+ $_state.addAttribute("callee", callee);
20322029 if (resType && !isa<VoidType>(resType))
20332030 $_state.addTypes(resType);
2034- }]>,
2035- // Build a call op for an indirect call
2036- OpBuilder<(ins "mlir::Value":$calleePtr, "mlir::Type":$resType,
2037- "mlir::ValueRange":$operands,
2038- CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
2039- $_state.addOperands(calleePtr);
2040- $_state.addOperands(operands);
2041- if (resType && !isa<VoidType>(resType))
2042- $_state.addTypes(resType);
2043- $_state.addAttribute("side_effect",
2044- SideEffectAttr::get($_builder.getContext(), sideEffect));
2045- }]>,
2031+ }]>
20462032 ];
20472033}
20482034
@@ -2535,6 +2521,146 @@ def ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
25352521 let hasFolder = 1;
25362522}
25372523
2524+ //===----------------------------------------------------------------------===//
2525+ // Bit Manipulation Operations
2526+ //===----------------------------------------------------------------------===//
2527+
2528+ class CIR_BitOpBase<string mnemonic, TypeConstraint operandTy>
2529+ : CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> {
2530+ let arguments = (ins operandTy:$input);
2531+ let results = (outs operandTy:$result);
2532+
2533+ let assemblyFormat = [{
2534+ `(` $input `:` type($input) `)` `:` type($result) attr-dict
2535+ }];
2536+ }
2537+
2538+ class CIR_BitZeroCountOpBase<string mnemonic, TypeConstraint operandTy>
2539+ : CIR_BitOpBase<mnemonic, operandTy> {
2540+ let arguments = (ins operandTy:$input, UnitAttr:$poison_zero);
2541+
2542+ let assemblyFormat = [{
2543+ `(` $input `:` type($input) `)` (`poison_zero` $poison_zero^)?
2544+ `:` type($result) attr-dict
2545+ }];
2546+ }
2547+
2548+ def BitClrsbOp : CIR_BitOpBase<"bit.clrsb", CIR_SIntOfWidths<[32, 64]>> {
2549+ let summary = "Get the number of leading redundant sign bits in the input";
2550+ let description = [{
2551+ Compute the number of leading redundant sign bits in the input integer.
2552+
2553+ The input integer must be a signed integer. The most significant bit of the
2554+ input integer is the sign bit. The `cir.bit.clrsb` operation returns the
2555+ number of consecutive bits following the sign bit that are identical to the
2556+ sign bit.
2557+
2558+ The bit width of the input integer must be either 32 or 64.
2559+
2560+ Examples:
2561+
2562+ ```mlir
2563+ // %0 = 0b1101_1110_1010_1101_1011_1110_1110_1111
2564+ %0 = cir.const #cir.int<3735928559> : !s32i
2565+ // %1 will be 1 because there is 1 bit following the most significant bit
2566+ // that is identical to it.
2567+ %1 = cir.bit.clrsb(%0 : !s32i) : !s32i
2568+
2569+ // %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
2570+ %2 = cir.const #cir.int<1> : !s32i
2571+ // %3 will be 30 because there are 30 consecutive bits following the sign
2572+ // bit that are identical to the sign bit.
2573+ %3 = cir.bit.clrsb(%2 : !s32i) : !s32i
2574+ ```
2575+ }];
2576+ }
2577+
2578+ def BitClzOp : CIR_BitZeroCountOpBase<"bit.clz",
2579+ CIR_UIntOfWidths<[16, 32, 64]>> {
2580+ let summary = "Get the number of leading 0-bits in the input";
2581+ let description = [{
2582+ Compute the number of leading 0-bits in the input.
2583+
2584+ The input integer must be an unsigned integer. The `cir.bit.clz` operation
2585+ returns the number of consecutive 0-bits at the most significant bit
2586+ position in the input.
2587+
2588+ If the `poison_zero` attribute is present, this operation will have
2589+ undefined behavior if the input value is 0.
2590+
2591+ Example:
2592+
2593+ ```mlir
2594+ // %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
2595+ %0 = cir.const #cir.int<8> : !u32i
2596+ // %1 will be 28
2597+ %1 = cir.bit.clz(%0 : !u32i) poison_zero : !u32i
2598+ ```
2599+ }];
2600+ }
2601+
2602+ def BitCtzOp : CIR_BitZeroCountOpBase<"bit.ctz",
2603+ CIR_UIntOfWidths<[16, 32, 64]>> {
2604+ let summary = "Get the number of trailing 0-bits in the input";
2605+ let description = [{
2606+ Compute the number of trailing 0-bits in the input.
2607+
2608+ The input integer must be an unsigned integer. The `cir.bit.ctz` operation
2609+ counts the number of consecutive 0-bits starting from the least significant
2610+ bit.
2611+
2612+ If the `poison_zero` attribute is present, this operation will have
2613+ undefined behavior if the input value is 0.
2614+
2615+ Example:
2616+
2617+ ```mlir
2618+ // %0 = 0b1000
2619+ %0 = cir.const #cir.int<8> : !u32i
2620+ // %1 will be 3
2621+ %1 = cir.bit.ctz(%0 : !u32i) poison_zero : !u32i
2622+ ```
2623+ }];
2624+ }
2625+
2626+ def BitParityOp : CIR_BitOpBase<"bit.parity", CIR_UIntOfWidths<[32, 64]>> {
2627+ let summary = "Get the parity of input";
2628+ let description = [{
2629+ Compute the parity of the input. The parity of an integer is the number of
2630+ 1-bits in it modulo 2.
2631+
2632+ The input must be an unsigned integer.
2633+
2634+ Example:
2635+
2636+ ```mlir
2637+ // %0 = 0x0110_1000
2638+ %0 = cir.const #cir.int<104> : !u32i
2639+ // %1 will be 1 since there are three 1-bits in %0
2640+ %1 = cir.bit.parity(%0 : !u32i) : !u32i
2641+ ```
2642+ }];
2643+ }
2644+
2645+ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
2646+ CIR_UIntOfWidths<[16, 32, 64]>> {
2647+ let summary = "Get the number of 1-bits in input";
2648+ let description = [{
2649+ Compute the number of 1-bits in the input.
2650+
2651+ The input must be an unsigned integer.
2652+
2653+ Example:
2654+
2655+ ```mlir
2656+ // %0 = 0x0110_1000
2657+ %0 = cir.const #cir.int<104> : !u32i
2658+ // %1 will be 3 since there are 3 1-bits in %0
2659+ %1 = cir.bit.popcnt(%0 : !u32i) : !u32i
2660+ ```
2661+ }];
2662+ }
2663+
25382664//===----------------------------------------------------------------------===//
25392665// Assume Operations
25402666//===----------------------------------------------------------------------===//
0 commit comments