LLZK 3.0.0
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 -----------------------------------------------*- C++ -*-===//
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#include <llvm/ADT/StringExtras.h>
16#include <llvm/ADT/TypeSwitch.h>
17
18using namespace mlir;
19using namespace llzk::smt;
20
21static bool isValidSetInfoValue(Attribute attr) {
22 return TypeSwitch<Attribute, bool>(attr)
23 .Case<BoolAttr, IntegerAttr, StringAttr, KeywordAttr, SymbolAttr>([](auto) { return true; })
24 .Case<ArrayAttr>([](ArrayAttr arrayAttr) {
25 return llvm::all_of(arrayAttr, [](Attribute element) { return isValidSetInfoValue(element); });
26 }).Default([](Attribute) { return false; });
27}
28
29static void printSetInfoValue(AsmPrinter &printer, Attribute value) {
30 TypeSwitch<Attribute>(value)
31 .Case<KeywordAttr>([&printer](auto keywordAttr) { printer << keywordAttr.getValue(); })
32 .Case<SymbolAttr>([&printer](auto symbolAttr) { printer << symbolAttr.getValue(); })
33 .Case<StringAttr, BoolAttr>([&printer](auto attr) { printer.printAttribute(attr); })
34 .Case<IntegerAttr>([&printer](auto intAttr) {
35 SmallString<32> valueText;
36 intAttr.getValue().toStringSigned(valueText);
37 printer << valueText;
38 }).Case<ArrayAttr>([&printer](ArrayAttr arrayAttr) {
39 printer << '(';
40 llvm::interleave(arrayAttr, [&printer](Attribute element) {
41 printSetInfoValue(printer, element);
42 }, [&printer] { printer << ' '; });
43 printer << ')';
44 });
45}
46
47static ParseResult parseSetInfoValue(OpAsmParser &parser, Attribute &value) {
48 Builder builder(parser.getContext());
49
50 if (succeeded(parser.parseOptionalLParen())) {
51 SmallVector<Attribute> elements;
52 while (failed(parser.parseOptionalRParen())) {
53 Attribute element;
54 if (parseSetInfoValue(parser, element)) {
55 return failure();
56 }
57 elements.push_back(element);
58 }
59 value = builder.getArrayAttr(elements);
60 return success();
61 }
62
63 if (succeeded(parser.parseOptionalColon())) {
64 StringRef keyword;
65 if (parser.parseKeyword(&keyword)) {
66 return failure();
67 }
68 value = KeywordAttr::get(parser.getContext(), (":" + keyword).str());
69 return success();
70 }
71
72 {
73 APInt numeral;
74 OptionalParseResult parseResult = parser.parseOptionalInteger(numeral);
75 if (!parseResult.has_value()) {
76 // no numeral
77 } else {
78 if (failed(*parseResult)) {
79 return failure();
80 }
81 auto intType = IntegerType::get(parser.getContext(), numeral.getBitWidth());
82 value = IntegerAttr::get(intType, numeral);
83 return success();
84 }
85 }
86
87 {
88 StringAttr strAttr;
89 OptionalParseResult parseResult = parser.parseOptionalAttribute(strAttr, Type());
90 if (!parseResult.has_value()) {
91 // no string attribute
92 } else {
93 if (failed(*parseResult)) {
94 return failure();
95 }
96 value = strAttr;
97 return success();
98 }
99 }
100
101 StringRef symbolOrBool;
102 if (succeeded(parser.parseOptionalKeyword(&symbolOrBool))) {
103 if (symbolOrBool == "true" || symbolOrBool == "false") {
104 value = builder.getBoolAttr(symbolOrBool == "true");
105 } else {
106 value = SymbolAttr::get(parser.getContext(), symbolOrBool);
107 }
108 return success();
109 }
110
111 parser.emitError(parser.getCurrentLocation()) << "expected SMT-LIB set-info value";
112 return failure();
113}
114
115//===----------------------------------------------------------------------===//
116// BVConstantOp
117//===----------------------------------------------------------------------===//
118
120 MLIRContext * /*context*/, std::optional<Location> /*location*/, ValueRange /*operands*/,
121 DictionaryAttr /*attributes*/, OpaqueProperties properties, RegionRange /*regions*/,
122 SmallVectorImpl<Type> &inferredReturnTypes
123) {
124 inferredReturnTypes.push_back(properties.as<Properties *>()->getValue().getType());
125 return success();
126}
127
128void BVConstantOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
129 SmallVector<char, 128> specialNameBuffer;
130 llvm::raw_svector_ostream specialName(specialNameBuffer);
131 specialName << "c" << getValue().getValue() << "_bv" << getValue().getValue().getBitWidth();
132 setNameFn(getResult(), specialName.str());
133}
134
135OpFoldResult BVConstantOp::fold(FoldAdaptor adaptor) {
136 assert(adaptor.getOperands().empty() && "constant has no operands");
137 return getValueAttr();
138}
139
140//===----------------------------------------------------------------------===//
141// DeclareFunOp
142//===----------------------------------------------------------------------===//
143
144void DeclareFunOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
145 setNameFn(getResult(), getNamePrefix().has_value() ? *getNamePrefix() : "");
146}
147
148//===----------------------------------------------------------------------===//
149// SolverOp
150//===----------------------------------------------------------------------===//
151
152LogicalResult SolverOp::verifyRegions() {
153 if (getBody()->getTerminator()->getOperands().getTypes() != getResultTypes()) {
154 return emitOpError() << "types of yielded values must match return values";
155 }
156 if (getBody()->getArgumentTypes() != getInputs().getTypes()) {
157 return emitOpError() << "block argument types must match the types of the 'inputs'";
158 }
159
160 return success();
161}
162
163//===----------------------------------------------------------------------===//
164// SetInfoOp
165//===----------------------------------------------------------------------===//
166
167ParseResult SetInfoOp::parse(OpAsmParser &parser, OperationState &result) {
168 SMLoc loc = parser.getCurrentLocation();
169 StringAttr keyText;
170 Attribute value;
171
172 if (parser.parseAttribute(keyText) || parseSetInfoValue(parser, value) ||
173 parser.parseOptionalAttrDict(result.attributes)) {
174 return failure();
175 }
176
177 auto keyAttr = KeywordAttr::getChecked([&parser, loc]() {
178 return parser.emitError(loc);
179 }, parser.getContext(), keyText.getValue());
180 if (!keyAttr) {
181 return failure();
182 }
183
184 result.addAttribute("key", keyAttr);
185 result.addAttribute("value", value);
186 result.location = parser.getEncodedSourceLoc(loc);
187 return success();
188}
189
190void SetInfoOp::print(OpAsmPrinter &printer) {
191 printer << ' ';
192 printer.printAttribute(StringAttr::get(getContext(), getKey().getValue()));
193 printer << ' ';
194 printSetInfoValue(printer, getValueAttr());
195 printer.printOptionalAttrDict(getOperation()->getAttrs(), {"key", "value"});
196}
197
198LogicalResult SetInfoOp::verify() {
199 if (!isValidSetInfoValue(getValueAttr())) {
200 return emitOpError(
201 "requires an SMT-LIB set-info value built from strings, booleans, "
202 "integers, SMT keywords, SMT symbols, or nested lists"
203 );
204 }
205 return success();
206}
207
208//===----------------------------------------------------------------------===//
209// CheckOp
210//===----------------------------------------------------------------------===//
211
212LogicalResult CheckOp::verifyRegions() {
213 if (getSatRegion().front().getTerminator()->getOperands().getTypes() != getResultTypes()) {
214 return emitOpError() << "types of yielded values in 'sat' region must "
215 "match return values";
216 }
217 if (getUnknownRegion().front().getTerminator()->getOperands().getTypes() != getResultTypes()) {
218 return emitOpError() << "types of yielded values in 'unknown' region must "
219 "match return values";
220 }
221 if (getUnsatRegion().front().getTerminator()->getOperands().getTypes() != getResultTypes()) {
222 return emitOpError() << "types of yielded values in 'unsat' region must "
223 "match return values";
224 }
225
226 return success();
227}
228
229//===----------------------------------------------------------------------===//
230// EqOp
231//===----------------------------------------------------------------------===//
232
233static LogicalResult
234parseSameOperandTypeVariadicToBoolOp(OpAsmParser &parser, OperationState &result) {
235 SmallVector<OpAsmParser::UnresolvedOperand, 4> inputs;
236 SMLoc loc = parser.getCurrentLocation();
237 Type type;
238
239 if (parser.parseOperandList(inputs) || parser.parseOptionalAttrDict(result.attributes) ||
240 parser.parseColon() || parser.parseType(type)) {
241 return failure();
242 }
243
244 result.addTypes(BoolType::get(parser.getContext()));
245 if (parser.resolveOperands(
246 inputs, SmallVector<Type>(inputs.size(), type), loc, result.operands
247 )) {
248 return failure();
249 }
250
251 return success();
252}
253
254ParseResult EqOp::parse(OpAsmParser &parser, OperationState &result) {
255 return parseSameOperandTypeVariadicToBoolOp(parser, result);
256}
257
258void EqOp::print(OpAsmPrinter &printer) {
259 printer << ' ' << getInputs();
260 printer.printOptionalAttrDict(getOperation()->getAttrs());
261 printer << " : " << getInputs().front().getType();
262}
263
264LogicalResult EqOp::verify() {
265 if (getInputs().size() < 2) {
266 return emitOpError() << "'inputs' must have at least size 2, but got " << getInputs().size();
267 }
268
269 return success();
270}
271
272//===----------------------------------------------------------------------===//
273// DistinctOp
274//===----------------------------------------------------------------------===//
275
276ParseResult DistinctOp::parse(OpAsmParser &parser, OperationState &result) {
277 return parseSameOperandTypeVariadicToBoolOp(parser, result);
278}
279
280void DistinctOp::print(OpAsmPrinter &printer) {
281 printer << ' ' << getInputs();
282 printer.printOptionalAttrDict(getOperation()->getAttrs());
283 printer << " : " << getInputs().front().getType();
284}
285
286LogicalResult DistinctOp::verify() {
287 if (getInputs().size() < 2) {
288 return emitOpError() << "'inputs' must have at least size 2, but got " << getInputs().size();
289 }
290
291 return success();
292}
293
294//===----------------------------------------------------------------------===//
295// ExtractOp
296//===----------------------------------------------------------------------===//
297
298LogicalResult ExtractOp::verify() {
299 unsigned rangeWidth = getType().getWidth();
300 unsigned inputWidth = cast<BitVectorType>(getInput().getType()).getWidth();
301 if (getLowBit() + rangeWidth > inputWidth) {
302 return emitOpError(
303 "range to be extracted is too big, expected range "
304 "starting at index "
305 )
306 << getLowBit() << " of length " << rangeWidth << " requires input width of at least "
307 << (getLowBit() + rangeWidth) << ", but the input width is only " << inputWidth;
308 }
309 return success();
310}
311
312//===----------------------------------------------------------------------===//
313// ConcatOp
314//===----------------------------------------------------------------------===//
315
317 MLIRContext *context, std::optional<Location> /*location*/, ValueRange operands,
318 DictionaryAttr /*attributes*/, OpaqueProperties /*properties*/, RegionRange /*regions*/,
319 SmallVectorImpl<Type> &inferredReturnTypes
320) {
321 inferredReturnTypes.push_back(
323 context, cast<BitVectorType>(operands[0].getType()).getWidth() +
324 cast<BitVectorType>(operands[1].getType()).getWidth()
325 )
326 );
327 return success();
328}
329
330//===----------------------------------------------------------------------===//
331// RepeatOp
332//===----------------------------------------------------------------------===//
333
334LogicalResult RepeatOp::verify() {
335 unsigned inputWidth = cast<BitVectorType>(getInput().getType()).getWidth();
336 unsigned resultWidth = getType().getWidth();
337 if (resultWidth % inputWidth != 0) {
338 return emitOpError() << "result bit-vector width must be a multiple of the "
339 "input bit-vector width";
340 }
341
342 return success();
343}
344
346 unsigned inputWidth = cast<BitVectorType>(getInput().getType()).getWidth();
347 unsigned resultWidth = getType().getWidth();
348 return resultWidth / inputWidth;
349}
350
351void RepeatOp::build(OpBuilder &builder, OperationState &state, unsigned count, Value input) {
352 int64_t inputWidth = cast<BitVectorType>(input.getType()).getWidth();
353 Type resultTy = BitVectorType::get(builder.getContext(), inputWidth * count);
354 build(builder, state, resultTy, input);
355}
356
357ParseResult RepeatOp::parse(OpAsmParser &parser, OperationState &result) {
358 OpAsmParser::UnresolvedOperand input;
359 Type inputType;
360 llvm::SMLoc countLoc = parser.getCurrentLocation();
361
362 APInt count;
363 if (parser.parseInteger(count) || parser.parseKeyword("times")) {
364 return failure();
365 }
366
367 if (count.isNonPositive()) {
368 return parser.emitError(countLoc) << "integer must be positive";
369 }
370
371 llvm::SMLoc inputLoc = parser.getCurrentLocation();
372 if (parser.parseOperand(input) || parser.parseOptionalAttrDict(result.attributes) ||
373 parser.parseColon() || parser.parseType(inputType)) {
374 return failure();
375 }
376
377 if (parser.resolveOperand(input, inputType, result.operands)) {
378 return failure();
379 }
380
381 auto bvInputTy = dyn_cast<BitVectorType>(inputType);
382 if (!bvInputTy) {
383 return parser.emitError(inputLoc) << "input must have bit-vector type";
384 }
385
386 // Make sure no assertions can trigger and no silent overflows can happen
387 // Bit-width is stored as 'int64_t' parameter in 'BitVectorType'
388 const unsigned maxBw = 63;
389 if (count.getActiveBits() > maxBw) {
390 return parser.emitError(countLoc) << "integer must fit into " << maxBw << " bits";
391 }
392
393 // Store multiplication in an APInt twice the size to not have any overflow
394 // and check if it can be truncated to 'maxBw' bits without cutting of
395 // important bits.
396 APInt resultBw = bvInputTy.getWidth() * count.zext(2 * maxBw);
397 if (resultBw.getActiveBits() > maxBw) {
398 return parser.emitError(countLoc)
399 << "result bit-width (provided integer times bit-width of the input "
400 "type) must fit into "
401 << maxBw << " bits";
402 }
403
404 uint64_t val = resultBw.getZExtValue();
405 assert(val <= std::numeric_limits<int64_t>::max() && "value too large");
406 Type resultTy = BitVectorType::get(parser.getContext(), static_cast<int64_t>(val));
407 result.addTypes(resultTy);
408 return success();
409}
410
411void RepeatOp::print(OpAsmPrinter &printer) {
412 printer << ' ' << getCount() << " times " << getInput();
413 printer.printOptionalAttrDict((*this)->getAttrs());
414 printer << " : " << getInput().getType();
415}
416
417//===----------------------------------------------------------------------===//
418// BoolConstantOp
419//===----------------------------------------------------------------------===//
420
421void BoolConstantOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
422 setNameFn(getResult(), getValue() ? "true" : "false");
423}
424
425OpFoldResult BoolConstantOp::fold(FoldAdaptor adaptor) {
426 assert(adaptor.getOperands().empty() && "constant has no operands");
427 return getValueAttr();
428}
429
430//===----------------------------------------------------------------------===//
431// IntConstantOp
432//===----------------------------------------------------------------------===//
433
434void IntConstantOp::getAsmResultNames(function_ref<void(Value, StringRef)> setNameFn) {
435 SmallVector<char, 32> specialNameBuffer;
436 llvm::raw_svector_ostream specialName(specialNameBuffer);
437 specialName << "c" << getValue();
438 setNameFn(getResult(), specialName.str());
439}
440
441OpFoldResult IntConstantOp::fold(FoldAdaptor adaptor) {
442 assert(adaptor.getOperands().empty() && "constant has no operands");
443 return getValueAttr();
444}
445
446void IntConstantOp::print(OpAsmPrinter &p) {
447 p << ' ' << getValue();
448 p.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/ {"value"});
449}
450
451ParseResult IntConstantOp::parse(OpAsmParser &parser, OperationState &result) {
452 APInt value;
453 if (parser.parseInteger(value)) {
454 return failure();
455 }
456
457 result.getOrAddProperties<Properties>().setValue(
458 IntegerAttr::get(parser.getContext(), APSInt(value))
459 );
460
461 if (parser.parseOptionalAttrDict(result.attributes)) {
462 return failure();
463 }
464
465 result.addTypes(smt::IntType::get(parser.getContext()));
466 return success();
467}
468
469//===----------------------------------------------------------------------===//
470// ForallOp
471//===----------------------------------------------------------------------===//
472
473template <typename QuantifierOp> static LogicalResult verifyQuantifierRegions(QuantifierOp op) {
474 if (op.getBoundVarNames() && op.getBody().getNumArguments() != op.getBoundVarNames()->size()) {
475 return op.emitOpError("number of bound variable names must match number of block arguments");
476 }
477 if (!llvm::all_of(op.getBody().getArgumentTypes(), isAnyNonFuncSMTValueType)) {
478 return op.emitOpError() << "bound variables must by any non-function SMT value";
479 }
480
481 if (op.getBody().front().getTerminator()->getNumOperands() != 1) {
482 return op.emitOpError("must have exactly one yielded value");
483 }
484 if (!isa<BoolType>(op.getBody().front().getTerminator()->getOperand(0).getType())) {
485 return op.emitOpError("yielded value must be of '!smt.bool' type");
486 }
487
488 for (auto regionWithIndex : llvm::enumerate(op.getPatterns())) {
489 unsigned i = regionWithIndex.index();
490 Region &region = regionWithIndex.value();
491
492 if (op.getBody().getArgumentTypes() != region.getArgumentTypes()) {
493 return op.emitOpError() << "block argument number and types of the 'body' "
494 "and 'patterns' region #"
495 << i << " must match";
496 }
497 if (region.front().getTerminator()->getNumOperands() < 1) {
498 return op.emitOpError() << "'patterns' region #" << i
499 << " must have at least one yielded value";
500 }
501
502 // All operations in the 'patterns' region must be SMT operations.
503 auto result = region.walk([&](Operation *childOp) {
504 if (!isa<SMTDialect>(childOp->getDialect())) {
505 auto diag = op.emitOpError()
506 << "the 'patterns' region #" << i << " may only contain SMT dialect operations";
507 diag.attachNote(childOp->getLoc()) << "first non-SMT operation here";
508 return WalkResult::interrupt();
509 }
510
511 // There may be no quantifier (or other variable binding) operations in
512 // the 'patterns' region.
513 if (isa<ForallOp, ExistsOp>(childOp)) {
514 auto diag = op.emitOpError() << "the 'patterns' region #" << i
515 << " must not contain "
516 "any variable binding operations";
517 diag.attachNote(childOp->getLoc()) << "first violating operation here";
518 return WalkResult::interrupt();
519 }
520
521 return WalkResult::advance();
522 });
523 if (result.wasInterrupted()) {
524 return failure();
525 }
526 }
527
528 return success();
529}
530
531template <typename Properties>
532static void buildQuantifier(
533 OpBuilder &odsBuilder, OperationState &odsState, TypeRange boundVarTypes,
534 function_ref<Value(OpBuilder &, Location, ValueRange)> bodyBuilder,
535 std::optional<ArrayRef<StringRef>> boundVarNames,
536 function_ref<ValueRange(OpBuilder &, Location, ValueRange)> patternBuilder, uint32_t weight,
537 bool noPattern
538) {
539 odsState.addTypes(BoolType::get(odsBuilder.getContext()));
540 if (weight != 0) {
541 odsState.getOrAddProperties<Properties>().weight =
542 odsBuilder.getIntegerAttr(odsBuilder.getIntegerType(32), weight);
543 }
544 if (noPattern) {
545 odsState.getOrAddProperties<Properties>().noPattern = odsBuilder.getUnitAttr();
546 }
547 if (boundVarNames.has_value()) {
548 SmallVector<Attribute> boundVarNamesList;
549 for (StringRef str : *boundVarNames) {
550 boundVarNamesList.emplace_back(odsBuilder.getStringAttr(str));
551 }
552 odsState.getOrAddProperties<Properties>().boundVarNames =
553 odsBuilder.getArrayAttr(boundVarNamesList);
554 }
555 {
556 OpBuilder::InsertionGuard guard(odsBuilder);
557 Region *region = odsState.addRegion();
558 Block *block = odsBuilder.createBlock(region);
559 block->addArguments(
560 boundVarTypes, SmallVector<Location>(boundVarTypes.size(), odsState.location)
561 );
562 Value returnVal = bodyBuilder(odsBuilder, odsState.location, block->getArguments());
563 odsBuilder.create<llzk::smt::YieldOp>(odsState.location, returnVal);
564 }
565 if (patternBuilder) {
566 Region *region = odsState.addRegion();
567 OpBuilder::InsertionGuard guard(odsBuilder);
568 Block *block = odsBuilder.createBlock(region);
569 block->addArguments(
570 boundVarTypes, SmallVector<Location>(boundVarTypes.size(), odsState.location)
571 );
572 ValueRange returnVals = patternBuilder(odsBuilder, odsState.location, block->getArguments());
573 odsBuilder.create<llzk::smt::YieldOp>(odsState.location, returnVals);
574 }
575}
576
577LogicalResult ForallOp::verify() {
578 if (!getPatterns().empty() && getNoPattern()) {
579 return emitOpError() << "patterns and the no_pattern attribute must not be "
580 "specified at the same time";
581 }
582
583 return success();
584}
585
586LogicalResult ForallOp::verifyRegions() { return verifyQuantifierRegions(*this); }
587
589 OpBuilder &odsBuilder, OperationState &odsState, TypeRange boundVarTypes,
590 function_ref<Value(OpBuilder &, Location, ValueRange)> bodyBuilder,
591 std::optional<ArrayRef<StringRef>> boundVarNames,
592 function_ref<ValueRange(OpBuilder &, Location, ValueRange)> patternBuilder, uint32_t weight,
593 bool noPattern
594) {
595 buildQuantifier<Properties>(
596 odsBuilder, odsState, boundVarTypes, bodyBuilder, boundVarNames, patternBuilder, weight,
597 noPattern
598 );
599}
600
601//===----------------------------------------------------------------------===//
602// ExistsOp
603//===----------------------------------------------------------------------===//
604
605LogicalResult ExistsOp::verify() {
606 if (!getPatterns().empty() && getNoPattern()) {
607 return emitOpError() << "patterns and the no_pattern attribute must not be "
608 "specified at the same time";
609 }
610
611 return success();
612}
613
614LogicalResult ExistsOp::verifyRegions() { return verifyQuantifierRegions(*this); }
615
616void ExistsOp::build(
617 OpBuilder &odsBuilder, OperationState &odsState, TypeRange boundVarTypes,
618 function_ref<Value(OpBuilder &, Location, ValueRange)> bodyBuilder,
619 std::optional<ArrayRef<StringRef>> boundVarNames,
620 function_ref<ValueRange(OpBuilder &, Location, ValueRange)> patternBuilder, uint32_t weight,
621 bool noPattern
622) {
623 buildQuantifier<Properties>(
624 odsBuilder, odsState, boundVarTypes, bodyBuilder, boundVarNames, patternBuilder, weight,
625 noPattern
626 );
627}
628
629#define GET_OP_CLASSES
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:128
::llzk::smt::BitVectorAttr getValue()
Definition SMT.cpp.inc:2676
::llzk::smt::BitVectorAttr getValueAttr()
Definition SMT.h.inc:2213
::mlir::OpFoldResult fold(FoldAdaptor adaptor)
Definition SMTOps.cpp:135
::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:119
FoldAdaptor::Properties Properties
Definition SMT.h.inc:2162
GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute > > FoldAdaptor
Definition SMT.h.inc:2161
::mlir::TypedValue<::llzk::smt::BitVectorType > getResult()
Definition SMT.h.inc:2200
static BitVectorType get(::mlir::MLIRContext *context, int64_t width)
::mlir::TypedValue<::llzk::smt::BoolType > getResult()
Definition SMT.h.inc:4202
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:421
GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute > > FoldAdaptor
Definition SMT.h.inc:4163
::mlir::BoolAttr getValueAttr()
Definition SMT.h.inc:4215
::mlir::OpFoldResult fold(FoldAdaptor adaptor)
Definition SMTOps.cpp:425
::mlir::Region & getUnsatRegion()
Definition SMT.h.inc:4390
::mlir::Region & getUnknownRegion()
Definition SMT.h.inc:4386
::mlir::Region & getSatRegion()
Definition SMT.h.inc:4382
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:212
::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:316
::mlir::TypedValue<::mlir::Type > getResult()
Definition SMT.h.inc:4707
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:144
::std::optional< ::llvm::StringRef > getNamePrefix()
Definition SMT.cpp.inc:5541
::mlir::Operation::operand_range getInputs()
Definition SMT.h.inc:4858
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:280
::llvm::LogicalResult verify()
Definition SMTOps.cpp:286
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:276
::mlir::Operation::operand_range getInputs()
Definition SMT.h.inc:4987
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:258
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:254
::llvm::LogicalResult verify()
Definition SMTOps.cpp:264
::llvm::LogicalResult verify()
Definition SMTOps.cpp:605
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:614
::mlir::MutableArrayRef<::mlir::Region > getPatterns()
Definition SMT.h.inc:5233
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)
::mlir::TypedValue<::llzk::smt::BitVectorType > getInput()
Definition SMT.h.inc:5457
::llvm::LogicalResult verify()
Definition SMTOps.cpp:298
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:586
::llvm::LogicalResult verify()
Definition SMTOps.cpp:577
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:588
::mlir::MutableArrayRef<::mlir::Region > getPatterns()
Definition SMT.h.inc:5739
::mlir::APInt getValue()
Definition SMT.cpp.inc:8106
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:446
GenericAdaptor<::llvm::ArrayRef<::mlir::Attribute > > FoldAdaptor
Definition SMT.h.inc:6714
::mlir::OpFoldResult fold(FoldAdaptor adaptor)
Definition SMTOps.cpp:441
::mlir::TypedValue<::llzk::smt::IntType > getResult()
Definition SMT.h.inc:6753
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition SMTOps.cpp:434
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:451
FoldAdaptor::Properties Properties
Definition SMT.h.inc:6715
::mlir::IntegerAttr getValueAttr()
Definition SMT.h.inc:6766
::mlir::TypedValue<::llzk::smt::BitVectorType > getInput()
Definition SMT.h.inc:8450
::llvm::LogicalResult verify()
Definition SMTOps.cpp:334
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, unsigned count, mlir::Value input)
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:411
unsigned getCount()
Get the number of times the input operand is repeated.
Definition SMTOps.cpp:345
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:357
::mlir::Attribute getValue()
::llzk::smt::KeywordAttr getKey()
void print(::mlir::OpAsmPrinter &p)
Definition SMTOps.cpp:190
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition SMTOps.cpp:167
::mlir::Attribute getValueAttr()
Definition SMT.h.inc:8796
::llvm::LogicalResult verify()
Definition SMTOps.cpp:198
::llvm::LogicalResult verifyRegions()
Definition SMTOps.cpp:152
::mlir::Operation::operand_range getInputs()
Definition SMT.h.inc:9132
bool isAnyNonFuncSMTValueType(mlir::Type type)
Returns whether the given type is an SMT value type (excluding functions).