39 SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>> &effects
41 effects.emplace_back(MemoryEffects::Write::get());
52static FailureOr<bool> getBoolValue(Attribute attr) {
53 auto ia = llvm::dyn_cast_or_null<IntegerAttr>(attr);
54 if (!ia || !ia.getType().isInteger(1)) {
57 return ia.getValue().getBoolValue();
61static IntegerAttr makeBoolAttr(MLIRContext *ctx,
bool val) {
62 auto i1Ty = IntegerType::get(ctx, 1);
63 return IntegerAttr::get(i1Ty, val ? 1 : 0);
73 auto lhs = getBoolValue(adaptor.
getLhs());
74 auto rhs = getBoolValue(adaptor.
getRhs());
75 if (failed(lhs) || failed(rhs)) {
78 return makeBoolAttr(getContext(), *lhs && *rhs);
86 auto lhs = getBoolValue(adaptor.
getLhs());
87 auto rhs = getBoolValue(adaptor.
getRhs());
88 if (failed(lhs) || failed(rhs)) {
91 return makeBoolAttr(getContext(), *lhs || *rhs);
99 auto lhs = getBoolValue(adaptor.
getLhs());
100 auto rhs = getBoolValue(adaptor.
getRhs());
101 if (failed(lhs) || failed(rhs)) {
104 return makeBoolAttr(getContext(), *lhs != *rhs);
112 auto val = getBoolValue(adaptor.
getOperand());
116 return makeBoolAttr(getContext(), !*val);
124eval(
FeltCmpPredicate pred,
const llvm::DynamicAPInt &lval,
const llvm::DynamicAPInt &rval) {
139 llvm_unreachable(
"invalid FeltCmpPredicate");
143 auto lhsAttr = llvm::dyn_cast_or_null<felt::FeltConstAttr>(adaptor.
getLhs());
144 auto rhsAttr = llvm::dyn_cast_or_null<felt::FeltConstAttr>(adaptor.
getRhs());
149 auto isZero = [](felt::FeltConstAttr value) {
154 if (value.getRawValue() == 0) {
157 auto reduced = value.getReducedValue();
158 return reduced && *reduced == 0;
160 if (isZero(rhsAttr)) {
165 if (isZero(lhsAttr)) {
171 if (!lhsAttr || !rhsAttr || lhsAttr.getFieldName() != rhsAttr.getFieldName()) {
175 auto lhs = lhsAttr.getReducedValue();
176 auto rhs = rhsAttr.getReducedValue();
181 return makeBoolAttr(getContext(), eval(predicate, *lhs, *rhs));
193template <
typename Op> LogicalResult verifyQuantOp(Op op) {
194 auto *block = op.getBody();
195 if (!block || block->getNumArguments() != 1) {
196 return op->emitOpError(
"must have one block argument");
198 auto argType = block->getArgument(0).getType();
200 if (argType != eltType) {
201 return op->emitOpError() <<
"expects element type " << argType <<
" but sort has element type "
205 auto termOp = block->getTerminator();
206 if (!llvm::dyn_cast_if_present<YieldOp>(termOp)) {
220ParseResult parseQuantOp(OpAsmParser &parser, OperationState &result) {
221 OpAsmParser::Argument arg;
222 if (parser.parseArgument(arg)) {
226 if (succeeded(parser.parseOptionalColon())) {
227 if (parser.parseType(arg.type)) {
231 if (parser.parseKeyword(
"in")) {
234 OpAsmParser::UnresolvedOperand sortOperand;
235 array::ArrayType sortType;
236 if (parser.parseOperand(sortOperand)) {
239 if (parser.parseColonType(sortType)) {
242 if (parser.resolveOperand(sortOperand, sortType, result.operands)) {
248 assert(arg.type &&
"argument type must be inferred from the array element type");
251 auto *body = result.addRegion();
252 SMLoc loc = parser.getCurrentLocation();
253 if (parser.parseRegion(
261 return parser.emitError(loc,
"expected non-empty body");
263 if (parser.parseOptionalAttrDictWithKeyword(result.attributes)) {
267 result.types = {parser.getBuilder().getI1Type()};
272template <
typename Op>
void printQuantOp(OpAsmPrinter &p, Op op) {
274 p.printRegionArgument(op.getBody()->getArgument(0));
276 p.printOperand(op.getSort());
277 p <<
" : " << op.getSort().getType();
279 p.printRegion(op.getRegion(),
false);
281 p.printOptionalAttrDictWithKeyword(op->getAttrs());
292 return parseQuantOp(parser, result);
304 return parseQuantOp(parser, result);