LLZK 2.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
SMTBitVectorOps.td
Go to the documentation of this file.
1//===- SMTBitVectorOps.td - SMT bit-vector dialect 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#ifndef MLIR_DIALECT_SMT_IR_SMTBITVECTOROPS_TD
10#define MLIR_DIALECT_SMT_IR_SMTBITVECTOROPS_TD
11
12include "llzk/Dialect/SMT/IR/SMTDialect.td"
13include "llzk/Dialect/SMT/IR/SMTAttributes.td"
14include "llzk/Dialect/SMT/IR/SMTTypes.td"
15include "mlir/IR/EnumAttr.td"
16include "mlir/IR/OpAsmInterface.td"
17include "mlir/Interfaces/InferTypeOpInterface.td"
18include "mlir/Interfaces/SideEffectInterfaces.td"
19
20class SMTBVOp<string mnemonic, list<Trait> traits = []>
21 : Op<SMTDialect, "bv."#mnemonic, traits>;
22
23def BVConstantOp
24 : SMTBVOp<"constant", [Pure, ConstantLike, FirstAttrDerivedResultType,
25 DeclareOpInterfaceMethods<
26 InferTypeOpInterface, ["inferReturnTypes"]>,
27 DeclareOpInterfaceMethods<
28 OpAsmOpInterface, ["getAsmResultNames"]>]> {
29 let summary = "produce a constant bit-vector";
30 let description = [{
31 This operation produces an SSA value equal to the bit-vector constant
32 specified by the 'value' attribute.
33 Refer to the `BitVectorAttr` documentation for more information about
34 the semantics of bit-vector constants, their format, and associated sort.
35 The result type always matches the attribute's type.
36
37 Examples:
38 ```mlir
39 %c92_bv8 = smt.bv.constant #smt.bv<92> : !smt.bv<8>
40 %c5_bv4 = smt.bv.constant #smt.bv<5> : !smt.bv<4>
41 ```
42 }];
43
44 let arguments = (ins BitVectorAttr:$value);
45 let results = (outs BitVectorType:$result);
46
47 let assemblyFormat = "qualified($value) attr-dict";
48
49 let builders = [OpBuilder<(ins "const llvm::APInt &":$value), [{
50 build($_builder, $_state,
51 BitVectorAttr::get($_builder.getContext(), value));
52 }]>,
53 OpBuilder<(ins "uint64_t":$value, "unsigned":$width), [{
54 build($_builder, $_state,
55 BitVectorAttr::get($_builder.getContext(), value, width));
56 }]>,
57 ];
58
59 let hasFolder = true;
60}
61
62class BVArithmeticOrBitwiseOp<string mnemonic, string desc>
63 : SMTBVOp<mnemonic, [Pure, SameOperandsAndResultType]> {
64 let summary = "equivalent to bv"#mnemonic#" in SMT-LIB";
65 let description = "This operation performs "#desc#[{. The semantics are
66 equivalent to the `bv}]#mnemonic#[{` operator defined in the SMT-LIB 2.7
67 standard. More precisely in the [theory of FixedSizeBitVectors](https://smtlib.cs.uiowa.edu/Theories/FixedSizeBitVectors.smt2)
68 and the [QF_BV logic](https://smtlib.cs.uiowa.edu/Logics/QF_BV.smt2)
69 describing closed quantifier-free formulas over the theory of fixed-size
70 bit-vectors.
71 }];
72
73 let results = (outs BitVectorType:$result);
74}
75
76class BinaryBVOp<string mnemonic, string desc>
77 : BVArithmeticOrBitwiseOp<mnemonic, desc> {
78 let arguments = (ins BitVectorType:$lhs, BitVectorType:$rhs);
79 let assemblyFormat = "$lhs `,` $rhs attr-dict `:` qualified(type($result))";
80}
81
82class UnaryBVOp<string mnemonic, string desc>
83 : BVArithmeticOrBitwiseOp<mnemonic, desc> {
84 let arguments = (ins BitVectorType:$input);
85 let assemblyFormat = "$input attr-dict `:` qualified(type($result))";
86}
87
88def BVNotOp : UnaryBVOp<"not", "bitwise negation">;
89def BVNegOp : UnaryBVOp<"neg", "two's complement unary minus">;
90
91def BVAndOp : BinaryBVOp<"and", "bitwise AND">;
92def BVOrOp : BinaryBVOp<"or", "bitwise OR">;
93def BVXOrOp : BinaryBVOp<"xor", "bitwise exclusive OR">;
94
95def BVAddOp : BinaryBVOp<"add", "addition">;
96def BVMulOp : BinaryBVOp<"mul", "multiplication">;
97def BVUDivOp : BinaryBVOp<"udiv", "unsigned division (rounded towards zero)">;
98def BVSDivOp : BinaryBVOp<"sdiv", "two's complement signed division">;
99def BVURemOp : BinaryBVOp<"urem", "unsigned remainder">;
100def BVSRemOp
101 : BinaryBVOp<"srem",
102 "two's complement signed remainder (sign follows dividend)">;
103def BVSModOp
104 : BinaryBVOp<"smod",
105 "two's complement signed remainder (sign follows divisor)">;
106def BVShlOp : BinaryBVOp<"shl", "shift left">;
107def BVLShrOp : BinaryBVOp<"lshr", "logical shift right">;
108def BVAShrOp : BinaryBVOp<"ashr", "arithmetic shift right">;
109
110def PredicateSLT : I64EnumAttrCase<"slt", 0>;
111def PredicateSLE : I64EnumAttrCase<"sle", 1>;
112def PredicateSGT : I64EnumAttrCase<"sgt", 2>;
113def PredicateSGE : I64EnumAttrCase<"sge", 3>;
114def PredicateULT : I64EnumAttrCase<"ult", 4>;
115def PredicateULE : I64EnumAttrCase<"ule", 5>;
116def PredicateUGT : I64EnumAttrCase<"ugt", 6>;
117def PredicateUGE : I64EnumAttrCase<"uge", 7>;
118let cppNamespace = "::llzk::smt" in def BVCmpPredicate
119 : I64EnumAttr<"BVCmpPredicate", "smt bit-vector comparison predicate",
120 [PredicateSLT, PredicateSLE, PredicateSGT, PredicateSGE,
121 PredicateULT, PredicateULE, PredicateUGT, PredicateUGE]>;
122
123def BVCmpOp : SMTBVOp<"cmp", [Pure, SameTypeOperands]> {
124 let summary = "compare bit-vectors interpreted as signed or unsigned";
125 let description = [{
126 This operation compares bit-vector values, interpreting them as signed or
127 unsigned values depending on the predicate. The semantics are equivalent to
128 the `bvslt`, `bvsle`, `bvsgt`, `bvsge`, `bvult`, `bvule`, `bvugt`, or
129 `bvuge` operator defined in the SMT-LIB 2.7 standard depending on the
130 specified predicate. More precisely in the
131 [theory of FixedSizeBitVectors](https://smtlib.cs.uiowa.edu/Theories/FixedSizeBitVectors.smt2)
132 and the [QF_BV logic](https://smtlib.cs.uiowa.edu/Logics/QF_BV.smt2)
133 describing closed quantifier-free formulas over the theory of fixed-size
134 bit-vectors.
135 }];
136
137 let arguments = (ins BVCmpPredicate:$pred, BitVectorType:$lhs,
138 BitVectorType:$rhs);
139 let results = (outs BoolType:$result);
140
141 let assemblyFormat = [{
142 $pred $lhs `,` $rhs attr-dict `:` qualified(type($lhs))
143 }];
144}
145
146def ConcatOp
147 : SMTBVOp<"concat", [Pure,
148 DeclareOpInterfaceMethods<
149 InferTypeOpInterface, ["inferReturnTypes"]>]> {
150 let summary = "bit-vector concatenation";
151 let description = [{
152 This operation concatenates bit-vector values with semantics equivalent to
153 the `concat` operator defined in the SMT-LIB 2.7 standard. More precisely in
154 the [theory of FixedSizeBitVectors](https://smtlib.cs.uiowa.edu/Theories/FixedSizeBitVectors.smt2)
155 and the [QF_BV logic](https://smtlib.cs.uiowa.edu/Logics/QF_BV.smt2)
156 describing closed quantifier-free formulas over the theory of fixed-size
157 bit-vectors.
158
159 Note that the following equivalences hold:
160 * `smt.bv.concat %a, %b : !smt.bv<4>, !smt.bv<4>` is equivalent to
161 `(concat a b)` in SMT-LIB
162 * `(= (concat #xf #x0) #xf0)`
163 }];
164
165 let arguments = (ins BitVectorType:$lhs, BitVectorType:$rhs);
166 let results = (outs BitVectorType:$result);
167
168 let assemblyFormat = "$lhs `,` $rhs attr-dict `:` qualified(type(operands))";
169}
170
171def ExtractOp : SMTBVOp<"extract", [Pure]> {
172 let summary = "bit-vector extraction";
173 let description = [{
174 This operation extracts the range of bits starting at the 'lowBit' index
175 (inclusive) up to the 'lowBit' + result-width index (exclusive). The
176 semantics are equivalent to the `extract` operator defined in the SMT-LIB
177 2.7 standard. More precisely in the
178 [theory of FixedSizeBitVectors](https://smtlib.cs.uiowa.edu/Theories/FixedSizeBitVectors.smt2)
179 and the [QF_BV logic](https://smtlib.cs.uiowa.edu/Logics/QF_BV.smt2)
180 describing closed quantifier-free formulas over the theory of fixed-size
181 bit-vectors.
182
183 Note that `smt.bv.extract %bv from 2 : (!smt.bv<32>) -> !smt.bv<16>` is
184 equivalent to `((_ extract 17 2) bv)`, i.e., the SMT-LIB operator takes the
185 low and high indices where both are inclusive. The following equivalence
186 holds: `(= ((_ extract 3 0) #x0f) #xf)`
187 }];
188
189 let arguments = (ins I32Attr:$lowBit, BitVectorType:$input);
190 let results = (outs BitVectorType:$result);
191
192 let assemblyFormat = [{
193 $input `from` $lowBit attr-dict `:` functional-type($input, $result)
194 }];
195
196 let hasVerifier = true;
197}
198
199def RepeatOp : SMTBVOp<"repeat", [Pure]> {
200 let summary = "repeated bit-vector concatenation of one value";
201 let description = [{
202 This operation is a shorthand for repeated concatenation of the same
203 bit-vector value, i.e.,
204 ```mlir
205 smt.bv.repeat 5 times %a : !smt.bv<4>
206 // is the same as
207 %0 = smt.bv.repeat 4 times %a : !smt.bv<4>
208 smt.bv.concat %a, %0 : !smt.bv<4>, !smt.bv<16>
209 // or also
210 %0 = smt.bv.repeat 4 times %a : !smt.bv<4>
211 smt.bv.concat %0, %a : !smt.bv<16>, !smt.bv<4>
212 ```
213
214 The semantics are equivalent to the `repeat` operator defined in the SMT-LIB
215 2.7 standard. More precisely in the
216 [theory of FixedSizeBitVectors](https://smtlib.cs.uiowa.edu/Theories/FixedSizeBitVectors.smt2)
217 and the [QF_BV logic](https://smtlib.cs.uiowa.edu/Logics/QF_BV.smt2)
218 describing closed quantifier-free formulas over the theory of fixed-size
219 bit-vectors.
220 }];
221
222 let arguments = (ins BitVectorType:$input);
223 let results = (outs BitVectorType:$result);
224
225 let hasCustomAssemblyFormat = true;
226 let hasVerifier = true;
227
228 let builders = [OpBuilder<(ins "unsigned":$count, "mlir::Value":$input)>, ];
229
230 let extraClassDeclaration = [{
231 /// Get the number of times the input operand is repeated.
232 unsigned getCount();
233 }];
234}
235
236def BV2IntOp : SMTOp<"bv2int", [Pure]> {
237 let summary = "Convert an SMT bit-vector to an SMT integer.";
238 let description = [{
239 Create an integer from the bit-vector argument `input`. If `is_signed` is
240 present, the bit-vector is treated as two's complement signed. Otherwise,
241 it is treated as an unsigned integer in the range [0..2^N-1], where N is
242 the number of bits in `input`.
243 }];
244 let arguments = (ins BitVectorType:$input, UnitAttr:$is_signed);
245 let results = (outs IntType:$result);
246 let assemblyFormat = [{$input (`signed` $is_signed^)? attr-dict `:`
247 qualified(type($input))}];
248}
249
250#endif // MLIR_DIALECT_SMT_IR_SMTBITVECTOROPS_TD