@@ -334,7 +334,7 @@ class Parser {
334334 FailureOr<ast::Expr *> parseLogicalAndExpr ();
335335 FailureOr<ast::Expr *> parseEqualityExpr ();
336336 FailureOr<ast::Expr *> parseRelationExpr ();
337- FailureOr<ast::Expr *> parseExp2Log2Expr ();
337+ FailureOr<ast::Expr *> parseExp2Log2AbsExpr ();
338338 FailureOr<ast::Expr *> parseAddSubExpr ();
339339 FailureOr<ast::Expr *> parseMulDivModExpr ();
340340 FailureOr<ast::Expr *> parseLogicalNotExpr ();
@@ -624,13 +624,15 @@ class Parser {
624624 ast::UserRewriteDecl *subRewrite;
625625 ast::UserRewriteDecl *log2Rewrite;
626626 ast::UserRewriteDecl *exp2Rewrite;
627+ ast::UserRewriteDecl *absRewrite;
627628 ast::UserConstraintDecl *mulConstraint;
628629 ast::UserConstraintDecl *divConstraint;
629630 ast::UserConstraintDecl *modConstraint;
630631 ast::UserConstraintDecl *addConstraint;
631632 ast::UserConstraintDecl *subConstraint;
632633 ast::UserConstraintDecl *log2Constraint;
633634 ast::UserConstraintDecl *exp2Constraint;
635+ ast::UserConstraintDecl *absConstraint;
634636 } builtins{};
635637};
636638} // namespace
@@ -701,6 +703,8 @@ void Parser::declareBuiltins() {
701703 " __builtin_log2Rewrite" , {" Attr" }, true );
702704 builtins.exp2Rewrite = declareBuiltin<ast::UserRewriteDecl>(
703705 " __builtin_exp2Rewrite" , {" Attr" }, true );
706+ builtins.absRewrite = declareBuiltin<ast::UserRewriteDecl>(
707+ " __builtin_absRewrite" , {" Attr" }, true );
704708 builtins.mulConstraint = declareBuiltin<ast::UserConstraintDecl>(
705709 " __builtin_mulConstraint" , {" lhs" , " rhs" }, true );
706710 builtins.divConstraint = declareBuiltin<ast::UserConstraintDecl>(
@@ -715,6 +719,8 @@ void Parser::declareBuiltins() {
715719 " __builtin_log2Constraint" , {" Attr" }, true );
716720 builtins.exp2Constraint = declareBuiltin<ast::UserConstraintDecl>(
717721 " __builtin_exp2Constraint" , {" Attr" }, true );
722+ builtins.absConstraint = declareBuiltin<ast::UserConstraintDecl>(
723+ " __builtin_absConstraint" , {" Attr" }, true );
718724}
719725
720726FailureOr<ast::Module *> Parser::parseModule () {
@@ -2030,15 +2036,15 @@ FailureOr<ast::Expr *> Parser::parseAddSubExpr() {
20302036}
20312037
20322038FailureOr<ast::Expr *> Parser::parseMulDivModExpr () {
2033- auto lhs = parseExp2Log2Expr ();
2039+ auto lhs = parseExp2Log2AbsExpr ();
20342040 if (failed (lhs))
20352041 return failure ();
20362042
20372043 for (;;) {
20382044 switch (curToken.getKind ()) {
20392045 case Token::mul: {
20402046 consumeToken ();
2041- auto rhs = parseExp2Log2Expr ();
2047+ auto rhs = parseExp2Log2AbsExpr ();
20422048 if (failed (rhs))
20432049 return failure ();
20442050 SmallVector<ast::Expr *> args{*lhs, *rhs};
@@ -2058,7 +2064,7 @@ FailureOr<ast::Expr *> Parser::parseMulDivModExpr() {
20582064 }
20592065 case Token::div: {
20602066 consumeToken ();
2061- auto rhs = parseExp2Log2Expr ();
2067+ auto rhs = parseExp2Log2AbsExpr ();
20622068 if (failed (rhs))
20632069 return failure ();
20642070 SmallVector<ast::Expr *> args{*lhs, *rhs};
@@ -2078,7 +2084,7 @@ FailureOr<ast::Expr *> Parser::parseMulDivModExpr() {
20782084 }
20792085 case Token::mod: {
20802086 consumeToken ();
2081- auto rhs = parseExp2Log2Expr ();
2087+ auto rhs = parseExp2Log2AbsExpr ();
20822088 if (failed (rhs))
20832089 return failure ();
20842090 SmallVector<ast::Expr *> args{*lhs, *rhs};
@@ -2100,7 +2106,7 @@ FailureOr<ast::Expr *> Parser::parseMulDivModExpr() {
21002106 }
21012107}
21022108
2103- FailureOr<ast::Expr *> Parser::parseExp2Log2Expr () {
2109+ FailureOr<ast::Expr *> Parser::parseExp2Log2AbsExpr () {
21042110 FailureOr<ast::Expr *> expr = nullptr ;
21052111
21062112 switch (curToken.getKind ()) {
@@ -2144,6 +2150,26 @@ FailureOr<ast::Expr *> Parser::parseExp2Log2Expr() {
21442150 : createBuiltinCall (curToken.getLoc (), builtins.exp2Constraint ,
21452151 {*expr});
21462152 }
2153+ case Token::abs: {
2154+ consumeToken ();
2155+ consumeToken (Token::l_paren);
2156+ expr = parseAddSubExpr ();
2157+ if (failed (expr))
2158+ return failure ();
2159+
2160+ // Check if it is in rewrite section but not in the let statement
2161+ bool inRewriteSection = parserContext == ParserContext::Rewrite;
2162+ if (inRewriteSection && nativeOperatorContext != NativeOperatorContext::Let)
2163+ return emitError (" cannot evaluate abs operator in rewrite section. "
2164+ " Assign to a variable with `let`" );
2165+
2166+ consumeToken (Token::r_paren);
2167+ return inRewriteSection
2168+ ? createBuiltinCall (curToken.getLoc (), builtins.absRewrite ,
2169+ {*expr})
2170+ : createBuiltinCall (curToken.getLoc (), builtins.absConstraint ,
2171+ {*expr});
2172+ }
21472173 default :
21482174 return parseLogicalNotExpr ();
21492175 }
0 commit comments