38 SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>> &effects
40 effects.emplace_back(MemoryEffects::Write::get());
51static FailureOr<bool> getBoolValue(Attribute attr) {
52 auto ia = llvm::dyn_cast_or_null<IntegerAttr>(attr);
53 if (!ia || !ia.getType().isInteger(1)) {
56 return ia.getValue().getBoolValue();
60static IntegerAttr makeBoolAttr(MLIRContext *ctx,
bool val) {
61 auto i1Ty = IntegerType::get(ctx, 1);
62 return IntegerAttr::get(i1Ty, val ? 1 : 0);
72 auto lhs = getBoolValue(adaptor.
getLhs());
73 auto rhs = getBoolValue(adaptor.
getRhs());
74 if (failed(lhs) || failed(rhs)) {
77 return makeBoolAttr(getContext(), *lhs && *rhs);
85 auto lhs = getBoolValue(adaptor.
getLhs());
86 auto rhs = getBoolValue(adaptor.
getRhs());
87 if (failed(lhs) || failed(rhs)) {
90 return makeBoolAttr(getContext(), *lhs || *rhs);
98 auto lhs = getBoolValue(adaptor.
getLhs());
99 auto rhs = getBoolValue(adaptor.
getRhs());
100 if (failed(lhs) || failed(rhs)) {
103 return makeBoolAttr(getContext(), *lhs != *rhs);
111 auto val = getBoolValue(adaptor.
getOperand());
115 return makeBoolAttr(getContext(), !*val);
122inline static bool eval(
FeltCmpPredicate pred,
const llvm::APInt &lval,
const llvm::APInt &rval) {
129 return lval.ult(rval);
131 return lval.ule(rval);
133 return lval.ugt(rval);
135 return lval.uge(rval);
137 llvm_unreachable(
"invalid FeltCmpPredicate");
141 auto lhsAttr = llvm::dyn_cast_or_null<felt::FeltConstAttr>(adaptor.
getLhs());
142 auto rhsAttr = llvm::dyn_cast_or_null<felt::FeltConstAttr>(adaptor.
getRhs());
143 if (!lhsAttr || !rhsAttr) {
148 llvm::APInt lval = lhsAttr.getValue();
149 llvm::APInt rval = rhsAttr.getValue();
150 unsigned w = std::max(lval.getBitWidth(), rval.getBitWidth());
151 if (lval.getBitWidth() < w) {
154 if (rval.getBitWidth() < w) {
157 return makeBoolAttr(getContext(), eval(
getPredicate(), lval, rval));
169template <
typename Op> LogicalResult verifyQuantOp(Op op) {
170 auto *block = op.getBody();
171 if (!block || block->getNumArguments() != 1) {
172 return op->emitOpError() <<
"must have one block argument";
174 auto argType = block->getArgument(0).getType();
176 if (argType != eltType) {
177 return op->emitOpError() <<
"expects element type " << argType <<
" but sort has element type "
181 auto termOp = block->getTerminator();
182 if (!llvm::dyn_cast_if_present<YieldOp>(termOp)) {
183 return op->emitOpError() <<
"expects 'bool.yield' terminator op";
196ParseResult parseQuantOp(OpAsmParser &parser, OperationState &result) {
197 OpAsmParser::Argument arg;
198 if (parser.parseArgument(arg)) {
202 if (succeeded(parser.parseOptionalColon())) {
203 if (parser.parseType(arg.type)) {
207 if (parser.parseKeyword(
"in")) {
210 OpAsmParser::UnresolvedOperand sortOperand;
211 array::ArrayType sortType;
212 if (parser.parseOperand(sortOperand)) {
215 if (parser.parseColonType(sortType)) {
218 if (parser.resolveOperand(sortOperand, sortType, result.operands)) {
224 assert(arg.type &&
"argument type must be inferred from the array element type");
227 auto *body = result.addRegion();
228 SMLoc loc = parser.getCurrentLocation();
229 if (parser.parseRegion(
237 return parser.emitError(loc,
"expected non-empty body");
239 if (parser.parseOptionalAttrDictWithKeyword(result.attributes)) {
243 result.types = {parser.getBuilder().getI1Type()};
248template <
typename Op>
void printQuantOp(OpAsmPrinter &p, Op op) {
250 p.printRegionArgument(op.getBody()->getArgument(0));
252 p.printOperand(op.getSort());
253 p <<
" : " << op.getSort().getType();
255 p.printRegion(op.getRegion(),
false);
257 p.printOptionalAttrDictWithKeyword(op->getAttrs());
268 return parseQuantOp(parser, result);
279ParseResult
ExistsOp::parse(OpAsmParser &parser, OperationState &result) {
280 return parseQuantOp(parser, result);