@@ -335,6 +335,9 @@ class SolidityToMLIRPass {
335335 // / Returns the mlir expression for the binary operation.
336336 mlir::Value genExpr (BinaryOperation const &binOp);
337337
338+ // / Returns the mlir expressions for the conditional (ternary) operation.
339+ mlir::SmallVector<mlir::Value> genExprs (Conditional const &cond);
340+
338341 // / Returns the mlir expression for the call.
339342 mlir::SmallVector<mlir::Value> genExprs (FunctionCall const &call);
340343
@@ -770,6 +773,31 @@ mlir::Value SolidityToMLIRPass::genExpr(UnaryOperation const &unaryOp) {
770773 b.create <mlir::sol::ConstantOp>(loc, b.getIntegerAttr (mlirTy, 0 ));
771774 return genBinExpr (Token::Sub, zero, expr, loc);
772775 }
776+ // Logical not
777+ case Token::Not: {
778+ mlir::Value expr = genRValExpr (unaryOp.subExpression ());
779+ mlir::Value zero = b.create <mlir::sol::ConstantOp>(
780+ loc, b.getIntegerAttr (expr.getType (), 0 ));
781+ return b.create <mlir::sol::CmpOp>(loc, mlir::sol::CmpPredicate::eq, expr,
782+ zero);
783+ }
784+ // Bitwise not (~x == x ^ -1)
785+ case Token::BitNot: {
786+ mlir::Value expr = genRValExpr (unaryOp.subExpression ());
787+
788+ // Convert bytes to int if needed.
789+ if (auto bytesTy = mlir::dyn_cast<mlir::sol::BytesType>(expr.getType ())) {
790+ mlir::Type intTy =
791+ b.getIntegerType (bytesTy.getSize () * 8 , /* isSigned=*/ false );
792+ expr = genCast (expr, intTy);
793+ }
794+
795+ auto intTy = mlir::cast<mlir::IntegerType>(expr.getType ());
796+ mlir::Value allOnes = b.create <mlir::sol::ConstantOp>(
797+ loc,
798+ b.getIntegerAttr (intTy, llvm::APInt::getAllOnes (intTy.getWidth ())));
799+ return b.create <mlir::sol::XorOp>(loc, expr, allOnes);
800+ }
773801 default :
774802 break ;
775803 }
@@ -831,6 +859,39 @@ mlir::Value SolidityToMLIRPass::genExpr(BinaryOperation const &binOp) {
831859 return genBinExpr (binOp.getOperator (), lhs, rhs, loc);
832860}
833861
862+ mlir::SmallVector<mlir::Value>
863+ SolidityToMLIRPass::genExprs (Conditional const &cond) {
864+ mlir::Location loc = getLoc (cond);
865+ mlir::Value condVal = genRValExpr (cond.condition ());
866+
867+ // Get result types - could be single type or tuple.
868+ mlir::SmallVector<mlir::Type> resTys;
869+ if (TupleType const *tupleTy =
870+ dynamic_cast <TupleType const *>(cond.annotation ().type )) {
871+ for (const Type *astTy : tupleTy->components ())
872+ resTys.push_back (getType (astTy));
873+ } else {
874+ resTys.push_back (getType (cond.annotation ().type ));
875+ }
876+
877+ auto ifOp =
878+ b.create <mlir::scf::IfOp>(loc, resTys, condVal, /* withElse=*/ true );
879+ mlir::OpBuilder::InsertionGuard guard (b);
880+
881+ // True branch
882+ b.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
883+ mlir::SmallVector<mlir::Value> trueVals = genRValExprs (cond.trueExpression ());
884+ b.create <mlir::scf::YieldOp>(loc, trueVals);
885+
886+ // False branch
887+ b.setInsertionPointToStart (&ifOp.getElseRegion ().front ());
888+ mlir::SmallVector<mlir::Value> falseVals =
889+ genRValExprs (cond.falseExpression ());
890+ b.create <mlir::scf::YieldOp>(loc, falseVals);
891+
892+ return ifOp.getResults ();
893+ }
894+
834895mlir::Value SolidityToMLIRPass::genExpr (IndexAccess const &idxAcc) {
835896 mlir::Location loc = getLoc (idxAcc);
836897
@@ -1776,6 +1837,13 @@ mlir::Value SolidityToMLIRPass::genLValExpr(Expression const &expr) {
17761837 return {};
17771838 }
17781839
1840+ // Conditional (ternary operator)
1841+ if (const auto *cond = dynamic_cast <Conditional const *>(&expr)) {
1842+ mlir::SmallVector<mlir::Value> exprs = genExprs (*cond);
1843+ assert (exprs.size () == 1 );
1844+ return exprs[0 ];
1845+ }
1846+
17791847 llvm_unreachable (" NYI" );
17801848}
17811849
@@ -1789,6 +1857,10 @@ SolidityToMLIRPass::genLValExprs(Expression const &expr) {
17891857 if (const auto *call = dynamic_cast <FunctionCall const *>(&expr))
17901858 return genExprs (*call);
17911859
1860+ // Conditional (ternary)
1861+ if (const auto *cond = dynamic_cast <Conditional const *>(&expr))
1862+ return genExprs (*cond);
1863+
17921864 mlir::SmallVector<mlir::Value, 1 > vals;
17931865 vals.push_back (genLValExpr (expr));
17941866 return vals;
0 commit comments