@@ -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