LLZK 2.1.1
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
SMTOps.cpp
Go to the documentation of this file.
1//===- SMTOps.cpp ---------------------------------------------------------===//
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
10
11#include <mlir/IR/Builders.h>
12#include <mlir/IR/OpImplementation.h>
13
14#include <llvm/ADT/APSInt.h>
15
16using namespace mlir;
17using namespace llzk::smt;
18
19//===----------------------------------------------------------------------===//
20// BVConstantOp
21//===----------------------------------------------------------------------===//
22
24 MLIRContext * /*context*/, std::optional<Location> /*location*/, ValueRange /*operands*/,
25 DictionaryAttr /*attributes*/, OpaqueProperties properties, RegionRange /*regions*/,
26 SmallVectorImpl<Type> &inferredReturnTypes
27) {
28 inferredReturnTypes.push_back(properties.as<Properties *>()->getValue().getType());
29 return success();
30}
31
32void BVConstantOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
33 SmallVector<char, 128> specialNameBuffer;
34 llvm::raw_svector_ostream specialName(specialNameBuffer);
35 specialName << "c" << getValue().getValue() << "_bv" << getValue().getValue().getBitWidth();
36 setNameFn(getResult(), specialName.str());
37}
38
39OpFoldResult BVConstantOp::fold(FoldAdaptor adaptor) {
40 assert(adaptor.getOperands().empty() && "constant has no operands");
41 return getValueAttr();
42}
43
44//===----------------------------------------------------------------------===//
45// DeclareFunOp
46//===----------------------------------------------------------------------===//
47
48void DeclareFunOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
49 setNameFn(getResult(), getNamePrefix().has_value() ? *getNamePrefix() : "");
50}
51
52//===----------------------------------------------------------------------===//
53// SolverOp
54//===----------------------------------------------------------------------===//
55
56LogicalResult SolverOp::verifyRegions() {
57 if (getBody()->getTerminator()->getOperands().getTypes() != getResultTypes()) {
58 return emitOpError() << "types of yielded values must match return values";
59 }
60 if (getBody()->getArgumentTypes() != getInputs().getTypes()) {
61 return emitOpError() << "block argument types must match the types of the 'inputs'";
62 }
63
64 return success();
65}
66
67//===----------------------------------------------------------------------===//
68// CheckOp
69//===----------------------------------------------------------------------===//
70
71LogicalResult CheckOp::verifyRegions() {
72 if (getSatRegion().front().getTerminator()->getOperands().getTypes() != getResultTypes()) {
73 return emitOpError() << "types of yielded values in 'sat' region must "
74 "match return values";
75 }
76 if (getUnknownRegion().front().getTerminator()->getOperands().getTypes() != getResultTypes()) {
77 return emitOpError() << "types of yielded values in 'unknown' region must "
78 "match return values";
79 }
80 if (getUnsatRegion().front().getTerminator()->getOperands().getTypes() != getResultTypes()) {
81 return emitOpError() << "types of yielded values in 'unsat' region must "
82 "match return values";
83 }
84
85 return success();
86}
87
88//===----------------------------------------------------------------------===//
89// EqOp
90//===----------------------------------------------------------------------===//
91
92static LogicalResult
93parseSameOperandTypeVariadicToBoolOp(OpAsmParser &parser, OperationState &result) {
94 SmallVector<OpAsmParser::UnresolvedOperand, 4> inputs;
95 SMLoc loc = parser.getCurrentLocation();
96 Type type;
97
98 if (parser.parseOperandList(inputs) || parser.parseOptionalAttrDict(result.attributes) ||
99 parser.parseColon() || parser.parseType(type)) {
100 return failure();
101 }
102
103 result.addTypes(BoolType::get(parser.getContext()));
104 if (parser.resolveOperands(
105 inputs, SmallVector<Type>(inputs.size(), type), loc, result.operands
106 )) {
107 return failure();
108 }
109
110 return success();
111}
112
113ParseResult EqOp::parse(OpAsmParser &parser, OperationState &result) {
114 return parseSameOperandTypeVariadicToBoolOp(parser, result);
115}
116
117void EqOp::print(OpAsmPrinter &printer) {
118 printer << ' ' << getInputs();
119 printer.printOptionalAttrDict(getOperation()->getAttrs());
120 printer << " : " << getInputs().front().getType();
121}
122
123LogicalResult EqOp::verify() {
124 if (getInputs().size() < 2) {
125 return emitOpError() << "'inputs' must have at least size 2, but got " << getInputs().size();
126 }
127
128 return success();
129}
130
131//===----------------------------------------------------------------------===//
132// DistinctOp
133//===----------------------------------------------------------------------===//
134
135ParseResult DistinctOp::parse(OpAsmParser &parser, OperationState &result) {
136 return parseSameOperandTypeVariadicToBoolOp(parser, result);
137}
138
139void DistinctOp::print(OpAsmPrinter &printer) {
140 printer << ' ' << getInputs();
141 printer.printOptionalAttrDict(getOperation()->getAttrs());
142 printer << " : " << getInputs().front().getType();
143}
144
145LogicalResult DistinctOp::verify() {
146 if (getInputs().size() < 2) {
147 return emitOpError() << "'inputs' must have at least size 2, but got " << getInputs().size();
148 }
149
150 return success();
151}
152
153//===----------------------------------------------------------------------===//
154// ExtractOp
155//===----------------------------------------------------------------------===//
156
157LogicalResult ExtractOp::verify() {
158 unsigned rangeWidth = getType().getWidth();
159 unsigned inputWidth = cast<BitVectorType>(getInput().getType()).getWidth();
160 if (getLowBit() + rangeWidth > inputWidth) {
161 return emitOpError(
162 "range to be extracted is too big, expected range "
163 "starting at index "
164 )
165 << getLowBit() << " of length " << rangeWidth << " requires input width of at least "
166 << (getLowBit() + rangeWidth) << ", but the input width is only " << inputWidth;
167 }
168 return success();
169}
170
171//===----------------------------------------------------------------------===//
172// ConcatOp
173//===----------------------------------------------------------------------===//
174
176 MLIRContext *context, std::optional<Location> /*location*/, ValueRange operands,
177 DictionaryAttr /*attributes*/, OpaqueProperties /*properties*/, RegionRange /*regions*/,
178 SmallVectorImpl<Type> &inferredReturnTypes
179) {
180 inferredReturnTypes.push_back(
182 context, cast<BitVectorType>(operands[0].getType()).getWidth() +
183 cast<BitVectorType>(operands[1].getType()).getWidth()
184 )
185 );
186 return success();
187}
188
189//===----------------------------------------------------------------------===//
190// RepeatOp
191//===----------------------------------------------------------------------===//
192
193LogicalResult RepeatOp::verify() {
194 unsigned inputWidth = cast<BitVectorType>(getInput().getType()).getWidth();
195 unsigned resultWidth = getType().getWidth();
196 if (resultWidth % inputWidth != 0) {
197 return emitOpError() << "result bit-vector width must be a multiple of the "
198 "input bit-vector width";
199 }
200
201 return success();
202}
203
205 unsigned inputWidth = cast<BitVectorType>(getInput().getType()).getWidth();
206 unsigned resultWidth = getType().getWidth();
207 return resultWidth / inputWidth;
208}
209
210void RepeatOp::build(OpBuilder &builder, OperationState &state, unsigned count, Value input) {
211 int64_t inputWidth = cast<BitVectorType>(input.getType()).getWidth();
212 Type resultTy = BitVectorType::get(builder.getContext(), inputWidth * count);
213 build(builder, state, resultTy, input);
214}
215
216ParseResult RepeatOp::parse(OpAsmParser &parser, OperationState &result) {
217 OpAsmParser::UnresolvedOperand input;
218 Type inputType;
219 llvm::SMLoc countLoc = parser.getCurrentLocation();
220
221 APInt count;
222 if (parser.parseInteger(count) || parser.parseKeyword("times")) {
223 return failure();
224 }
225
226 if (count.isNonPositive()) {
227 return parser.emitError(countLoc) << "integer must be positive";
228 }
229
230 llvm::SMLoc inputLoc = parser.getCurrentLocation();
231 if (parser.parseOperand(input) || parser.parseOptionalAttrDict(result.attributes) ||
232 parser.parseColon() || parser.parseType(inputType)) {
233 return failure();
234 }
235
236 if (parser.resolveOperand(input, inputType, result.operands)) {
237 return failure();
238 }
239
240 auto bvInputTy = dyn_cast<BitVectorType>(inputType);
241 if (!bvInputTy) {
242 return parser.emitError(inputLoc) << "input must have bit-vector type";
243 }
244
245 // Make sure no assertions can trigger and no silent overflows can happen
246 // Bit-width is stored as 'int64_t' parameter in 'BitVectorType'
247 const unsigned maxBw = 63;
248 if (count.getActiveBits() > maxBw) {
249 return parser.emitError(countLoc) << "integer must fit into " << maxBw << " bits";
250 }
251
252 // Store multiplication in an APInt twice the size to not have any overflow
253 // and check if it can be truncated to 'maxBw' bits without cutting of
254 // important bits.
255 APInt resultBw = bvInputTy.getWidth() * count.zext(2 * maxBw);
256 if (resultBw.getActiveBits() > maxBw) {
257 return parser.emitError(countLoc)
258 << "result bit-width (provided integer times bit-width of the input "
259 "type) must fit into "
260 << maxBw << " bits";
261 }
262
263 uint64_t val = resultBw.getZExtValue();
264 assert(val <= std::numeric_limits<int64_t>::max() && "value too large");
265 Type resultTy = BitVectorType::get(parser.getContext(), static_cast<int64_t>(val));
266 result.addTypes(resultTy);
267 return success();
268}
269
270void RepeatOp::print(OpAsmPrinter &printer) {
271 printer << ' ' << getCount() << " times " << getInput();
272 printer.printOptionalAttrDict((*this)->getAttrs());
273 printer << " : " << getInput().getType();
274}
275
276//===----------------------------------------------------------------------===//
277// BoolConstantOp
278//===----------------------------------------------------------------------===//
279
280void BoolConstantOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
281 setNameFn(getResult(), getValue() ? "true" : "false");
282}
283
284OpFoldResult BoolConstantOp::fold(FoldAdaptor adaptor) {
285 assert(adaptor.getOperands().empty() && "constant has no operands");
286 return getValueAttr();
287}
288
289//===----------------------------------------------------------------------===//
290// IntConstantOp
291//===----------------------------------------------------------------------===//
292
293void IntConstantOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
294 SmallVector<char, 32> specialNameBuffer;
295 llvm::raw_svector_ostream specialName(specialNameBuffer);
296 specialName << "c" << getValue();
297 setNameFn(getResult(), specialName.str());
298}
299
300OpFoldResult IntConstantOp::fold(FoldAdaptor adaptor) {
301 assert(adaptor.getOperands().empty() && "constant has no operands");
302 return getValueAttr();
303}
304
305void IntConstantOp::print(OpAsmPrinter &p) {
306 p << ' ' << getValue();
307 p.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/ {"value"});
308}
309
310ParseResult IntConstantOp::parse(OpAsmParser &parser, OperationState &result) {
311 APInt value;
312 if (parser.parseInteger(value)) {
313 return failure();
314 }
315
316 result.getOrAddProperties<Properties>().setValue(
317 IntegerAttr::get(parser.getContext(), APSInt(value))
318 );
319
320 if (parser.parseOptionalAttrDict(result.attributes)) {
321 return failure();
322 }
323
324 result.addTypes(smt::IntType::get(parser.getContext()));
325 return success();
326}
327
328//===----------------------------------------------------------------------===//
329// ForallOp
330//===----------------------------------------------------------------------===//
331
332template <typename QuantifierOp> static LogicalResult verifyQuantifierRegions(QuantifierOp op) {
333 if (op.getBoundVarNames() && op.getBody().getNumArguments() != op.getBoundVarNames()->size()) {
334 return op.emitOpError("number of bound variable names must match number of block arguments");
335 }
336 if (!llvm::all_of(op.getBody().getArgumentTypes(), isAnyNonFuncSMTValueType)) {
337 return op.emitOpError() << "bound variables must by any non-function SMT value";
338 }
339
340 if (op.getBody().front().getTerminator()->getNumOperands() != 1) {
341 return op.emitOpError("must have exactly one yielded value");
342 }
343 if (!isa<BoolType>(op.getBody().front().getTerminator()->getOperand(0).getType())) {
344 return op.emitOpError("yielded value must be of '!smt.bool' type");
345 }
346
347 for (auto regionWithIndex : llvm::enumerate(op.getPatterns())) {
348 unsigned i = regionWithIndex.index();
349 Region &region = regionWithIndex.value();
350
351 if (op.getBody().getArgumentTypes() != region.getArgumentTypes()) {
352 return op.emitOpError() << "block argument number and types of the 'body' "
353 "and 'patterns' region #"
354 << i << " must match";
355 }
356 if (region.front().getTerminator()->getNumOperands() < 1) {
357 return op.emitOpError() << "'patterns' region #" << i
358 << " must have at least one yielded value";
359 }
360
361 // All operations in the 'patterns' region must be SMT operations.
362 auto result = region.walk([&](Operation *childOp) {
363 if (!isa<SMTDialect>(childOp->getDialect())) {
364 auto diag = op.emitOpError()
365 << "the 'patterns' region #" << i << " may only contain SMT dialect operations";
366 diag.attachNote(childOp->getLoc()) << "first non-SMT operation here";
367 return WalkResult::interrupt();
368 }
369
370 // There may be no quantifier (or other variable binding) operations in
371 // the 'patterns' region.
372 if (isa<ForallOp, ExistsOp>(childOp)) {
373 auto diag = op.emitOpError() << "the 'patterns' region #" << i
374 << " must not contain "
375 "any variable binding operations";
376 diag.attachNote(childOp->getLoc()) << "first violating operation here";
377 return WalkResult::interrupt();
378 }
379
380 return WalkResult::advance();
381 });
382 if (result.wasInterrupted()) {
383 return failure();
384 }
385 }
386
387 return success();
388}
389
390template <typename Properties>
391static void buildQuantifier(
392 OpBuilder &odsBuilder, OperationState &odsState, TypeRange boundVarTypes,
393 function_ref<Value(OpBuilder &, Location, ValueRange)> bodyBuilder,
394 std::optional<ArrayRef<StringRef>> boundVarNames,
395 function_ref<ValueRange(OpBuilder &, Location, ValueRange)> patternBuilder, uint32_t weight,
396 bool noPattern
397) {
398 odsState.addTypes(BoolType::get(odsBuilder.getContext()));
399 if (weight != 0) {
400 odsState.getOrAddProperties<Properties>().weight =
401 odsBuilder.getIntegerAttr(odsBuilder.getIntegerType(32), weight);
402 }
403 if (noPattern) {
404 odsState.getOrAddProperties<Properties>().noPattern = odsBuilder.getUnitAttr();
405 }
406 if (boundVarNames.has_value()) {
407 SmallVector<Attribute> boundVarNamesList;
408 for (StringRef str : *boundVarNames) {
409 boundVarNamesList.emplace_back(odsBuilder.getStringAttr(str));
410 }
411 odsState.getOrAddProperties<Properties>().boundVarNames =
412 odsBuilder.getArrayAttr(boundVarNamesList);
413 }
414 {
415 OpBuilder::InsertionGuard guard(odsBuilder);
416 Region *region = odsState.addRegion();
417 Block *block = odsBuilder.createBlock(region);
418 block->addArguments(
419 boundVarTypes, SmallVector<Location>(boundVarTypes.size(), odsState.location)
420 );
421 Value returnVal = bodyBuilder(odsBuilder, odsState.location, block->getArguments());
422 odsBuilder.create<llzk::smt::YieldOp>(odsState.location, returnVal);
423 }
424 if (patternBuilder) {
425 Region *region = odsState.addRegion();
426 OpBuilder::InsertionGuard guard(odsBuilder);
427 Block *block = odsBuilder.createBlock(region);
428 block->addArguments(
429 boundVarTypes, SmallVector<Location>(boundVarTypes.size(), odsState.location)
430 );
431 ValueRange returnVals = patternBuilder(odsBuilder, odsState.location, block->getArguments());
432 odsBuilder.create<llzk::smt::YieldOp>(odsState.location, returnVals);
433 }
434}
435
436LogicalResult ForallOp::verify() {
437 if (!getPatterns().empty() && getNoPattern()) {
438 return emitOpError() << "patterns and the no_pattern attribute must not be "
439 "specified at the same time";
440 }
441
442 return success();
443}
444
445LogicalResult ForallOp::verifyRegions() { return verifyQuantifierRegions(*this); }
446
448 OpBuilder &odsBuilder, OperationState &odsState, TypeRange boundVarTypes,
449 function_ref<Value(OpBuilder &, Location, ValueRange)> bodyBuilder,
450 std::optional<ArrayRef<StringRef>> boundVarNames,
451 function_ref<ValueRange(OpBuilder &, Location, ValueRange)> patternBuilder, uint32_t weight,
452 bool noPattern
453) {
454 buildQuantifier<Properties>(
455 odsBuilder, odsState, boundVarTypes, bodyBuilder, boundVarNames, patternBuilder, weight,
456 noPattern
457 );
458}
459
460//===----------------------------------------------------------------------===//
461// ExistsOp
462//===----------------------------------------------------------------------===//
463
464LogicalResult ExistsOp::verify() {
465 if (!getPatterns().empty() && getNoPattern()) {
466 return emitOpError() << "patterns and the no_pattern attribute must not be "
467 "specified at the same time";
468 }
469
470 return success();
471}
472
473LogicalResult ExistsOp::verifyRegions() { return verifyQuantifierRegions(*this); }
474
476 OpBuilder &odsBuilder, OperationState &odsState, TypeRange boundVarTypes,
477 function_ref<Value(OpBuilder &, Location, ValueRange)> bodyBuilder,
478 std::optional<ArrayRef<StringRef>> boundVarNames,
479 function_ref<ValueRange(OpBuilder &, Location, ValueRange)> patternBuilder, uint32_t weight,
480 bool noPattern
481) {
482 buildQuantifier<Properties>(
483 odsBuilder, odsState, boundVarTypes, bodyBuilder, boundVarNames, patternBuilder, weight,
484 noPattern
485 );
486}
487
488#define GET_OP_CLASSES
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:32
::llzk::smt::BitVectorAttr getValue()
Definition SMT.cpp.inc:2647
::llzk::smt::BitVectorAttr getValueAttr()
Definition SMT.h.inc:2208
::mlir::OpFoldResult fold(FoldAdaptor adaptor)
Definition SMTOps.cpp:39
::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location > location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type > &inferredReturnTypes)
Definition SMTOps.cpp:23
FoldAdaptor::Properties Properties
Definition SMT.h.inc:2157
GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute > > FoldAdaptor
Definition SMT.h.inc:2156
::mlir::TypedValue<::llzk::smt::BitVectorType > getResult()
Definition SMT.h.inc:2195
static BitVectorType get(::mlir::MLIRContext *context, int64_t width)
::mlir::TypedValue<::llzk::smt::BoolType > getResult()
Definition SMT.h.inc:4197
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:280
GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute > > FoldAdaptor
Definition SMT.h.inc:4158
::mlir::BoolAttr getValueAttr()
Definition SMT.h.inc:4210
::mlir::OpFoldResult fold(FoldAdaptor adaptor)
Definition SMTOps.cpp:284
::mlir::Region & getUnsatRegion()
Definition SMT.h.inc:4385
::mlir::Region & getUnknownRegion()
Definition SMT.h.inc:4381
::mlir::Region & getSatRegion()
Definition SMT.h.inc:4377
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:71
::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location > location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type > &inferredReturnTypes)
Definition SMTOps.cpp:175
::mlir::TypedValue<::mlir::Type > getResult()
Definition SMT.h.inc:4702
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:48
::std::optional< ::llvm::StringRef > getNamePrefix()
Definition SMT.cpp.inc:5512
::mlir::Operation::operand_range getInputs()
Definition SMT.h.inc:4853
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:139
::llvm::LogicalResult verify()
Definition SMTOps.cpp:145
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:135
::mlir::Operation::operand_range getInputs()
Definition SMT.h.inc:4982
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:117
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:113
::llvm::LogicalResult verify()
Definition SMTOps.cpp:123
::llvm::LogicalResult verify()
Definition SMTOps.cpp:464
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:473
::mlir::MutableArrayRef<::mlir::Region > getPatterns()
Definition SMT.h.inc:5228
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, mlir::TypeRange boundVarTypes, llvm::function_ref< mlir::Value(mlir::OpBuilder &, mlir::Location, mlir::ValueRange)> bodyBuilder, std::optional< llvm::ArrayRef< mlir::StringRef > > boundVarNames=std::nullopt, llvm::function_ref< mlir::ValueRange(mlir::OpBuilder &, mlir::Location, mlir::ValueRange)> patternBuilder={}, uint32_t weight=0, bool noPattern=false)
Definition SMTOps.cpp:475
::mlir::TypedValue<::llzk::smt::BitVectorType > getInput()
Definition SMT.h.inc:5452
::llvm::LogicalResult verify()
Definition SMTOps.cpp:157
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:445
::llvm::LogicalResult verify()
Definition SMTOps.cpp:436
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, mlir::TypeRange boundVarTypes, llvm::function_ref< mlir::Value(mlir::OpBuilder &, mlir::Location, mlir::ValueRange)> bodyBuilder, std::optional< llvm::ArrayRef< mlir::StringRef > > boundVarNames=std::nullopt, llvm::function_ref< mlir::ValueRange(mlir::OpBuilder &, mlir::Location, mlir::ValueRange)> patternBuilder={}, uint32_t weight=0, bool noPattern=false)
Definition SMTOps.cpp:447
::mlir::MutableArrayRef<::mlir::Region > getPatterns()
Definition SMT.h.inc:5734
::mlir::APInt getValue()
Definition SMT.cpp.inc:8077
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:305
GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute > > FoldAdaptor
Definition SMT.h.inc:6709
::mlir::OpFoldResult fold(FoldAdaptor adaptor)
Definition SMTOps.cpp:300
::mlir::TypedValue<::llzk::smt::IntType > getResult()
Definition SMT.h.inc:6748
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:293
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:310
FoldAdaptor::Properties Properties
Definition SMT.h.inc:6710
::mlir::IntegerAttr getValueAttr()
Definition SMT.h.inc:6761
::mlir::TypedValue<::llzk::smt::BitVectorType > getInput()
Definition SMT.h.inc:8445
::llvm::LogicalResult verify()
Definition SMTOps.cpp:193
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, unsigned count, mlir::Value input)
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:270
unsigned getCount()
Get the number of times the input operand is repeated.
Definition SMTOps.cpp:204
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:216
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:56
::mlir::Operation::operand_range getInputs()
Definition SMT.h.inc:8900
bool isAnyNonFuncSMTValueType(mlir::Type type)
Returns whether the given type is an SMT value type (excluding functions).