diff --git a/libsolidity/codegen/mlir/Sol/SolOps.td b/libsolidity/codegen/mlir/Sol/SolOps.td index 85742a8e6..e0508ef1e 100644 --- a/libsolidity/codegen/mlir/Sol/SolOps.td +++ b/libsolidity/codegen/mlir/Sol/SolOps.td @@ -110,6 +110,9 @@ def Sol_DivOp : Sol_UncheckedIntArithOp<"div"> { def Sol_ModOp : Sol_UncheckedIntArithOp<"mod"> { // TODO: folder, canonicalizer } +def Sol_ExpOp : Sol_UncheckedIntArithOp<"exp"> { + // TODO: folder, canonicalizer +} def Sol_CmpOp : Sol_Op<"cmp", [Pure, SameTypeOperands]> { let arguments = (ins Sol_CmpPredicateAttr:$predicate, Sol_Int:$lhs, diff --git a/libsolidity/codegen/mlir/SolToStandardPass.cpp b/libsolidity/codegen/mlir/SolToStandardPass.cpp index 2b1eaf320..1894840aa 100644 --- a/libsolidity/codegen/mlir/SolToStandardPass.cpp +++ b/libsolidity/codegen/mlir/SolToStandardPass.cpp @@ -139,6 +139,7 @@ struct ConvertSolToStandard sol::CSubOp, sol::CMulOp, sol::CDivOp, + sol::ExpOp, sol::AllocaOp, sol::MallocOp, sol::ArrayLitOp, diff --git a/libsolidity/codegen/mlir/SolidityToMLIR.cpp b/libsolidity/codegen/mlir/SolidityToMLIR.cpp index f1bf4a2d0..b4c2dd6d7 100644 --- a/libsolidity/codegen/mlir/SolidityToMLIR.cpp +++ b/libsolidity/codegen/mlir/SolidityToMLIR.cpp @@ -619,6 +619,10 @@ mlir::Value SolidityToMLIRPass::genBinExpr(Token op, mlir::Value lhs, return b.create(loc, lhs, rhs); case Token::Mod: return b.create(loc, lhs, rhs); + case Token::Exp: + if (inUnchecked) + return b.create(loc, lhs, rhs); + break; case Token::Equal: return b.create(loc, mlir::sol::CmpPredicate::eq, lhs, rhs); diff --git a/libsolidity/codegen/mlir/Target/EVM/SolToYul.cpp b/libsolidity/codegen/mlir/Target/EVM/SolToYul.cpp index c8cdcc53c..ea0817c84 100644 --- a/libsolidity/codegen/mlir/Target/EVM/SolToYul.cpp +++ b/libsolidity/codegen/mlir/Target/EVM/SolToYul.cpp @@ -113,8 +113,8 @@ struct BytesCastOpLowering : public OpConversionPattern { } }; -/// A templatized version of a conversion pattern for lowering add, sub and mul -/// ops. +/// A templatized version of a conversion pattern for lowering add, sub, mul +/// and exp ops. template struct ArithBinOpLowering : public OpConversionPattern { using OpConversionPattern::OpConversionPattern; @@ -2213,6 +2213,7 @@ void evm::populateArithPats(RewritePatternSet &pats, TypeConverter &tyConv) { ArithBinOpLowering, ArithBinOpLowering, ArithBinOpLowering, + ArithBinOpLowering, DivOrModOpLowering, DivOrModOpLowering, CmpOpLowering>(tyConv, pats.getContext()); diff --git a/libsolidity/codegen/mlir/Target/EVM/Util.cpp b/libsolidity/codegen/mlir/Target/EVM/Util.cpp index 8f5430759..ef383600d 100644 --- a/libsolidity/codegen/mlir/Target/EVM/Util.cpp +++ b/libsolidity/codegen/mlir/Target/EVM/Util.cpp @@ -148,6 +148,14 @@ Value evm::Builder::genStoragePtr(Value addr, std::optional locArg) { return b.create(loc, storageAddrSpacePtrTy, addr); } +Value evm::Builder::genTStoragePtr(Value addr, std::optional locArg) { + Location loc = locArg ? *locArg : defLoc; + + auto tstorageAddrSpacePtrTy = LLVM::LLVMPointerType::get( + b.getContext(), evm::AddrSpace_TransientStorage); + return b.create(loc, tstorageAddrSpacePtrTy, addr); +} + Value evm::Builder::genCodePtr(Value addr, std::optional locArg) { Location loc = locArg ? *locArg : defLoc; diff --git a/libsolidity/codegen/mlir/Target/EVM/Util.h b/libsolidity/codegen/mlir/Target/EVM/Util.h index c50573e60..e8366a4db 100644 --- a/libsolidity/codegen/mlir/Target/EVM/Util.h +++ b/libsolidity/codegen/mlir/Target/EVM/Util.h @@ -164,6 +164,11 @@ class Builder { genStoragePtr(mlir::Value addr, std::optional locArg = std::nullopt); + /// Generates a pointer to the address in the transient storage. + mlir::Value + genTStoragePtr(mlir::Value addr, + std::optional locArg = std::nullopt); + /// Generates a pointer to the address in the code. mlir::Value genCodePtr(mlir::Value addr, std::optional locArg = std::nullopt); diff --git a/libsolidity/codegen/mlir/Target/EVM/YulToStandard.cpp b/libsolidity/codegen/mlir/Target/EVM/YulToStandard.cpp index 63973d50e..455aec456 100644 --- a/libsolidity/codegen/mlir/Target/EVM/YulToStandard.cpp +++ b/libsolidity/codegen/mlir/Target/EVM/YulToStandard.cpp @@ -58,6 +58,182 @@ struct Keccak256OpLowering : public OpRewritePattern { } }; +struct DivOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::DivOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_div, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getDividend(), op.getDivisor()}, "evm.div"); + + return success(); + } +}; + +struct SDivOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::SDivOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_sdiv, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getDividend(), op.getDivisor()}, "evm.sdiv"); + + return success(); + } +}; + +struct ModOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::ModOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_mod, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getValue(), op.getMod()}, "evm.mod"); + + return success(); + } +}; + +struct SModOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::SModOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_smod, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getValue(), op.getMod()}, "evm.smod"); + + return success(); + } +}; + +struct ShlOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::ShlOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_shl, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getShift(), op.getVal()}, "evm.shl"); + + return success(); + } +}; + +struct ShrOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::ShrOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_shr, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getShift(), op.getVal()}, "evm.shr"); + + return success(); + } +}; + +struct SarOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::SarOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_sar, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getShift(), op.getVal()}, "evm.sar"); + + return success(); + } +}; + +struct ExpOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::ExpOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_exp, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getBase(), op.getExp()}, "evm.exp"); + + return success(); + } +}; + +struct AddModOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::AddModOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_addmod, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getX(), op.getY(), op.getMod()}, "evm.addmod"); + + return success(); + } +}; + +struct MulModOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::MulModOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_mulmod, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getX(), op.getY(), op.getMod()}, "evm.mulmod"); + + return success(); + } +}; + +struct SignExtendOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::SignExtendOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_signextend, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getVal(), op.getOff()}, "evm.signextend"); + + return success(); + } +}; + struct LogOpLowering : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -110,6 +286,32 @@ struct AddressOpLowering : public OpRewritePattern { } }; +struct BalanceOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::BalanceOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_balance, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getAddr()}, + "evm.balance"); + return success(); + } +}; + +struct SelfBalanceOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::SelfBalanceOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_selfbalance, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, + "evm.selfbalance"); + return success(); + } +}; + struct CallerOpLowering : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -135,6 +337,159 @@ struct GasOpLowering : public OpRewritePattern { } }; +struct ChainIdOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::ChainIdOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_chainid, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, "evm.chainid"); + return success(); + } +}; + +struct BaseFeeOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::BaseFeeOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_basefee, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, "evm.basefee"); + return success(); + } +}; + +struct BlobBaseFeeOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::BlobBaseFeeOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_blobbasefee, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, + "evm.blobbasefee"); + return success(); + } +}; + +struct OriginOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::OriginOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_origin, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, "evm.origin"); + return success(); + } +}; + +struct GasPriceOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::GasPriceOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_gasprice, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, + "evm.gasprice"); + return success(); + } +}; + +struct BlockHashOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::BlockHashOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_blockhash, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getBlock()}, + "evm.blockhash"); + return success(); + } +}; + +struct BlobHashOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::BlobHashOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_blobhash, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{op.getIdx()}, + "evm.blobhash"); + return success(); + } +}; + +struct CoinBaseOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::CoinBaseOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_coinbase, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, + "evm.coinbase"); + return success(); + } +}; + +struct TimeStampOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::TimeStampOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_timestamp, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, + "evm.timestamp"); + return success(); + } +}; + +struct NumberOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::NumberOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_number, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, "evm.number"); + return success(); + } +}; + +struct PrevrandaoOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::PrevrandaoOp op, + PatternRewriter &r) const override { + // TODO: fix the intrinsic name in LLVM. + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_difficulty, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, + "evm.difficulty"); + return success(); + } +}; + +struct GasLimitOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::GasLimitOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_gaslimit, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, + "evm.gaslimit"); + return success(); + } +}; + struct CallValOpLowering : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -248,6 +603,34 @@ struct SStoreOpLowering : public OpRewritePattern { } }; +struct TLoadOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::TLoadOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op->getLoc()); + + Value ptr = evmB.genTStoragePtr(op.getAddr()); + r.replaceOpWithNewOp(op, r.getIntegerType(256), ptr, + evm::getAlignment(ptr)); + return success(); + } +}; + +struct TStoreOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::TStoreOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op->getLoc()); + + Value ptr = evmB.genTStoragePtr(op.getAddr()); + r.replaceOpWithNewOp(op, op.getVal(), ptr, + evm::getAlignment(ptr)); + return success(); + } +}; + struct DataOffsetOpLowering : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -332,6 +715,19 @@ struct ExtCodeCopyOpLowering : public OpRewritePattern { } }; +struct ExtCodeHashOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::ExtCodeHashOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_extcodehash, + /*resTy=*/r.getIntegerType(256), + /*ins=*/op.getAddr(), + "evm.extcodehash"); + return success(); + } +}; + struct CreateOpLowering : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -377,6 +773,18 @@ struct MLoadOpLowering : public OpRewritePattern { } }; +struct MSizeOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::MSizeOp op, + PatternRewriter &r) const override { + r.replaceOpWithNewOp(op, llvm::Intrinsic::evm_msize, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ValueRange{}, "evm.msize"); + return success(); + } +}; + struct LoadImmutable2OpLowering : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -560,6 +968,25 @@ struct BuiltinCallOpLowering : public OpRewritePattern { } }; +struct CallCodeOpLowering : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(yul::CallCodeOp op, + PatternRewriter &r) const override { + evm::Builder evmB(r, op.getLoc()); + + r.replaceOpWithNewOp( + op, llvm::Intrinsic::evm_callcode, + /*resTy=*/r.getIntegerType(256), + /*ins=*/ + ValueRange{op.getGas(), op.getAddress(), op.getValue(), + evmB.genHeapPtr(op.getInpOffset()), op.getInpSize(), + evmB.genHeapPtr(op.getOutOffset()), op.getOutSize()}, + "evm.callcode"); + return success(); + } +}; + struct StaticCallOpLowering : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -695,12 +1122,37 @@ struct ObjectOpLowering : public OpRewritePattern { void evm::populateYulPats(RewritePatternSet &pats) { pats.add< // clang-format off + AddModOpLowering, + MulModOpLowering, UpdFreePtrOpLowering, Keccak256OpLowering, + DivOpLowering, + SDivOpLowering, + ModOpLowering, + SModOpLowering, + ShlOpLowering, + ShrOpLowering, + SarOpLowering, + ExpOpLowering, + SignExtendOpLowering, LogOpLowering, AddressOpLowering, + BalanceOpLowering, + SelfBalanceOpLowering, CallerOpLowering, GasOpLowering, + ChainIdOpLowering, + BaseFeeOpLowering, + BlobBaseFeeOpLowering, + OriginOpLowering, + GasPriceOpLowering, + BlockHashOpLowering, + BlobHashOpLowering, + CoinBaseOpLowering, + TimeStampOpLowering, + NumberOpLowering, + PrevrandaoOpLowering, + GasLimitOpLowering, RevertOpLowering, StopOpLowering, CallValOpLowering, @@ -711,15 +1163,19 @@ void evm::populateYulPats(RewritePatternSet &pats) { ReturnDataCopyOpLowering, SLoadOpLowering, SStoreOpLowering, + TLoadOpLowering, + TStoreOpLowering, DataOffsetOpLowering, DataSizeOpLowering, CodeSizeOpLowering, CodeCopyOpLowering, ExtCodeSizeOpLowering, ExtCodeCopyOpLowering, + ExtCodeHashOpLowering, CreateOpLowering, Create2OpLowering, MLoadOpLowering, + MSizeOpLowering, LoadImmutableOpLowering, LoadImmutable2OpLowering, LinkerSymbolOpLowering, @@ -730,6 +1186,7 @@ void evm::populateYulPats(RewritePatternSet &pats) { MCopyOpLowering, MemGuardOpLowering, BuiltinCallOpLowering, + CallCodeOpLowering, StaticCallOpLowering, DelegateCallOpLowering, BuiltinRetOpLowering, diff --git a/libsolidity/codegen/mlir/Yul/YulOps.td b/libsolidity/codegen/mlir/Yul/YulOps.td index b0c30c084..24cb613a0 100644 --- a/libsolidity/codegen/mlir/Yul/YulOps.td +++ b/libsolidity/codegen/mlir/Yul/YulOps.td @@ -78,6 +78,19 @@ def Yul_AddressOp : Yul_Op<"address", [Pure]> { let assemblyFormat = "attr-dict"; } +def Yul_BalanceOp : Yul_Op<"balance"> { + let summary = "Represents the `balance` call in yul"; + let arguments = (ins I256:$addr); + let results = (outs I256:$out); + let assemblyFormat = "$addr attr-dict"; +} + +def Yul_SelfBalanceOp : Yul_Op<"selfbalance"> { + let summary = "Represents the `selfbalance` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + def Yul_CallOp : Yul_Op<"call"> { let summary = "Represents the `call` call in yul"; let arguments = (ins I256:$gas, I256:$address, I256:$value, I256:$inpOffset, @@ -89,6 +102,17 @@ def Yul_CallOp : Yul_Op<"call"> { }]; } +def Yul_CallCodeOp : Yul_Op<"callcode"> { + let summary = "Represents the `callcode` call in yul"; + let arguments = (ins I256:$gas, I256:$address, I256:$value, I256:$inpOffset, + I256:$inpSize, I256:$outOffset, I256:$outSize); + let results = (outs I256:$status); + let assemblyFormat = [{ + $gas `,` $address `,` $value `,` $inpOffset `,` $inpSize `,` $outOffset `,` + $outSize attr-dict + }]; +} + def Yul_StaticCallOp : Yul_Op<"static_call"> { let summary = "Represents the `staticcall` call in yul"; let arguments = (ins I256:$gas, I256:$address, I256:$inpOffset, @@ -161,7 +185,7 @@ def Yul_MCopyOp : Yul_Op<"mcopy"> { let assemblyFormat = "$dst `,` $src `,` $size attr-dict"; } -def Yul_MSizeOp : Yul_Op<"msize", [Pure]> { +def Yul_MSizeOp : Yul_Op<"msize"> { let summary = "Represents the `msize` call in yul"; let results = (outs I256:$out); let assemblyFormat = "attr-dict"; @@ -217,6 +241,19 @@ def Yul_SStoreOp : Yul_Op<"sstore"> { let assemblyFormat = "$addr `,` $val attr-dict"; } +def Yul_TLoadOp : Yul_Op<"tload"> { + let summary = "Represents the `tload` call in yul"; + let arguments = (ins I256:$addr); + let results = (outs I256:$out); + let assemblyFormat = "$addr attr-dict"; +} + +def Yul_TStoreOp : Yul_Op<"tstore"> { + let summary = "Represents the `tstore` call in yul"; + let arguments = (ins I256:$addr, I256:$val); + let assemblyFormat = "$addr `,` $val attr-dict"; +} + // TODO: Support symbolic references to objects outside the current symbol table // (including ones outside the translation unit) using SymbolRefAttr instead of // FlatSymbolRefAttr @@ -247,6 +284,12 @@ def Yul_CodeCopyOp : Yul_Op<"codecopy"> { let assemblyFormat = "$dst `,` $src `,` $size attr-dict"; } +def Yul_ExtCodeCopyOp : Yul_Op<"extcodecopy"> { + let summary = "Represents the `extcodecopy` call in yul"; + let arguments = (ins I256:$addr, I256:$dst, I256:$src, I256:$size); + let assemblyFormat = "$addr `,` $dst `,` $src `,` $size attr-dict"; +} + def Yul_ExtCodeSizeOp : Yul_Op<"extcodesize", [Pure]> { let summary = "Represents the `extcodesize` call in yul"; let arguments = (ins I256:$addr); @@ -254,10 +297,11 @@ def Yul_ExtCodeSizeOp : Yul_Op<"extcodesize", [Pure]> { let assemblyFormat = "$addr attr-dict"; } -def Yul_ExtCodeCopyOp : Yul_Op<"extcodecopy"> { - let summary = "Represents the `extcodecopy` call in yul"; - let arguments = (ins I256:$addr, I256:$dst, I256:$src, I256:$size); - let assemblyFormat = "$addr `,` $dst `,` $src `,` $size attr-dict"; +def Yul_ExtCodeHashOp : Yul_Op<"extcodehash"> { + let summary = "Represents the `extcodehash` call in yul"; + let arguments = (ins I256:$addr); + let results = (outs I256:$out); + let assemblyFormat = "$addr attr-dict"; } def Yul_CreateOp : Yul_Op<"create"> { @@ -274,6 +318,80 @@ def Yul_Create2Op : Yul_Op<"create2"> { let assemblyFormat = "$val `,` $addr `,` $size `,` $salt attr-dict"; } +def Yul_ChainIdOp : Yul_Op<"chainid"> { + let summary = "Represents the `chainid` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_BaseFeeOp : Yul_Op<"basefee"> { + let summary = "Represents the `basefee` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_BlobBaseFeeOp : Yul_Op<"blobbasefee"> { + let summary = "Represents the `blobbasefee` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_OriginOp : Yul_Op<"origin"> { + let summary = "Represents the `origin` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_GasPriceOp : Yul_Op<"gasprice"> { + let summary = "Represents the `gasprice` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_BlockHashOp : Yul_Op<"blockhash"> { + let summary = "Represents the `blockhash` call in yul"; + let arguments = (ins I256:$block); + let results = (outs I256:$out); + let assemblyFormat = "$block attr-dict"; +} + +def Yul_BlobHashOp : Yul_Op<"blobhash"> { + let summary = "Represents the `blobhash` call in yul"; + let arguments = (ins I256:$Idx); + let results = (outs I256:$out); + let assemblyFormat = "$Idx attr-dict"; +} + +def Yul_CoinBaseOp : Yul_Op<"coinbase"> { + let summary = "Represents the `coinbase` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_TimeStampOp : Yul_Op<"timestamp"> { + let summary = "Represents the `timestamp` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_NumberOp : Yul_Op<"number"> { + let summary = "Represents the `number` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_PrevrandaoOp : Yul_Op<"prevrandao"> { + let summary = "Represents the `prevrandao` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + +def Yul_GasLimitOp : Yul_Op<"gaslimit"> { + let summary = "Represents the `gaslimit` call in yul"; + let results = (outs I256:$out); + let assemblyFormat = "attr-dict"; +} + // TODO: Is this `ConstantLike`? Adding it causes "expected ConstantLike op to // be foldable" assert fail (probably due to the missing let hasFolder = 1). def Yul_MemGuardOp : Yul_Op<"memoryguard", [Pure]> { @@ -291,6 +409,76 @@ def Yul_Keccak256Op : Yul_Op<"keccak256"> { let assemblyFormat = "$addr `,` $size attr-dict"; } +def Yul_DivOp : Yul_Op<"div", [Pure]> { + let summary = "Represents the `div` call in yul"; + let arguments = (ins I256:$dividend, I256:$divisor); + let results = (outs I256:$out); + let assemblyFormat = "$dividend `,` $divisor attr-dict"; +} + +def Yul_SDivOp : Yul_Op<"sdiv", [Pure]> { + let summary = "Represents the `sdiv` call in yul"; + let arguments = (ins I256:$dividend, I256:$divisor); + let results = (outs I256:$out); + let assemblyFormat = "$dividend `,` $divisor attr-dict"; +} + +def Yul_ModOp : Yul_Op<"mod", [Pure]> { + let summary = "Represents the `mod` call in yul"; + let arguments = (ins I256:$value, I256:$mod); + let results = (outs I256:$out); + let assemblyFormat = "$value `,` $mod attr-dict"; +} + +def Yul_SModOp : Yul_Op<"smod", [Pure]> { + let summary = "Represents the `smod` call in yul"; + let arguments = (ins I256:$value, I256:$mod); + let results = (outs I256:$out); + let assemblyFormat = "$value `,` $mod attr-dict"; +} + +def Yul_ShlOp : Yul_Op<"shl", [Pure]> { + let summary = "Represents the `shl` call in yul"; + let arguments = (ins I256:$shift, I256:$val); + let results = (outs I256:$out); + let assemblyFormat = "$shift `,` $val attr-dict"; +} + +def Yul_ShrOp : Yul_Op<"shr", [Pure]> { + let summary = "Represents the `shr` call in yul"; + let arguments = (ins I256:$shift, I256:$val); + let results = (outs I256:$out); + let assemblyFormat = "$shift `,` $val attr-dict"; +} + +def Yul_SarOp : Yul_Op<"sar", [Pure]> { + let summary = "Represents the `sar` call in yul"; + let arguments = (ins I256:$shift, I256:$val); + let results = (outs I256:$out); + let assemblyFormat = "$shift `,` $val attr-dict"; +} + +def Yul_ExpOp : Yul_Op<"exp", [Pure]> { + let summary = "Represents the `exp` call in yul"; + let arguments = (ins I256:$base, I256:$exp); + let results = (outs I256:$out); + let assemblyFormat = "$base `,` $exp attr-dict"; +} + +def Yul_AddModOp : Yul_Op<"addmod", [Pure]> { + let summary = "Represents the `addmod` call in yul"; + let arguments = (ins I256:$x, I256:$y, I256:$mod); + let results = (outs I256:$out); + let assemblyFormat = "$x `,` $y `,` $mod attr-dict"; +} + +def Yul_MulModOp : Yul_Op<"mulmod", [Pure]> { + let summary = "Represents the `mulmod` call in yul"; + let arguments = (ins I256:$x, I256:$y, I256:$mod); + let results = (outs I256:$out); + let assemblyFormat = "$x `,` $y `,` $mod attr-dict"; +} + def Yul_LogOp : Yul_Op<"log"> { let summary = "Represents the `log*` calls in yul"; let arguments = (ins I256:$addr, I256:$size, Variadic:$topics); @@ -298,6 +486,13 @@ def Yul_LogOp : Yul_Op<"log"> { let assemblyFormat = "$addr `,` $size oilist(`topics` `(` $topics `)` ) attr-dict"; } +def Yul_SignExtendOp : Yul_Op<"signextend", [Pure]> { + let summary = "Represents the `signextend` call in yul"; + let arguments = (ins I256:$val, I256:$off); + let results = (outs I256:$out); + let assemblyFormat = "$val `,` $off attr-dict"; +} + def Yul_SetImmutableOp : Yul_Op<"setimmutable"> { let summary = "Represents the `setimmutable` call in yul"; let arguments = (ins I256:$addr, StrAttr:$name, I256:$val); diff --git a/libsolidity/codegen/mlir/YulToMLIR.cpp b/libsolidity/codegen/mlir/YulToMLIR.cpp index 2f0b0f7c6..26aac7016 100644 --- a/libsolidity/codegen/mlir/YulToMLIR.cpp +++ b/libsolidity/codegen/mlir/YulToMLIR.cpp @@ -280,9 +280,30 @@ void YulToMLIRPass::populateBuiltinGenMap() { using namespace mlir::yul; defSimpleBuiltinGen("add"); defSimpleBuiltinGen("sub"); - defSimpleBuiltinGen("shr"); + defSimpleBuiltinGen("mul"); + defSimpleBuiltinGen("and"); + defSimpleBuiltinGen("or"); + defSimpleBuiltinGen("xor"); + defSimpleBuiltinGen("div"); + defSimpleBuiltinGen("sdiv"); + defSimpleBuiltinGen("mod"); + defSimpleBuiltinGen("smod"); + defSimpleBuiltinGen("shr"); + defSimpleBuiltinGen("shl"); + defSimpleBuiltinGen("sar"); defCmpBuiltinGen("lt"); defCmpBuiltinGen("slt"); + defCmpBuiltinGen("gt"); + defCmpBuiltinGen("sgt"); + defCmpBuiltinGen("eq"); + builtinGenMap["not"] = [&](std::vector const &args, + mlir::Location loc) { + mlir::SmallVector resVals; + mlirgen::BuilderExt bExt(b, loc); + resVals.push_back(b.create(loc, genDefTyExpr(args[0]), + bExt.genI256Const(-1))); + return resVals; + }; builtinGenMap["iszero"] = [&](std::vector const &args, mlir::Location loc) { mlir::SmallVector resVals; @@ -292,6 +313,13 @@ void YulToMLIRPass::populateBuiltinGenMap() { bExt.genI256Const(0))); return resVals; }; + builtinGenMap["pop"] = [&](std::vector const &args, + mlir::Location loc) { + return mlir::SmallVector{genDefTyExpr(args[0])}; + }; + defSimpleBuiltinGen("addmod"); + defSimpleBuiltinGen("mulmod"); + defSimpleBuiltinGen("signextend"); defSimpleBuiltinGen("mload"); defSimpleBuiltinGenNoRet("loadimmutable"); defSimpleBuiltinGenNoRet("mstore"); @@ -309,19 +337,38 @@ void YulToMLIRPass::populateBuiltinGenMap() { defSimpleBuiltinGen("codesize"); defSimpleBuiltinGen("extcodesize"); defSimpleBuiltinGenNoRet("extcodecopy"); + defSimpleBuiltinGen("extcodehash"); defSimpleBuiltinGen("create"); defSimpleBuiltinGen("create2"); defSimpleBuiltinGen("sload"); defSimpleBuiltinGenNoRet("sstore"); + defSimpleBuiltinGen("tload"); + defSimpleBuiltinGenNoRet("tstore"); defSimpleBuiltinGenNoRet("return"); defSimpleBuiltinGenNoRet("revert"); defSimpleBuiltinGenNoRet("stop"); defSimpleBuiltinGen("keccak256"); + defSimpleBuiltinGen("exp"); defSimpleBuiltinGen("callvalue"); defSimpleBuiltinGen("address"); + defSimpleBuiltinGen("balance"); + defSimpleBuiltinGen("selfbalance"); defSimpleBuiltinGen("caller"); defSimpleBuiltinGen("gas"); + defSimpleBuiltinGen("chainid"); + defSimpleBuiltinGen("basefee"); + defSimpleBuiltinGen("blobbasefee"); + defSimpleBuiltinGen("origin"); + defSimpleBuiltinGen("gasprice"); + defSimpleBuiltinGen("blockhash"); + defSimpleBuiltinGen("blobhash"); + defSimpleBuiltinGen("coinbase"); + defSimpleBuiltinGen("timestamp"); + defSimpleBuiltinGen("number"); + defSimpleBuiltinGen("prevrandao"); + defSimpleBuiltinGen("gaslimit"); defSimpleBuiltinGen("call"); + defSimpleBuiltinGen("callcode"); defSimpleBuiltinGen("staticcall"); defSimpleBuiltinGen("delegatecall"); defSimpleBuiltinGenNoRet("log0"); diff --git a/test/lit/mlirCodegen/EVM/exp.sol b/test/lit/mlirCodegen/EVM/exp.sol new file mode 100644 index 000000000..cbcbaae5f --- /dev/null +++ b/test/lit/mlirCodegen/EVM/exp.sol @@ -0,0 +1,30 @@ +// RUN: solc --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +function power(uint256 base, uint256 exponent) pure returns (uint256) { + unchecked { + return base ** exponent; + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: #loc2 = loc({{.*}}:2:15) +// CHECK-NEXT: #loc3 = loc({{.*}}:2:29) +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @power_15(%arg0: i256 loc({{.*}}:2:15), %arg1: i256 loc({{.*}}:2:29)) -> i256 attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc) +// CHECK-NEXT: %0 = llvm.alloca %c1_i256 x !llvm.ptr : (i256) -> !llvm.ptr loc(#loc2) +// CHECK-NEXT: llvm.store %arg0, %0 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc2) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x !llvm.ptr : (i256) -> !llvm.ptr loc(#loc3) +// CHECK-NEXT: llvm.store %arg1, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %2 = llvm.load %0 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc4) +// CHECK-NEXT: %3 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc5) +// CHECK-NEXT: %4 = "llvm.intrcall"(%2, %3) <{id = 3708 : i32, name = "evm.exp"}> : (i256, i256) -> i256 loc(#loc4) +// CHECK-NEXT: return %4 : i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:2:0) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/balance.yul b/test/lit/mlirCodegen/EVM/yul/balance.yul new file mode 100644 index 000000000..ff78f7934 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/balance.yul @@ -0,0 +1,34 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, balance(mload(0))) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc2) +// CHECK-NEXT: %1 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc2) +// CHECK-NEXT: %2 = "llvm.intrcall"(%1) <{id = 3686 : i32, name = "evm.balance"}> : (i256) -> i256 loc(#loc3) +// CHECK-NEXT: %3 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: %4 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%4, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:22) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/basefee.yul b/test/lit/mlirCodegen/EVM/yul/basefee.yul new file mode 100644 index 000000000..497fb9347 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/basefee.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, basefee()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3687 : i32, name = "evm.basefee"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/blobbasefee.yul b/test/lit/mlirCodegen/EVM/yul/blobbasefee.yul new file mode 100644 index 000000000..d97e16a40 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/blobbasefee.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, blobbasefee()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3688 : i32, name = "evm.blobbasefee"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/blobhash.yul b/test/lit/mlirCodegen/EVM/yul/blobhash.yul new file mode 100644 index 000000000..0fd6292b4 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/blobhash.yul @@ -0,0 +1,33 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, blobhash(1)) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc2) +// CHECK-NEXT: %0 = "llvm.intrcall"(%c1_i256) <{id = 3689 : i32, name = "evm.blobhash"}> : (i256) -> i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:23) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/blockhash.yul b/test/lit/mlirCodegen/EVM/yul/blockhash.yul new file mode 100644 index 000000000..9c1961189 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/blockhash.yul @@ -0,0 +1,33 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, blockhash(1)) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc2) +// CHECK-NEXT: %0 = "llvm.intrcall"(%c1_i256) <{id = 3690 : i32, name = "evm.blockhash"}> : (i256) -> i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:24) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/call.yul b/test/lit/mlirCodegen/EVM/yul/call.yul index 6795c0309..22f8f2a00 100644 --- a/test/lit/mlirCodegen/EVM/yul/call.yul +++ b/test/lit/mlirCodegen/EVM/yul/call.yul @@ -3,6 +3,7 @@ object "Test" { code { let r := call(0, 1, 2, 3, 4, 5, 6) + r := callcode(0, 1, 2, 3, 4, 5, 6) r := staticcall(0, 1, 2, 3, 4, 5) r := delegatecall(0, 1, 2, 3, 4, 5) } @@ -18,30 +19,35 @@ object "Test" { // CHECK-NEXT: %c3_i256 = arith.constant 3 : i256 loc(#loc) // CHECK-NEXT: %c4_i256 = arith.constant 4 : i256 loc(#loc) // CHECK-NEXT: %c5_i256 = arith.constant 5 : i256 loc(#loc) -// CHECK-NEXT: %c6_i256 = arith.constant 6 : i256 loc(#loc1) -// CHECK-NEXT: %0 = llvm.inttoptr %c3_i256 : i256 to !llvm.ptr<1> loc(#loc2) -// CHECK-NEXT: %1 = llvm.inttoptr %c5_i256 : i256 to !llvm.ptr<1> loc(#loc2) -// CHECK-NEXT: %2 = "llvm.intrcall"(%c0_i256, %c1_i256, %c2_i256, %0, %c4_i256, %1, %c6_i256) <{id = 3692 : i32, name = "evm.call"}> : (i256, i256, i256, !llvm.ptr<1>, i256, !llvm.ptr<1>, i256) -> i256 loc(#loc2) -// CHECK-NEXT: %3 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc3) -// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc4) -// CHECK-NEXT: %4 = llvm.inttoptr %c2_i256 : i256 to !llvm.ptr<1> loc(#loc5) -// CHECK-NEXT: %5 = llvm.inttoptr %c4_i256 : i256 to !llvm.ptr<1> loc(#loc5) -// CHECK-NEXT: %6 = "llvm.intrcall"(%c0_i256, %c1_i256, %4, %c3_i256, %5, %c5_i256) <{id = 3747 : i32, name = "evm.staticcall"}> : (i256, i256, !llvm.ptr<1>, i256, !llvm.ptr<1>, i256) -> i256 loc(#loc5) -// CHECK-NEXT: llvm.store %6, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc6) -// CHECK-NEXT: %7 = llvm.inttoptr %c2_i256 : i256 to !llvm.ptr<1> loc(#loc7) -// CHECK-NEXT: %8 = llvm.inttoptr %c4_i256 : i256 to !llvm.ptr<1> loc(#loc7) -// CHECK-NEXT: %9 = "llvm.intrcall"(%c0_i256, %c1_i256, %7, %c3_i256, %8, %c5_i256) <{id = 3705 : i32, name = "evm.delegatecall"}> : (i256, i256, !llvm.ptr<1>, i256, !llvm.ptr<1>, i256) -> i256 loc(#loc7) -// CHECK-NEXT: llvm.store %9, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc8) +// CHECK-NEXT: %c6_i256 = arith.constant 6 : i256 loc(#loc) +// CHECK-NEXT: %0 = llvm.inttoptr %c3_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: %1 = llvm.inttoptr %c5_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: %2 = "llvm.intrcall"(%c0_i256, %c1_i256, %c2_i256, %0, %c4_i256, %1, %c6_i256) <{id = 3692 : i32, name = "evm.call"}> : (i256, i256, i256, !llvm.ptr<1>, i256, !llvm.ptr<1>, i256) -> i256 loc(#loc1) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc2) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %4 = llvm.inttoptr %c3_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: %5 = llvm.inttoptr %c5_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: %6 = "llvm.intrcall"(%c0_i256, %c1_i256, %c2_i256, %4, %c4_i256, %5, %c6_i256) <{id = 3693 : i32, name = "evm.callcode"}> : (i256, i256, i256, !llvm.ptr<1>, i256, !llvm.ptr<1>, i256) -> i256 loc(#loc4) +// CHECK-NEXT: llvm.store %6, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc5) +// CHECK-NEXT: %7 = llvm.inttoptr %c2_i256 : i256 to !llvm.ptr<1> loc(#loc6) +// CHECK-NEXT: %8 = llvm.inttoptr %c4_i256 : i256 to !llvm.ptr<1> loc(#loc6) +// CHECK-NEXT: %9 = "llvm.intrcall"(%c0_i256, %c1_i256, %7, %c3_i256, %8, %c5_i256) <{id = 3747 : i32, name = "evm.staticcall"}> : (i256, i256, !llvm.ptr<1>, i256, !llvm.ptr<1>, i256) -> i256 loc(#loc6) +// CHECK-NEXT: llvm.store %9, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %10 = llvm.inttoptr %c2_i256 : i256 to !llvm.ptr<1> loc(#loc8) +// CHECK-NEXT: %11 = llvm.inttoptr %c4_i256 : i256 to !llvm.ptr<1> loc(#loc8) +// CHECK-NEXT: %12 = "llvm.intrcall"(%c0_i256, %c1_i256, %10, %c3_i256, %11, %c5_i256) <{id = 3705 : i32, name = "evm.delegatecall"}> : (i256, i256, !llvm.ptr<1>, i256, !llvm.ptr<1>, i256) -> i256 loc(#loc8) +// CHECK-NEXT: llvm.store %12, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc9) // CHECK-NEXT: llvm.unreachable loc(#loc) // CHECK-NEXT: } loc(#loc) // CHECK-NEXT: } loc(#loc) // CHECK-NEXT: #loc = loc(unknown) -// CHECK-NEXT: #loc1 = loc({{.*}}:4:36) -// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) -// CHECK-NEXT: #loc3 = loc({{.*}}:4:8) -// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) -// CHECK-NEXT: #loc5 = loc({{.*}}:5:9) -// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) -// CHECK-NEXT: #loc7 = loc({{.*}}:6:9) -// CHECK-NEXT: #loc8 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:9) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc6 = loc({{.*}}:6:9) +// CHECK-NEXT: #loc7 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:7:9) +// CHECK-NEXT: #loc9 = loc({{.*}}:7:4) // CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/chainid.yul b/test/lit/mlirCodegen/EVM/yul/chainid.yul new file mode 100644 index 000000000..e1940e2e4 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/chainid.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, chainid()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3698 : i32, name = "evm.chainid"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/coinbase.yul b/test/lit/mlirCodegen/EVM/yul/coinbase.yul new file mode 100644 index 000000000..128079a44 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/coinbase.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, coinbase()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3700 : i32, name = "evm.coinbase"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/div.yul b/test/lit/mlirCodegen/EVM/yul/div.yul new file mode 100644 index 000000000..84fa26319 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/div.yul @@ -0,0 +1,87 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let a := mload(0) + let b := mload(32) + mstore(64, div(a, b)) + mstore(96, sdiv(a, b)) + mstore(128, mod(a, b)) + mstore(160, smod(a, b)) + return(64, 128) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c160_i256 = arith.constant 160 : i256 loc(#loc) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc) +// CHECK-NEXT: %c96_i256 = arith.constant 96 : i256 loc(#loc) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc2) +// CHECK-NEXT: %0 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %1 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc3) +// CHECK-NEXT: %2 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %1, %2 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc5) +// CHECK-NEXT: %3 = llvm.inttoptr %c32_i256 : i256 to !llvm.ptr<1> loc(#loc6) +// CHECK-NEXT: %4 = llvm.load %3 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc6) +// CHECK-NEXT: %5 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc7) +// CHECK-NEXT: llvm.store %4, %5 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc8) +// CHECK-NEXT: %6 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc9) +// CHECK-NEXT: %7 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %8 = "llvm.intrcall"(%6, %7) <{id = 3707 : i32, name = "evm.div"}> : (i256, i256) -> i256 loc(#loc11) +// CHECK-NEXT: %9 = llvm.inttoptr %c64_i256 : i256 to !llvm.ptr<1> loc(#loc12) +// CHECK-NEXT: llvm.store %8, %9 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc12) +// CHECK-NEXT: %10 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc13) +// CHECK-NEXT: %11 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc14) +// CHECK-NEXT: %12 = "llvm.intrcall"(%10, %11) <{id = 3739 : i32, name = "evm.sdiv"}> : (i256, i256) -> i256 loc(#loc15) +// CHECK-NEXT: %13 = llvm.inttoptr %c96_i256 : i256 to !llvm.ptr<1> loc(#loc16) +// CHECK-NEXT: llvm.store %12, %13 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc16) +// CHECK-NEXT: %14 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc17) +// CHECK-NEXT: %15 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc18) +// CHECK-NEXT: %16 = "llvm.intrcall"(%14, %15) <{id = 3727 : i32, name = "evm.mod"}> : (i256, i256) -> i256 loc(#loc19) +// CHECK-NEXT: %17 = llvm.inttoptr %c128_i256 : i256 to !llvm.ptr<1> loc(#loc20) +// CHECK-NEXT: llvm.store %16, %17 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc20) +// CHECK-NEXT: %18 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc21) +// CHECK-NEXT: %19 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc22) +// CHECK-NEXT: %20 = "llvm.intrcall"(%18, %19) <{id = 3746 : i32, name = "evm.smod"}> : (i256, i256) -> i256 loc(#loc23) +// CHECK-NEXT: %21 = llvm.inttoptr %c160_i256 : i256 to !llvm.ptr<1> loc(#loc24) +// CHECK-NEXT: llvm.store %20, %21 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc24) +// CHECK-NEXT: %22 = llvm.inttoptr %c64_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%22, %c128_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:10:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:19) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:22) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:15) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc13 = loc({{.*}}:7:20) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:23) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:15) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc17 = loc({{.*}}:8:20) +// CHECK-NEXT: #loc18 = loc({{.*}}:8:23) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:16) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:4) +// CHECK-NEXT: #loc21 = loc({{.*}}:9:21) +// CHECK-NEXT: #loc22 = loc({{.*}}:9:24) +// CHECK-NEXT: #loc23 = loc({{.*}}:9:16) +// CHECK-NEXT: #loc24 = loc({{.*}}:9:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/exp.yul b/test/lit/mlirCodegen/EVM/yul/exp.yul new file mode 100644 index 000000000..8f806d4d6 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/exp.yul @@ -0,0 +1,29 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, exp(mload(0), mload(32))) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: %1 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc1) +// CHECK-NEXT: %2 = llvm.inttoptr %c32_i256 : i256 to !llvm.ptr<1> loc(#loc2) +// CHECK-NEXT: %3 = llvm.load %2 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc2) +// CHECK-NEXT: %4 = "llvm.intrcall"(%1, %3) <{id = 3708 : i32, name = "evm.exp"}> : (i256, i256) -> i256 loc(#loc3) +// CHECK-NEXT: %5 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: llvm.store %4, %5 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:18) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:28) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/extcodecopy.yul b/test/lit/mlirCodegen/EVM/yul/extcodecopy.yul new file mode 100644 index 000000000..06e6fc02e --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/extcodecopy.yul @@ -0,0 +1,34 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + extcodecopy(0xaaaaaaaa, 0, 4, 128) + return(0, 128) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c2863311530_i256 = arith.constant 2863311530 : i256 loc(#loc2) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %c4_i256 = arith.constant 4 : i256 loc(#loc3) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc) +// CHECK-NEXT: %0 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: %1 = llvm.inttoptr %c4_i256 : i256 to !llvm.ptr<4> loc(#loc4) +// CHECK-NEXT: "llvm.intrcall"(%c2863311530_i256, %0, %1, %c128_i256) <{id = 3709 : i32, name = "evm.extcodecopy"}> : (i256, !llvm.ptr<1>, !llvm.ptr<4>, i256) -> () loc(#loc4) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c128_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:16) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:31) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/extcodehash.yul b/test/lit/mlirCodegen/EVM/yul/extcodehash.yul new file mode 100644 index 000000000..c87dfbdd8 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/extcodehash.yul @@ -0,0 +1,33 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, extcodehash(0xaaaaaaaa)) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %c2863311530_i256 = arith.constant 2863311530 : i256 loc(#loc2) +// CHECK-NEXT: %0 = "llvm.intrcall"(%c2863311530_i256) <{id = 3710 : i32, name = "evm.extcodehash"}> : (i256) -> i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc4) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:26) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/gaslimit.yul b/test/lit/mlirCodegen/EVM/yul/gaslimit.yul new file mode 100644 index 000000000..27651a4ac --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/gaslimit.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, gaslimit()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3713 : i32, name = "evm.gaslimit"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/gasprice.yul b/test/lit/mlirCodegen/EVM/yul/gasprice.yul new file mode 100644 index 000000000..805368738 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/gasprice.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, gasprice()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3714 : i32, name = "evm.gasprice"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/modops.yul b/test/lit/mlirCodegen/EVM/yul/modops.yul new file mode 100644 index 000000000..51597eaff --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/modops.yul @@ -0,0 +1,75 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let x := mload(0) + let y := mload(32) + let m := mload(64) + mstore(0, addmod(x, y, m)) + mstore(32, mulmod(x, y, m)) + return(0, 64) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc2) +// CHECK-NEXT: %1 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc2) +// CHECK-NEXT: %2 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc3) +// CHECK-NEXT: llvm.store %1, %2 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc4) +// CHECK-NEXT: %3 = llvm.inttoptr %c32_i256 : i256 to !llvm.ptr<1> loc(#loc5) +// CHECK-NEXT: %4 = llvm.load %3 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc5) +// CHECK-NEXT: %5 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc6) +// CHECK-NEXT: llvm.store %4, %5 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %6 = llvm.inttoptr %c64_i256 : i256 to !llvm.ptr<1> loc(#loc8) +// CHECK-NEXT: %7 = llvm.load %6 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc8) +// CHECK-NEXT: %8 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc9) +// CHECK-NEXT: llvm.store %7, %8 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc10) +// CHECK-NEXT: %9 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc11) +// CHECK-NEXT: %10 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc12) +// CHECK-NEXT: %11 = llvm.load %8 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc13) +// CHECK-NEXT: %12 = "llvm.intrcall"(%9, %10, %11) <{id = 3684 : i32, name = "evm.addmod"}> : (i256, i256, i256) -> i256 loc(#loc14) +// CHECK-NEXT: %13 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc15) +// CHECK-NEXT: llvm.store %12, %13 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc15) +// CHECK-NEXT: %14 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc16) +// CHECK-NEXT: %15 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc17) +// CHECK-NEXT: %16 = llvm.load %8 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc18) +// CHECK-NEXT: %17 = "llvm.intrcall"(%14, %15, %16) <{id = 3730 : i32, name = "evm.mulmod"}> : (i256, i256, i256) -> i256 loc(#loc19) +// CHECK-NEXT: %18 = llvm.inttoptr %c32_i256 : i256 to !llvm.ptr<1> loc(#loc20) +// CHECK-NEXT: llvm.store %17, %18 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc20) +// CHECK-NEXT: %19 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%19, %c64_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:9:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:6:13) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:8) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc11 = loc({{.*}}:7:21) +// CHECK-NEXT: #loc12 = loc({{.*}}:7:24) +// CHECK-NEXT: #loc13 = loc({{.*}}:7:27) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:14) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc16 = loc({{.*}}:8:22) +// CHECK-NEXT: #loc17 = loc({{.*}}:8:25) +// CHECK-NEXT: #loc18 = loc({{.*}}:8:28) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:15) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/msize.yul b/test/lit/mlirCodegen/EVM/yul/msize.yul new file mode 100644 index 000000000..594746050 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/msize.yul @@ -0,0 +1,32 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, msize()) + return(0, 32) + } +} + +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3728 : i32, name = "evm.msize"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/number.yul b/test/lit/mlirCodegen/EVM/yul/number.yul new file mode 100644 index 000000000..f6ef214c1 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/number.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, number()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3731 : i32, name = "evm.number"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/origin.yul b/test/lit/mlirCodegen/EVM/yul/origin.yul new file mode 100644 index 000000000..0879c8c8d --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/origin.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, origin()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3732 : i32, name = "evm.origin"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/prevrandao.yul b/test/lit/mlirCodegen/EVM/yul/prevrandao.yul new file mode 100644 index 000000000..022a86a0d --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/prevrandao.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, prevrandao()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3706 : i32, name = "evm.difficulty"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/selfbalance.yul b/test/lit/mlirCodegen/EVM/yul/selfbalance.yul new file mode 100644 index 000000000..f89e56906 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/selfbalance.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, selfbalance()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3740 : i32, name = "evm.selfbalance"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/shifts.yul b/test/lit/mlirCodegen/EVM/yul/shifts.yul new file mode 100644 index 000000000..d7b48ef9f --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/shifts.yul @@ -0,0 +1,76 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let a := mload(0) + let b := mload(32) + mstore(64, shl(a, b)) + mstore(96, shr(a, b)) + mstore(128, sar(a, b)) + return(64, 96) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc) +// CHECK-NEXT: %c96_i256 = arith.constant 96 : i256 loc(#loc) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc2) +// CHECK-NEXT: %0 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %1 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc3) +// CHECK-NEXT: %2 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %1, %2 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc5) +// CHECK-NEXT: %3 = llvm.inttoptr %c32_i256 : i256 to !llvm.ptr<1> loc(#loc6) +// CHECK-NEXT: %4 = llvm.load %3 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc6) +// CHECK-NEXT: %5 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc7) +// CHECK-NEXT: llvm.store %4, %5 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc8) +// CHECK-NEXT: %6 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc9) +// CHECK-NEXT: %7 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %8 = "llvm.intrcall"(%6, %7) <{id = 3743 : i32, name = "evm.shl"}> : (i256, i256) -> i256 loc(#loc11) +// CHECK-NEXT: %9 = llvm.inttoptr %c64_i256 : i256 to !llvm.ptr<1> loc(#loc12) +// CHECK-NEXT: llvm.store %8, %9 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc12) +// CHECK-NEXT: %10 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc13) +// CHECK-NEXT: %11 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc14) +// CHECK-NEXT: %12 = "llvm.intrcall"(%10, %11) <{id = 3744 : i32, name = "evm.shr"}> : (i256, i256) -> i256 loc(#loc15) +// CHECK-NEXT: %13 = llvm.inttoptr %c96_i256 : i256 to !llvm.ptr<1> loc(#loc16) +// CHECK-NEXT: llvm.store %12, %13 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc16) +// CHECK-NEXT: %14 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc17) +// CHECK-NEXT: %15 = llvm.load %2 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc18) +// CHECK-NEXT: %16 = "llvm.intrcall"(%14, %15) <{id = 3738 : i32, name = "evm.sar"}> : (i256, i256) -> i256 loc(#loc19) +// CHECK-NEXT: %17 = llvm.inttoptr %c128_i256 : i256 to !llvm.ptr<1> loc(#loc20) +// CHECK-NEXT: llvm.store %16, %17 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc20) +// CHECK-NEXT: %18 = llvm.inttoptr %c64_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%18, %c96_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:9:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:22) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:19) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:15) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc13 = loc({{.*}}:7:22) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:19) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:15) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc17 = loc({{.*}}:8:23) +// CHECK-NEXT: #loc18 = loc({{.*}}:8:20) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:16) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/signextend.yul b/test/lit/mlirCodegen/EVM/yul/signextend.yul new file mode 100644 index 000000000..44402c8a4 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/signextend.yul @@ -0,0 +1,37 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, signextend(mload(0), mload(32))) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc2) +// CHECK-NEXT: %1 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc2) +// CHECK-NEXT: %2 = llvm.inttoptr %c32_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %3 = llvm.load %2 {alignment = 1 : i64} : !llvm.ptr<1> -> i256 loc(#loc3) +// CHECK-NEXT: %4 = "llvm.intrcall"(%1, %3) <{id = 3745 : i32, name = "evm.signextend"}> : (i256, i256) -> i256 loc(#loc4) +// CHECK-NEXT: %5 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc5) +// CHECK-NEXT: llvm.store %4, %5 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc5) +// CHECK-NEXT: %6 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%6, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:25) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:35) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/timestamp.yul b/test/lit/mlirCodegen/EVM/yul/timestamp.yul new file mode 100644 index 000000000..fe40a6320 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/timestamp.yul @@ -0,0 +1,31 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, timestamp()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @".unreachable"() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: llvm.unreachable loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc) +// CHECK-NEXT: %0 = "llvm.intrcall"() <{id = 3749 : i32, name = "evm.timestamp"}> : () -> i256 loc(#loc2) +// CHECK-NEXT: %1 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 1 : i64} : i256, !llvm.ptr<1> loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<1> loc(#loc1) +// CHECK-NEXT: "llvm.intrcall"(%2, %c32_i256) <{id = 3735 : i32, name = "evm.return"}> : (!llvm.ptr<1>, i256) -> () loc(#loc1) +// CHECK-NEXT: call @".unreachable"() : () -> () loc(#loc1) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/EVM/yul/tstorage.yul b/test/lit/mlirCodegen/EVM/yul/tstorage.yul new file mode 100644 index 000000000..fbd2cab00 --- /dev/null +++ b/test/lit/mlirCodegen/EVM/yul/tstorage.yul @@ -0,0 +1,26 @@ +// RUN: solc --strict-assembly --mlir-action=print-std-mlir --mlir-target=evm --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + tstore(0, tload(1)) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module @Test attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: func.func @__entry() attributes {llvm.linkage = #llvm.linkage, passthrough = ["nofree", "null_pointer_is_valid"]} { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc2) +// CHECK-NEXT: %0 = llvm.inttoptr %c1_i256 : i256 to !llvm.ptr<6> loc(#loc3) +// CHECK-NEXT: %1 = llvm.load %0 {alignment = 1 : i64} : !llvm.ptr<6> -> i256 loc(#loc3) +// CHECK-NEXT: %2 = llvm.inttoptr %c0_i256 : i256 to !llvm.ptr<6> loc(#loc4) +// CHECK-NEXT: llvm.store %1, %2 {alignment = 1 : i64} : i256, !llvm.ptr<6> loc(#loc4) +// CHECK-NEXT: llvm.unreachable loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:20) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/exp.sol b/test/lit/mlirCodegen/exp.sol new file mode 100644 index 000000000..abc6a61a5 --- /dev/null +++ b/test/lit/mlirCodegen/exp.sol @@ -0,0 +1,30 @@ +// RUN: solc --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +function power(uint256 base, uint256 exponent) pure returns (uint256) { + unchecked { + return base ** exponent; + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: #Pure = #sol +// CHECK-NEXT: #loc2 = loc({{.*}}:2:15) +// CHECK-NEXT: #loc3 = loc({{.*}}:2:29) +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: sol.func @power_15(%arg0: ui256 loc({{.*}}:2:15), %arg1: ui256 loc({{.*}}:2:29)) -> ui256 attributes {state_mutability = #Pure} { +// CHECK-NEXT: %0 = sol.alloca : !sol.ptr loc(#loc2) +// CHECK-NEXT: sol.store %arg0, %0 : ui256, !sol.ptr loc(#loc2) +// CHECK-NEXT: %1 = sol.alloca : !sol.ptr loc(#loc3) +// CHECK-NEXT: sol.store %arg1, %1 : ui256, !sol.ptr loc(#loc3) +// CHECK-NEXT: %2 = sol.load %0 : !sol.ptr, ui256 loc(#loc4) +// CHECK-NEXT: %3 = sol.load %1 : !sol.ptr, ui256 loc(#loc5) +// CHECK-NEXT: %4 = sol.exp %2, %3 : ui256 loc(#loc4) +// CHECK-NEXT: sol.return %4 : ui256 loc(#loc6) +// CHECK-NEXT: } loc(#loc1) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:2:0) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/arith.yul b/test/lit/mlirCodegen/yul/arith.yul index e88f1f9af..573a45a38 100644 --- a/test/lit/mlirCodegen/yul/arith.yul +++ b/test/lit/mlirCodegen/yul/arith.yul @@ -2,9 +2,11 @@ object "Test" { code { - let a := add(0, 1) - let b := sub(0, 1) - let c := shr(0, 1) + let a := mload(0) + let b := mload(32) + mstore(64, add(a, b)) + mstore(96, sub(a, b)) + mstore(128, mul(a, b)) } } @@ -13,39 +15,54 @@ object "Test" { // CHECK-NEXT: module attributes {sol.evm_version = #Prague} { // CHECK-NEXT: yul.object @Test { // CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) -// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc2) -// CHECK-NEXT: %0 = arith.addi %c0_i256, %c1_i256 : i256 loc(#loc3) -// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc4) -// CHECK-NEXT: %1 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc5) -// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc4) -// CHECK-NEXT: %c0_i256_1 = arith.constant 0 : i256 loc(#loc6) -// CHECK-NEXT: %c1_i256_2 = arith.constant 1 : i256 loc(#loc7) -// CHECK-NEXT: %2 = arith.subi %c0_i256_1, %c1_i256_2 : i256 loc(#loc8) -// CHECK-NEXT: %c1_i256_3 = arith.constant 1 : i256 loc(#loc9) -// CHECK-NEXT: %3 = llvm.alloca %c1_i256_3 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc10) -// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc9) -// CHECK-NEXT: %c1_i256_4 = arith.constant 1 : i256 loc(#loc11) -// CHECK-NEXT: %c0_i256_5 = arith.constant 0 : i256 loc(#loc12) -// CHECK-NEXT: %4 = arith.shrui %c1_i256_4, %c0_i256_5 : i256 loc(#loc13) -// CHECK-NEXT: %c1_i256_6 = arith.constant 1 : i256 loc(#loc14) -// CHECK-NEXT: %5 = llvm.alloca %c1_i256_6 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc15) -// CHECK-NEXT: llvm.store %4, %5 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc14) +// CHECK-NEXT: %0 = yul.mload %c0_i256 loc(#loc2) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.mload %c32_i256 loc(#loc6) +// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc7) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc8) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc9) +// CHECK-NEXT: %4 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %5 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc11) +// CHECK-NEXT: %6 = arith.addi %4, %5 : i256 loc(#loc12) +// CHECK-NEXT: yul.mstore %c64_i256, %6 loc(#loc13) +// CHECK-NEXT: %c96_i256 = arith.constant 96 : i256 loc(#loc14) +// CHECK-NEXT: %7 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc15) +// CHECK-NEXT: %8 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc16) +// CHECK-NEXT: %9 = arith.subi %7, %8 : i256 loc(#loc17) +// CHECK-NEXT: yul.mstore %c96_i256, %9 loc(#loc18) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc19) +// CHECK-NEXT: %10 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc20) +// CHECK-NEXT: %11 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc21) +// CHECK-NEXT: %12 = arith.muli %10, %11 : i256 loc(#loc22) +// CHECK-NEXT: yul.mstore %c128_i256, %12 loc(#loc23) // CHECK-NEXT: } loc(#loc) // CHECK-NEXT: } loc(#loc) // CHECK-NEXT: #loc = loc(unknown) -// CHECK-NEXT: #loc1 = loc({{.*}}:4:17) -// CHECK-NEXT: #loc2 = loc({{.*}}:4:20) -// CHECK-NEXT: #loc3 = loc({{.*}}:4:13) -// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) -// CHECK-NEXT: #loc5 = loc({{.*}}:4:8) -// CHECK-NEXT: #loc6 = loc({{.*}}:5:17) -// CHECK-NEXT: #loc7 = loc({{.*}}:5:20) -// CHECK-NEXT: #loc8 = loc({{.*}}:5:13) -// CHECK-NEXT: #loc9 = loc({{.*}}:5:4) -// CHECK-NEXT: #loc10 = loc({{.*}}:5:8) -// CHECK-NEXT: #loc11 = loc({{.*}}:6:20) -// CHECK-NEXT: #loc12 = loc({{.*}}:6:17) -// CHECK-NEXT: #loc13 = loc({{.*}}:6:13) -// CHECK-NEXT: #loc14 = loc({{.*}}:6:4) -// CHECK-NEXT: #loc15 = loc({{.*}}:6:8) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:11) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:19) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:22) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:15) +// CHECK-NEXT: #loc13 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:11) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:19) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:22) +// CHECK-NEXT: #loc17 = loc({{.*}}:7:15) +// CHECK-NEXT: #loc18 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:11) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:20) +// CHECK-NEXT: #loc21 = loc({{.*}}:8:23) +// CHECK-NEXT: #loc22 = loc({{.*}}:8:16) +// CHECK-NEXT: #loc23 = loc({{.*}}:8:4) // CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/balance.yul b/test/lit/mlirCodegen/yul/balance.yul new file mode 100644 index 000000000..5c9177093 --- /dev/null +++ b/test/lit/mlirCodegen/yul/balance.yul @@ -0,0 +1,32 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, balance(mload(0))) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc2) +// CHECK-NEXT: %0 = yul.mload %c0_i256_0 loc(#loc3) +// CHECK-NEXT: %1 = yul.balance %0 loc(#loc4) +// CHECK-NEXT: yul.mstore %c0_i256, %1 loc(#loc5) +// CHECK-NEXT: %c0_i256_1 = arith.constant 0 : i256 loc(#loc6) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc7) +// CHECK-NEXT: yul.return %c0_i256_1, %c32_i256 loc(#loc8) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:28) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:22) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/basefee.yul b/test/lit/mlirCodegen/yul/basefee.yul new file mode 100644 index 000000000..81ff9b8e8 --- /dev/null +++ b/test/lit/mlirCodegen/yul/basefee.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, basefee()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.basefee loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/bitwise.yul b/test/lit/mlirCodegen/yul/bitwise.yul new file mode 100644 index 000000000..eee6d19b6 --- /dev/null +++ b/test/lit/mlirCodegen/yul/bitwise.yul @@ -0,0 +1,67 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let a := mload(0) + let b := mload(32) + mstore(64, and(a, b)) + mstore(96, or(a, b)) + mstore(128, xor(a, b)) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.mload %c0_i256 loc(#loc2) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.mload %c32_i256 loc(#loc6) +// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc7) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc8) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc9) +// CHECK-NEXT: %4 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %5 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc11) +// CHECK-NEXT: %6 = arith.andi %4, %5 : i256 loc(#loc12) +// CHECK-NEXT: yul.mstore %c64_i256, %6 loc(#loc13) +// CHECK-NEXT: %c96_i256 = arith.constant 96 : i256 loc(#loc14) +// CHECK-NEXT: %7 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc15) +// CHECK-NEXT: %8 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc16) +// CHECK-NEXT: %9 = arith.ori %7, %8 : i256 loc(#loc17) +// CHECK-NEXT: yul.mstore %c96_i256, %9 loc(#loc18) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc19) +// CHECK-NEXT: %10 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc20) +// CHECK-NEXT: %11 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc21) +// CHECK-NEXT: %12 = arith.xori %10, %11 : i256 loc(#loc22) +// CHECK-NEXT: yul.mstore %c128_i256, %12 loc(#loc23) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:11) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:19) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:22) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:15) +// CHECK-NEXT: #loc13 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:11) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:18) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:21) +// CHECK-NEXT: #loc17 = loc({{.*}}:7:15) +// CHECK-NEXT: #loc18 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:11) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:20) +// CHECK-NEXT: #loc21 = loc({{.*}}:8:23) +// CHECK-NEXT: #loc22 = loc({{.*}}:8:16) +// CHECK-NEXT: #loc23 = loc({{.*}}:8:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/blobbasefee.yul b/test/lit/mlirCodegen/yul/blobbasefee.yul new file mode 100644 index 000000000..1ce26ab98 --- /dev/null +++ b/test/lit/mlirCodegen/yul/blobbasefee.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, blobbasefee()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.blobbasefee loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/blobhash.yul b/test/lit/mlirCodegen/yul/blobhash.yul new file mode 100644 index 000000000..833c072d5 --- /dev/null +++ b/test/lit/mlirCodegen/yul/blobhash.yul @@ -0,0 +1,30 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, blobhash(1)) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc2) +// CHECK-NEXT: %0 = yul.blobhash %c1_i256 loc(#loc3) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc4) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc5) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc6) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc7) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:23) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/blockhash.yul b/test/lit/mlirCodegen/yul/blockhash.yul new file mode 100644 index 000000000..6d5f08f51 --- /dev/null +++ b/test/lit/mlirCodegen/yul/blockhash.yul @@ -0,0 +1,30 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, blockhash(1)) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc2) +// CHECK-NEXT: %0 = yul.blockhash %c1_i256 loc(#loc3) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc4) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc5) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc6) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc7) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:24) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/call.yul b/test/lit/mlirCodegen/yul/call.yul index b5892a7d9..ebe6633d4 100644 --- a/test/lit/mlirCodegen/yul/call.yul +++ b/test/lit/mlirCodegen/yul/call.yul @@ -3,6 +3,7 @@ object "Test" { code { let r := call(0, 1, 2, 3, 4, 5, 6) + r := callcode(0, 1, 2, 3, 4, 5, 6) r := staticcall(0, 1, 2, 3, 4, 5) r := delegatecall(0, 1, 2, 3, 4, 5) } @@ -29,16 +30,25 @@ object "Test" { // CHECK-NEXT: %c3_i256_4 = arith.constant 3 : i256 loc(#loc14) // CHECK-NEXT: %c4_i256_5 = arith.constant 4 : i256 loc(#loc15) // CHECK-NEXT: %c5_i256_6 = arith.constant 5 : i256 loc(#loc16) -// CHECK-NEXT: %2 = yul.static_call %c0_i256_1, %c1_i256_2, %c2_i256_3, %c3_i256_4, %c4_i256_5, %c5_i256_6 loc(#loc17) -// CHECK-NEXT: llvm.store %2, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc18) -// CHECK-NEXT: %c0_i256_7 = arith.constant 0 : i256 loc(#loc19) -// CHECK-NEXT: %c1_i256_8 = arith.constant 1 : i256 loc(#loc20) -// CHECK-NEXT: %c2_i256_9 = arith.constant 2 : i256 loc(#loc21) -// CHECK-NEXT: %c3_i256_10 = arith.constant 3 : i256 loc(#loc22) -// CHECK-NEXT: %c4_i256_11 = arith.constant 4 : i256 loc(#loc23) -// CHECK-NEXT: %c5_i256_12 = arith.constant 5 : i256 loc(#loc24) -// CHECK-NEXT: %3 = yul.delegate_call %c0_i256_7, %c1_i256_8, %c2_i256_9, %c3_i256_10, %c4_i256_11, %c5_i256_12 loc(#loc25) -// CHECK-NEXT: llvm.store %3, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc26) +// CHECK-NEXT: %c6_i256_7 = arith.constant 6 : i256 loc(#loc17) +// CHECK-NEXT: %2 = yul.callcode %c0_i256_1, %c1_i256_2, %c2_i256_3, %c3_i256_4, %c4_i256_5, %c5_i256_6, %c6_i256_7 loc(#loc18) +// CHECK-NEXT: llvm.store %2, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc19) +// CHECK-NEXT: %c0_i256_8 = arith.constant 0 : i256 loc(#loc20) +// CHECK-NEXT: %c1_i256_9 = arith.constant 1 : i256 loc(#loc21) +// CHECK-NEXT: %c2_i256_10 = arith.constant 2 : i256 loc(#loc22) +// CHECK-NEXT: %c3_i256_11 = arith.constant 3 : i256 loc(#loc23) +// CHECK-NEXT: %c4_i256_12 = arith.constant 4 : i256 loc(#loc24) +// CHECK-NEXT: %c5_i256_13 = arith.constant 5 : i256 loc(#loc25) +// CHECK-NEXT: %3 = yul.static_call %c0_i256_8, %c1_i256_9, %c2_i256_10, %c3_i256_11, %c4_i256_12, %c5_i256_13 loc(#loc26) +// CHECK-NEXT: llvm.store %3, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc27) +// CHECK-NEXT: %c0_i256_14 = arith.constant 0 : i256 loc(#loc28) +// CHECK-NEXT: %c1_i256_15 = arith.constant 1 : i256 loc(#loc29) +// CHECK-NEXT: %c2_i256_16 = arith.constant 2 : i256 loc(#loc30) +// CHECK-NEXT: %c3_i256_17 = arith.constant 3 : i256 loc(#loc31) +// CHECK-NEXT: %c4_i256_18 = arith.constant 4 : i256 loc(#loc32) +// CHECK-NEXT: %c5_i256_19 = arith.constant 5 : i256 loc(#loc33) +// CHECK-NEXT: %4 = yul.delegate_call %c0_i256_14, %c1_i256_15, %c2_i256_16, %c3_i256_17, %c4_i256_18, %c5_i256_19 loc(#loc34) +// CHECK-NEXT: llvm.store %4, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc35) // CHECK-NEXT: } loc(#loc) // CHECK-NEXT: } loc(#loc) // CHECK-NEXT: #loc = loc(unknown) @@ -52,20 +62,29 @@ object "Test" { // CHECK-NEXT: #loc8 = loc({{.*}}:4:13) // CHECK-NEXT: #loc9 = loc({{.*}}:4:4) // CHECK-NEXT: #loc10 = loc({{.*}}:4:8) -// CHECK-NEXT: #loc11 = loc({{.*}}:5:20) -// CHECK-NEXT: #loc12 = loc({{.*}}:5:23) -// CHECK-NEXT: #loc13 = loc({{.*}}:5:26) -// CHECK-NEXT: #loc14 = loc({{.*}}:5:29) -// CHECK-NEXT: #loc15 = loc({{.*}}:5:32) -// CHECK-NEXT: #loc16 = loc({{.*}}:5:35) -// CHECK-NEXT: #loc17 = loc({{.*}}:5:9) -// CHECK-NEXT: #loc18 = loc({{.*}}:5:4) -// CHECK-NEXT: #loc19 = loc({{.*}}:6:22) -// CHECK-NEXT: #loc20 = loc({{.*}}:6:25) -// CHECK-NEXT: #loc21 = loc({{.*}}:6:28) -// CHECK-NEXT: #loc22 = loc({{.*}}:6:31) -// CHECK-NEXT: #loc23 = loc({{.*}}:6:34) -// CHECK-NEXT: #loc24 = loc({{.*}}:6:37) -// CHECK-NEXT: #loc25 = loc({{.*}}:6:9) -// CHECK-NEXT: #loc26 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc11 = loc({{.*}}:5:18) +// CHECK-NEXT: #loc12 = loc({{.*}}:5:21) +// CHECK-NEXT: #loc13 = loc({{.*}}:5:24) +// CHECK-NEXT: #loc14 = loc({{.*}}:5:27) +// CHECK-NEXT: #loc15 = loc({{.*}}:5:30) +// CHECK-NEXT: #loc16 = loc({{.*}}:5:33) +// CHECK-NEXT: #loc17 = loc({{.*}}:5:36) +// CHECK-NEXT: #loc18 = loc({{.*}}:5:9) +// CHECK-NEXT: #loc19 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc20 = loc({{.*}}:6:20) +// CHECK-NEXT: #loc21 = loc({{.*}}:6:23) +// CHECK-NEXT: #loc22 = loc({{.*}}:6:26) +// CHECK-NEXT: #loc23 = loc({{.*}}:6:29) +// CHECK-NEXT: #loc24 = loc({{.*}}:6:32) +// CHECK-NEXT: #loc25 = loc({{.*}}:6:35) +// CHECK-NEXT: #loc26 = loc({{.*}}:6:9) +// CHECK-NEXT: #loc27 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc28 = loc({{.*}}:7:22) +// CHECK-NEXT: #loc29 = loc({{.*}}:7:25) +// CHECK-NEXT: #loc30 = loc({{.*}}:7:28) +// CHECK-NEXT: #loc31 = loc({{.*}}:7:31) +// CHECK-NEXT: #loc32 = loc({{.*}}:7:34) +// CHECK-NEXT: #loc33 = loc({{.*}}:7:37) +// CHECK-NEXT: #loc34 = loc({{.*}}:7:9) +// CHECK-NEXT: #loc35 = loc({{.*}}:7:4) // CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/chainid.yul b/test/lit/mlirCodegen/yul/chainid.yul new file mode 100644 index 000000000..ca03cdce2 --- /dev/null +++ b/test/lit/mlirCodegen/yul/chainid.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, chainid()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.chainid loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/cmp.yul b/test/lit/mlirCodegen/yul/cmp.yul new file mode 100644 index 000000000..53d93ded9 --- /dev/null +++ b/test/lit/mlirCodegen/yul/cmp.yul @@ -0,0 +1,369 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo --mlir-target=eravm %s | FileCheck %s + +object "Test" { + code { + let a := mload(32) + let b := mload(64) + if lt(a, b) { + mstore(0, 0) + } + mstore(0, lt(a, b)) + if slt(a, b) { + mstore(0, 0) + } + mstore(0, slt(a, b)) + if iszero(a) { + mstore(1, 0) + } + mstore(1, iszero(a)) + return(0, 0) + } + object "Test_deployed" { + code { + let a := mload(32) + let b := mload(64) + if lt(a, b) { + mstore(0, 0) + } + mstore(0, lt(a, b)) + if slt(a, b) { + mstore(0, 0) + } + mstore(0, slt(a, b)) + if iszero(a) { + mstore(1, 0) + } + + if gt(a, b) { + mstore(7, 0) + } + mstore(0, gt(a, b)) + if sgt(a, b) { + mstore(96, 0) + } + mstore(128, sgt(b, a)) + mstore(96, eq(a, b)) + if eq(a, 33) { + mstore(3, 0) + } + mstore(16, not(a)) + mstore(1, iszero(a)) + return(0, 0) + } + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.mload %c32_i256 loc(#loc2) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.mload %c64_i256 loc(#loc6) +// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc7) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc8) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %4 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc9) +// CHECK-NEXT: %5 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %6 = arith.cmpi ult, %4, %5 : i256 loc(#loc11) +// CHECK-NEXT: sol.if %6 { +// CHECK-NEXT: %c0_i256_7 = arith.constant 0 : i256 loc(#loc13) +// CHECK-NEXT: %c0_i256_8 = arith.constant 0 : i256 loc(#loc14) +// CHECK-NEXT: yul.mstore %c0_i256_7, %c0_i256_8 loc(#loc15) +// CHECK-NEXT: sol.yield loc(#loc12) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc12) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc16) +// CHECK-NEXT: %7 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc17) +// CHECK-NEXT: %8 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc18) +// CHECK-NEXT: %9 = arith.cmpi ult, %7, %8 : i256 loc(#loc19) +// CHECK-NEXT: %10 = arith.extui %9 : i1 to i256 loc(#loc19) +// CHECK-NEXT: yul.mstore %c0_i256, %10 loc(#loc20) +// CHECK-NEXT: %11 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc21) +// CHECK-NEXT: %12 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc22) +// CHECK-NEXT: %13 = arith.cmpi slt, %11, %12 : i256 loc(#loc23) +// CHECK-NEXT: sol.if %13 { +// CHECK-NEXT: %c0_i256_7 = arith.constant 0 : i256 loc(#loc25) +// CHECK-NEXT: %c0_i256_8 = arith.constant 0 : i256 loc(#loc26) +// CHECK-NEXT: yul.mstore %c0_i256_7, %c0_i256_8 loc(#loc27) +// CHECK-NEXT: sol.yield loc(#loc24) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc24) +// CHECK-NEXT: %c0_i256_1 = arith.constant 0 : i256 loc(#loc28) +// CHECK-NEXT: %14 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc29) +// CHECK-NEXT: %15 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc30) +// CHECK-NEXT: %16 = arith.cmpi slt, %14, %15 : i256 loc(#loc31) +// CHECK-NEXT: %17 = arith.extui %16 : i1 to i256 loc(#loc31) +// CHECK-NEXT: yul.mstore %c0_i256_1, %17 loc(#loc32) +// CHECK-NEXT: %18 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc33) +// CHECK-NEXT: %c0_i256_2 = arith.constant 0 : i256 loc(#loc34) +// CHECK-NEXT: %19 = arith.cmpi eq, %18, %c0_i256_2 : i256 loc(#loc34) +// CHECK-NEXT: sol.if %19 { +// CHECK-NEXT: %c1_i256_7 = arith.constant 1 : i256 loc(#loc36) +// CHECK-NEXT: %c0_i256_8 = arith.constant 0 : i256 loc(#loc37) +// CHECK-NEXT: yul.mstore %c1_i256_7, %c0_i256_8 loc(#loc38) +// CHECK-NEXT: sol.yield loc(#loc35) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc35) +// CHECK-NEXT: %c1_i256_3 = arith.constant 1 : i256 loc(#loc39) +// CHECK-NEXT: %20 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc40) +// CHECK-NEXT: %c0_i256_4 = arith.constant 0 : i256 loc(#loc41) +// CHECK-NEXT: %21 = arith.cmpi eq, %20, %c0_i256_4 : i256 loc(#loc41) +// CHECK-NEXT: %22 = arith.extui %21 : i1 to i256 loc(#loc41) +// CHECK-NEXT: yul.mstore %c1_i256_3, %22 loc(#loc42) +// CHECK-NEXT: %c0_i256_5 = arith.constant 0 : i256 loc(#loc43) +// CHECK-NEXT: %c0_i256_6 = arith.constant 0 : i256 loc(#loc44) +// CHECK-NEXT: yul.return %c0_i256_5, %c0_i256_6 loc(#loc45) +// CHECK-NEXT: yul.object @Test_deployed { +// CHECK-NEXT: %c32_i256_7 = arith.constant 32 : i256 loc(#loc46) +// CHECK-NEXT: %23 = yul.mload %c32_i256_7 loc(#loc47) +// CHECK-NEXT: %c1_i256_8 = arith.constant 1 : i256 loc(#loc48) +// CHECK-NEXT: %24 = llvm.alloca %c1_i256_8 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc49) +// CHECK-NEXT: llvm.store %23, %24 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc48) +// CHECK-NEXT: %c64_i256_9 = arith.constant 64 : i256 loc(#loc50) +// CHECK-NEXT: %25 = yul.mload %c64_i256_9 loc(#loc51) +// CHECK-NEXT: %c1_i256_10 = arith.constant 1 : i256 loc(#loc52) +// CHECK-NEXT: %26 = llvm.alloca %c1_i256_10 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc53) +// CHECK-NEXT: llvm.store %25, %26 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc52) +// CHECK-NEXT: %27 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc54) +// CHECK-NEXT: %28 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc55) +// CHECK-NEXT: %29 = arith.cmpi ult, %27, %28 : i256 loc(#loc56) +// CHECK-NEXT: sol.if %29 { +// CHECK-NEXT: %c0_i256_19 = arith.constant 0 : i256 loc(#loc58) +// CHECK-NEXT: %c0_i256_20 = arith.constant 0 : i256 loc(#loc59) +// CHECK-NEXT: yul.mstore %c0_i256_19, %c0_i256_20 loc(#loc60) +// CHECK-NEXT: sol.yield loc(#loc57) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc57) +// CHECK-NEXT: %c0_i256_11 = arith.constant 0 : i256 loc(#loc61) +// CHECK-NEXT: %30 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc62) +// CHECK-NEXT: %31 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc63) +// CHECK-NEXT: %32 = arith.cmpi ult, %30, %31 : i256 loc(#loc64) +// CHECK-NEXT: %33 = arith.extui %32 : i1 to i256 loc(#loc64) +// CHECK-NEXT: yul.mstore %c0_i256_11, %33 loc(#loc65) +// CHECK-NEXT: %34 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc66) +// CHECK-NEXT: %35 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc67) +// CHECK-NEXT: %36 = arith.cmpi slt, %34, %35 : i256 loc(#loc68) +// CHECK-NEXT: sol.if %36 { +// CHECK-NEXT: %c0_i256_19 = arith.constant 0 : i256 loc(#loc70) +// CHECK-NEXT: %c0_i256_20 = arith.constant 0 : i256 loc(#loc71) +// CHECK-NEXT: yul.mstore %c0_i256_19, %c0_i256_20 loc(#loc72) +// CHECK-NEXT: sol.yield loc(#loc69) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc69) +// CHECK-NEXT: %c0_i256_12 = arith.constant 0 : i256 loc(#loc73) +// CHECK-NEXT: %37 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc74) +// CHECK-NEXT: %38 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc75) +// CHECK-NEXT: %39 = arith.cmpi slt, %37, %38 : i256 loc(#loc76) +// CHECK-NEXT: %40 = arith.extui %39 : i1 to i256 loc(#loc76) +// CHECK-NEXT: yul.mstore %c0_i256_12, %40 loc(#loc77) +// CHECK-NEXT: %41 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc78) +// CHECK-NEXT: %c0_i256_13 = arith.constant 0 : i256 loc(#loc79) +// CHECK-NEXT: %42 = arith.cmpi eq, %41, %c0_i256_13 : i256 loc(#loc79) +// CHECK-NEXT: sol.if %42 { +// CHECK-NEXT: %c1_i256_19 = arith.constant 1 : i256 loc(#loc81) +// CHECK-NEXT: %c0_i256_20 = arith.constant 0 : i256 loc(#loc82) +// CHECK-NEXT: yul.mstore %c1_i256_19, %c0_i256_20 loc(#loc83) +// CHECK-NEXT: sol.yield loc(#loc80) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc80) +// CHECK-NEXT: %43 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc84) +// CHECK-NEXT: %44 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc85) +// CHECK-NEXT: %45 = arith.cmpi ugt, %43, %44 : i256 loc(#loc86) +// CHECK-NEXT: sol.if %45 { +// CHECK-NEXT: %c7_i256 = arith.constant 7 : i256 loc(#loc88) +// CHECK-NEXT: %c0_i256_19 = arith.constant 0 : i256 loc(#loc89) +// CHECK-NEXT: yul.mstore %c7_i256, %c0_i256_19 loc(#loc90) +// CHECK-NEXT: sol.yield loc(#loc87) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc87) +// CHECK-NEXT: %c0_i256_14 = arith.constant 0 : i256 loc(#loc91) +// CHECK-NEXT: %46 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc92) +// CHECK-NEXT: %47 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc93) +// CHECK-NEXT: %48 = arith.cmpi ugt, %46, %47 : i256 loc(#loc94) +// CHECK-NEXT: %49 = arith.extui %48 : i1 to i256 loc(#loc94) +// CHECK-NEXT: yul.mstore %c0_i256_14, %49 loc(#loc95) +// CHECK-NEXT: %50 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc96) +// CHECK-NEXT: %51 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc97) +// CHECK-NEXT: %52 = arith.cmpi sgt, %50, %51 : i256 loc(#loc98) +// CHECK-NEXT: sol.if %52 { +// CHECK-NEXT: %c96_i256_19 = arith.constant 96 : i256 loc(#loc100) +// CHECK-NEXT: %c0_i256_20 = arith.constant 0 : i256 loc(#loc101) +// CHECK-NEXT: yul.mstore %c96_i256_19, %c0_i256_20 loc(#loc102) +// CHECK-NEXT: sol.yield loc(#loc99) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc99) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc103) +// CHECK-NEXT: %53 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc104) +// CHECK-NEXT: %54 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc105) +// CHECK-NEXT: %55 = arith.cmpi sgt, %53, %54 : i256 loc(#loc106) +// CHECK-NEXT: %56 = arith.extui %55 : i1 to i256 loc(#loc106) +// CHECK-NEXT: yul.mstore %c128_i256, %56 loc(#loc107) +// CHECK-NEXT: %c96_i256 = arith.constant 96 : i256 loc(#loc108) +// CHECK-NEXT: %57 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc109) +// CHECK-NEXT: %58 = llvm.load %26 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc110) +// CHECK-NEXT: %59 = arith.cmpi eq, %57, %58 : i256 loc(#loc111) +// CHECK-NEXT: %60 = arith.extui %59 : i1 to i256 loc(#loc111) +// CHECK-NEXT: yul.mstore %c96_i256, %60 loc(#loc112) +// CHECK-NEXT: %61 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc113) +// CHECK-NEXT: %c33_i256 = arith.constant 33 : i256 loc(#loc114) +// CHECK-NEXT: %62 = arith.cmpi eq, %61, %c33_i256 : i256 loc(#loc115) +// CHECK-NEXT: sol.if %62 { +// CHECK-NEXT: %c3_i256 = arith.constant 3 : i256 loc(#loc117) +// CHECK-NEXT: %c0_i256_19 = arith.constant 0 : i256 loc(#loc118) +// CHECK-NEXT: yul.mstore %c3_i256, %c0_i256_19 loc(#loc119) +// CHECK-NEXT: sol.yield loc(#loc116) +// CHECK-NEXT: } else { +// CHECK-NEXT: } loc(#loc116) +// CHECK-NEXT: %c16_i256 = arith.constant 16 : i256 loc(#loc120) +// CHECK-NEXT: %63 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc121) +// CHECK-NEXT: %c-1_i256 = arith.constant -1 : i256 loc(#loc122) +// CHECK-NEXT: %64 = arith.xori %63, %c-1_i256 : i256 loc(#loc122) +// CHECK-NEXT: yul.mstore %c16_i256, %64 loc(#loc123) +// CHECK-NEXT: %c1_i256_15 = arith.constant 1 : i256 loc(#loc124) +// CHECK-NEXT: %65 = llvm.load %24 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc125) +// CHECK-NEXT: %c0_i256_16 = arith.constant 0 : i256 loc(#loc126) +// CHECK-NEXT: %66 = arith.cmpi eq, %65, %c0_i256_16 : i256 loc(#loc126) +// CHECK-NEXT: %67 = arith.extui %66 : i1 to i256 loc(#loc126) +// CHECK-NEXT: yul.mstore %c1_i256_15, %67 loc(#loc127) +// CHECK-NEXT: %c0_i256_17 = arith.constant 0 : i256 loc(#loc128) +// CHECK-NEXT: %c0_i256_18 = arith.constant 0 : i256 loc(#loc129) +// CHECK-NEXT: yul.return %c0_i256_17, %c0_i256_18 loc(#loc130) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:10) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:13) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:7) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc13 = loc({{.*}}:7:13) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:16) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:6) +// CHECK-NEXT: #loc16 = loc({{.*}}:9:11) +// CHECK-NEXT: #loc17 = loc({{.*}}:9:17) +// CHECK-NEXT: #loc18 = loc({{.*}}:9:20) +// CHECK-NEXT: #loc19 = loc({{.*}}:9:14) +// CHECK-NEXT: #loc20 = loc({{.*}}:9:4) +// CHECK-NEXT: #loc21 = loc({{.*}}:10:11) +// CHECK-NEXT: #loc22 = loc({{.*}}:10:14) +// CHECK-NEXT: #loc23 = loc({{.*}}:10:7) +// CHECK-NEXT: #loc24 = loc({{.*}}:10:4) +// CHECK-NEXT: #loc25 = loc({{.*}}:11:13) +// CHECK-NEXT: #loc26 = loc({{.*}}:11:16) +// CHECK-NEXT: #loc27 = loc({{.*}}:11:6) +// CHECK-NEXT: #loc28 = loc({{.*}}:13:11) +// CHECK-NEXT: #loc29 = loc({{.*}}:13:18) +// CHECK-NEXT: #loc30 = loc({{.*}}:13:21) +// CHECK-NEXT: #loc31 = loc({{.*}}:13:14) +// CHECK-NEXT: #loc32 = loc({{.*}}:13:4) +// CHECK-NEXT: #loc33 = loc({{.*}}:14:14) +// CHECK-NEXT: #loc34 = loc({{.*}}:14:7) +// CHECK-NEXT: #loc35 = loc({{.*}}:14:4) +// CHECK-NEXT: #loc36 = loc({{.*}}:15:13) +// CHECK-NEXT: #loc37 = loc({{.*}}:15:16) +// CHECK-NEXT: #loc38 = loc({{.*}}:15:6) +// CHECK-NEXT: #loc39 = loc({{.*}}:17:11) +// CHECK-NEXT: #loc40 = loc({{.*}}:17:21) +// CHECK-NEXT: #loc41 = loc({{.*}}:17:14) +// CHECK-NEXT: #loc42 = loc({{.*}}:17:4) +// CHECK-NEXT: #loc43 = loc({{.*}}:18:11) +// CHECK-NEXT: #loc44 = loc({{.*}}:18:14) +// CHECK-NEXT: #loc45 = loc({{.*}}:18:4) +// CHECK-NEXT: #loc46 = loc({{.*}}:22:21) +// CHECK-NEXT: #loc47 = loc({{.*}}:22:15) +// CHECK-NEXT: #loc48 = loc({{.*}}:22:6) +// CHECK-NEXT: #loc49 = loc({{.*}}:22:10) +// CHECK-NEXT: #loc50 = loc({{.*}}:23:21) +// CHECK-NEXT: #loc51 = loc({{.*}}:23:15) +// CHECK-NEXT: #loc52 = loc({{.*}}:23:6) +// CHECK-NEXT: #loc53 = loc({{.*}}:23:10) +// CHECK-NEXT: #loc54 = loc({{.*}}:24:12) +// CHECK-NEXT: #loc55 = loc({{.*}}:24:15) +// CHECK-NEXT: #loc56 = loc({{.*}}:24:9) +// CHECK-NEXT: #loc57 = loc({{.*}}:24:6) +// CHECK-NEXT: #loc58 = loc({{.*}}:25:15) +// CHECK-NEXT: #loc59 = loc({{.*}}:25:18) +// CHECK-NEXT: #loc60 = loc({{.*}}:25:8) +// CHECK-NEXT: #loc61 = loc({{.*}}:27:13) +// CHECK-NEXT: #loc62 = loc({{.*}}:27:19) +// CHECK-NEXT: #loc63 = loc({{.*}}:27:22) +// CHECK-NEXT: #loc64 = loc({{.*}}:27:16) +// CHECK-NEXT: #loc65 = loc({{.*}}:27:6) +// CHECK-NEXT: #loc66 = loc({{.*}}:28:13) +// CHECK-NEXT: #loc67 = loc({{.*}}:28:16) +// CHECK-NEXT: #loc68 = loc({{.*}}:28:9) +// CHECK-NEXT: #loc69 = loc({{.*}}:28:6) +// CHECK-NEXT: #loc70 = loc({{.*}}:29:15) +// CHECK-NEXT: #loc71 = loc({{.*}}:29:18) +// CHECK-NEXT: #loc72 = loc({{.*}}:29:8) +// CHECK-NEXT: #loc73 = loc({{.*}}:31:13) +// CHECK-NEXT: #loc74 = loc({{.*}}:31:20) +// CHECK-NEXT: #loc75 = loc({{.*}}:31:23) +// CHECK-NEXT: #loc76 = loc({{.*}}:31:16) +// CHECK-NEXT: #loc77 = loc({{.*}}:31:6) +// CHECK-NEXT: #loc78 = loc({{.*}}:32:16) +// CHECK-NEXT: #loc79 = loc({{.*}}:32:9) +// CHECK-NEXT: #loc80 = loc({{.*}}:32:6) +// CHECK-NEXT: #loc81 = loc({{.*}}:33:15) +// CHECK-NEXT: #loc82 = loc({{.*}}:33:18) +// CHECK-NEXT: #loc83 = loc({{.*}}:33:8) +// CHECK-NEXT: #loc84 = loc({{.*}}:36:12) +// CHECK-NEXT: #loc85 = loc({{.*}}:36:15) +// CHECK-NEXT: #loc86 = loc({{.*}}:36:9) +// CHECK-NEXT: #loc87 = loc({{.*}}:36:6) +// CHECK-NEXT: #loc88 = loc({{.*}}:37:15) +// CHECK-NEXT: #loc89 = loc({{.*}}:37:18) +// CHECK-NEXT: #loc90 = loc({{.*}}:37:8) +// CHECK-NEXT: #loc91 = loc({{.*}}:39:13) +// CHECK-NEXT: #loc92 = loc({{.*}}:39:19) +// CHECK-NEXT: #loc93 = loc({{.*}}:39:22) +// CHECK-NEXT: #loc94 = loc({{.*}}:39:16) +// CHECK-NEXT: #loc95 = loc({{.*}}:39:6) +// CHECK-NEXT: #loc96 = loc({{.*}}:40:13) +// CHECK-NEXT: #loc97 = loc({{.*}}:40:16) +// CHECK-NEXT: #loc98 = loc({{.*}}:40:9) +// CHECK-NEXT: #loc99 = loc({{.*}}:40:6) +// CHECK-NEXT: #loc100 = loc({{.*}}:41:15) +// CHECK-NEXT: #loc101 = loc({{.*}}:41:19) +// CHECK-NEXT: #loc102 = loc({{.*}}:41:8) +// CHECK-NEXT: #loc103 = loc({{.*}}:43:13) +// CHECK-NEXT: #loc104 = loc({{.*}}:43:22) +// CHECK-NEXT: #loc105 = loc({{.*}}:43:25) +// CHECK-NEXT: #loc106 = loc({{.*}}:43:18) +// CHECK-NEXT: #loc107 = loc({{.*}}:43:6) +// CHECK-NEXT: #loc108 = loc({{.*}}:44:13) +// CHECK-NEXT: #loc109 = loc({{.*}}:44:20) +// CHECK-NEXT: #loc110 = loc({{.*}}:44:23) +// CHECK-NEXT: #loc111 = loc({{.*}}:44:17) +// CHECK-NEXT: #loc112 = loc({{.*}}:44:6) +// CHECK-NEXT: #loc113 = loc({{.*}}:45:12) +// CHECK-NEXT: #loc114 = loc({{.*}}:45:15) +// CHECK-NEXT: #loc115 = loc({{.*}}:45:9) +// CHECK-NEXT: #loc116 = loc({{.*}}:45:6) +// CHECK-NEXT: #loc117 = loc({{.*}}:46:15) +// CHECK-NEXT: #loc118 = loc({{.*}}:46:18) +// CHECK-NEXT: #loc119 = loc({{.*}}:46:8) +// CHECK-NEXT: #loc120 = loc({{.*}}:48:13) +// CHECK-NEXT: #loc121 = loc({{.*}}:48:21) +// CHECK-NEXT: #loc122 = loc({{.*}}:48:17) +// CHECK-NEXT: #loc123 = loc({{.*}}:48:6) +// CHECK-NEXT: #loc124 = loc({{.*}}:49:13) +// CHECK-NEXT: #loc125 = loc({{.*}}:49:23) +// CHECK-NEXT: #loc126 = loc({{.*}}:49:16) +// CHECK-NEXT: #loc127 = loc({{.*}}:49:6) +// CHECK-NEXT: #loc128 = loc({{.*}}:50:13) +// CHECK-NEXT: #loc129 = loc({{.*}}:50:16) +// CHECK-NEXT: #loc130 = loc({{.*}}:50:6) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/coinbase.yul b/test/lit/mlirCodegen/yul/coinbase.yul new file mode 100644 index 000000000..0e896da85 --- /dev/null +++ b/test/lit/mlirCodegen/yul/coinbase.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, coinbase()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.coinbase loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/div.yul b/test/lit/mlirCodegen/yul/div.yul new file mode 100644 index 000000000..78e0ad004 --- /dev/null +++ b/test/lit/mlirCodegen/yul/div.yul @@ -0,0 +1,85 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let a := mload(0) + let b := mload(32) + mstore(64, div(a, b)) + mstore(96, sdiv(a, b)) + mstore(128, mod(a, b)) + mstore(160, smod(a, b)) + return(64, 128) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.mload %c0_i256 loc(#loc2) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.mload %c32_i256 loc(#loc6) +// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc7) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc8) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc9) +// CHECK-NEXT: %4 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %5 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc11) +// CHECK-NEXT: %6 = yul.div %4, %5 loc(#loc12) +// CHECK-NEXT: yul.mstore %c64_i256, %6 loc(#loc13) +// CHECK-NEXT: %c96_i256 = arith.constant 96 : i256 loc(#loc14) +// CHECK-NEXT: %7 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc15) +// CHECK-NEXT: %8 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc16) +// CHECK-NEXT: %9 = yul.sdiv %7, %8 loc(#loc17) +// CHECK-NEXT: yul.mstore %c96_i256, %9 loc(#loc18) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc19) +// CHECK-NEXT: %10 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc20) +// CHECK-NEXT: %11 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc21) +// CHECK-NEXT: %12 = yul.mod %10, %11 loc(#loc22) +// CHECK-NEXT: yul.mstore %c128_i256, %12 loc(#loc23) +// CHECK-NEXT: %c160_i256 = arith.constant 160 : i256 loc(#loc24) +// CHECK-NEXT: %13 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc25) +// CHECK-NEXT: %14 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc26) +// CHECK-NEXT: %15 = yul.smod %13, %14 loc(#loc27) +// CHECK-NEXT: yul.mstore %c160_i256, %15 loc(#loc28) +// CHECK-NEXT: %c64_i256_1 = arith.constant 64 : i256 loc(#loc29) +// CHECK-NEXT: %c128_i256_2 = arith.constant 128 : i256 loc(#loc30) +// CHECK-NEXT: yul.return %c64_i256_1, %c128_i256_2 loc(#loc31) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:11) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:19) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:22) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:15) +// CHECK-NEXT: #loc13 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:11) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:20) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:23) +// CHECK-NEXT: #loc17 = loc({{.*}}:7:15) +// CHECK-NEXT: #loc18 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:11) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:20) +// CHECK-NEXT: #loc21 = loc({{.*}}:8:23) +// CHECK-NEXT: #loc22 = loc({{.*}}:8:16) +// CHECK-NEXT: #loc23 = loc({{.*}}:8:4) +// CHECK-NEXT: #loc24 = loc({{.*}}:9:11) +// CHECK-NEXT: #loc25 = loc({{.*}}:9:21) +// CHECK-NEXT: #loc26 = loc({{.*}}:9:24) +// CHECK-NEXT: #loc27 = loc({{.*}}:9:16) +// CHECK-NEXT: #loc28 = loc({{.*}}:9:4) +// CHECK-NEXT: #loc29 = loc({{.*}}:10:11) +// CHECK-NEXT: #loc30 = loc({{.*}}:10:15) +// CHECK-NEXT: #loc31 = loc({{.*}}:10:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/exp.yul b/test/lit/mlirCodegen/yul/exp.yul new file mode 100644 index 000000000..af1aeac85 --- /dev/null +++ b/test/lit/mlirCodegen/yul/exp.yul @@ -0,0 +1,57 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let a := mload(0) + let b := mload(32) + mstore(0, exp(a, b)) + return(0, 32) + } + object "Test_deployed" { + code {} + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.mload %c0_i256 loc(#loc2) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.mload %c32_i256 loc(#loc6) +// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc7) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc8) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %c0_i256_1 = arith.constant 0 : i256 loc(#loc9) +// CHECK-NEXT: %4 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %5 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc11) +// CHECK-NEXT: %6 = yul.exp %4, %5 loc(#loc12) +// CHECK-NEXT: yul.mstore %c0_i256_1, %6 loc(#loc13) +// CHECK-NEXT: %c0_i256_2 = arith.constant 0 : i256 loc(#loc14) +// CHECK-NEXT: %c32_i256_3 = arith.constant 32 : i256 loc(#loc15) +// CHECK-NEXT: yul.return %c0_i256_2, %c32_i256_3 loc(#loc16) +// CHECK-NEXT: yul.object @Test_deployed { +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:11) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:18) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:21) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:14) +// CHECK-NEXT: #loc13 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:11) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:14) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/extcodecopy.yul b/test/lit/mlirCodegen/yul/extcodecopy.yul new file mode 100644 index 000000000..36b1e5dc9 --- /dev/null +++ b/test/lit/mlirCodegen/yul/extcodecopy.yul @@ -0,0 +1,32 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + extcodecopy(0xaaaaaaaa, 0, 4, 128) + return(0, 128) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c2863311530_i256 = arith.constant 2863311530 : i256 loc(#loc1) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc2) +// CHECK-NEXT: %c4_i256 = arith.constant 4 : i256 loc(#loc3) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc4) +// CHECK-NEXT: yul.extcodecopy %c2863311530_i256, %c0_i256, %c4_i256, %c128_i256 loc(#loc5) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc6) +// CHECK-NEXT: %c128_i256_1 = arith.constant 128 : i256 loc(#loc7) +// CHECK-NEXT: yul.return %c0_i256_0, %c128_i256_1 loc(#loc8) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:16) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:28) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:31) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:34) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/extcodehash.yul b/test/lit/mlirCodegen/yul/extcodehash.yul new file mode 100644 index 000000000..d7f752f26 --- /dev/null +++ b/test/lit/mlirCodegen/yul/extcodehash.yul @@ -0,0 +1,30 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, extcodehash(0xaaaaaaaa)) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %c2863311530_i256 = arith.constant 2863311530 : i256 loc(#loc2) +// CHECK-NEXT: %0 = yul.extcodehash %c2863311530_i256 loc(#loc3) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc4) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc5) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc6) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc7) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:26) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/gaslimit.yul b/test/lit/mlirCodegen/yul/gaslimit.yul new file mode 100644 index 000000000..f8887205d --- /dev/null +++ b/test/lit/mlirCodegen/yul/gaslimit.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, gaslimit()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.gaslimit loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/gasprice.yul b/test/lit/mlirCodegen/yul/gasprice.yul new file mode 100644 index 000000000..3edd5c808 --- /dev/null +++ b/test/lit/mlirCodegen/yul/gasprice.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, gasprice()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.gasprice loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/modops.yul b/test/lit/mlirCodegen/yul/modops.yul new file mode 100644 index 000000000..b5a5b99d7 --- /dev/null +++ b/test/lit/mlirCodegen/yul/modops.yul @@ -0,0 +1,77 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let x := mload(0) + let y := mload(32) + let m := mload(64) + mstore(0, addmod(x, y, m)) + mstore(32, mulmod(x, y, m)) + return(0, 64) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.mload %c0_i256 loc(#loc2) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.mload %c32_i256 loc(#loc6) +// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc7) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc8) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc9) +// CHECK-NEXT: %4 = yul.mload %c64_i256 loc(#loc10) +// CHECK-NEXT: %c1_i256_1 = arith.constant 1 : i256 loc(#loc11) +// CHECK-NEXT: %5 = llvm.alloca %c1_i256_1 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc12) +// CHECK-NEXT: llvm.store %4, %5 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc11) +// CHECK-NEXT: %c0_i256_2 = arith.constant 0 : i256 loc(#loc13) +// CHECK-NEXT: %6 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc14) +// CHECK-NEXT: %7 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc15) +// CHECK-NEXT: %8 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc16) +// CHECK-NEXT: %9 = yul.addmod %6, %7, %8 loc(#loc17) +// CHECK-NEXT: yul.mstore %c0_i256_2, %9 loc(#loc18) +// CHECK-NEXT: %c32_i256_3 = arith.constant 32 : i256 loc(#loc19) +// CHECK-NEXT: %10 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc20) +// CHECK-NEXT: %11 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc21) +// CHECK-NEXT: %12 = llvm.load %5 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc22) +// CHECK-NEXT: %13 = yul.mulmod %10, %11, %12 loc(#loc23) +// CHECK-NEXT: yul.mstore %c32_i256_3, %13 loc(#loc24) +// CHECK-NEXT: %c0_i256_4 = arith.constant 0 : i256 loc(#loc25) +// CHECK-NEXT: %c64_i256_5 = arith.constant 64 : i256 loc(#loc26) +// CHECK-NEXT: yul.return %c0_i256_4, %c64_i256_5 loc(#loc27) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:19) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:13) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:8) +// CHECK-NEXT: #loc13 = loc({{.*}}:7:11) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:21) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:24) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:27) +// CHECK-NEXT: #loc17 = loc({{.*}}:7:14) +// CHECK-NEXT: #loc18 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:11) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:22) +// CHECK-NEXT: #loc21 = loc({{.*}}:8:25) +// CHECK-NEXT: #loc22 = loc({{.*}}:8:28) +// CHECK-NEXT: #loc23 = loc({{.*}}:8:15) +// CHECK-NEXT: #loc24 = loc({{.*}}:8:4) +// CHECK-NEXT: #loc25 = loc({{.*}}:9:11) +// CHECK-NEXT: #loc26 = loc({{.*}}:9:14) +// CHECK-NEXT: #loc27 = loc({{.*}}:9:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/msize.yul b/test/lit/mlirCodegen/yul/msize.yul new file mode 100644 index 000000000..fcb11101c --- /dev/null +++ b/test/lit/mlirCodegen/yul/msize.yul @@ -0,0 +1,29 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, msize()) + return(0, 32) + } +} + +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.msize loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/number.yul b/test/lit/mlirCodegen/yul/number.yul new file mode 100644 index 000000000..e7e7d6efb --- /dev/null +++ b/test/lit/mlirCodegen/yul/number.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, number()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.number loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/origin.yul b/test/lit/mlirCodegen/yul/origin.yul new file mode 100644 index 000000000..a4e012cc0 --- /dev/null +++ b/test/lit/mlirCodegen/yul/origin.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, origin()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.origin loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/pop.yul b/test/lit/mlirCodegen/yul/pop.yul new file mode 100644 index 000000000..017b6a0f1 --- /dev/null +++ b/test/lit/mlirCodegen/yul/pop.yul @@ -0,0 +1,25 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + pop(msize()) + return(0, 32) + } +} + +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %0 = yul.msize loc(#loc1) +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc2) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc3) +// CHECK-NEXT: yul.return %c0_i256, %c32_i256 loc(#loc4) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc2 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc3 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/prevrandao.yul b/test/lit/mlirCodegen/yul/prevrandao.yul new file mode 100644 index 000000000..a274f1d2c --- /dev/null +++ b/test/lit/mlirCodegen/yul/prevrandao.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, prevrandao()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.prevrandao loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/selfbalance.yul b/test/lit/mlirCodegen/yul/selfbalance.yul new file mode 100644 index 000000000..19a189874 --- /dev/null +++ b/test/lit/mlirCodegen/yul/selfbalance.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, selfbalance()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.selfbalance loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/shifts.yul b/test/lit/mlirCodegen/yul/shifts.yul new file mode 100644 index 000000000..75613824a --- /dev/null +++ b/test/lit/mlirCodegen/yul/shifts.yul @@ -0,0 +1,74 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + let a := mload(0) + let b := mload(32) + mstore(64, shl(a, b)) + mstore(96, shr(a, b)) + mstore(128, sar(a, b)) + return(64, 96) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.mload %c0_i256 loc(#loc2) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc3) +// CHECK-NEXT: %1 = llvm.alloca %c1_i256 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc4) +// CHECK-NEXT: llvm.store %0, %1 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc3) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.mload %c32_i256 loc(#loc6) +// CHECK-NEXT: %c1_i256_0 = arith.constant 1 : i256 loc(#loc7) +// CHECK-NEXT: %3 = llvm.alloca %c1_i256_0 x i256 {alignment = 32 : i64} : (i256) -> !llvm.ptr loc(#loc8) +// CHECK-NEXT: llvm.store %2, %3 {alignment = 32 : i64} : i256, !llvm.ptr loc(#loc7) +// CHECK-NEXT: %c64_i256 = arith.constant 64 : i256 loc(#loc9) +// CHECK-NEXT: %4 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc10) +// CHECK-NEXT: %5 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc11) +// CHECK-NEXT: %6 = yul.shl %4, %5 loc(#loc12) +// CHECK-NEXT: yul.mstore %c64_i256, %6 loc(#loc13) +// CHECK-NEXT: %c96_i256 = arith.constant 96 : i256 loc(#loc14) +// CHECK-NEXT: %7 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc15) +// CHECK-NEXT: %8 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc16) +// CHECK-NEXT: %9 = yul.shr %7, %8 loc(#loc17) +// CHECK-NEXT: yul.mstore %c96_i256, %9 loc(#loc18) +// CHECK-NEXT: %c128_i256 = arith.constant 128 : i256 loc(#loc19) +// CHECK-NEXT: %10 = llvm.load %3 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc20) +// CHECK-NEXT: %11 = llvm.load %1 {alignment = 32 : i64} : !llvm.ptr -> i256 loc(#loc21) +// CHECK-NEXT: %12 = yul.sar %10, %11 loc(#loc22) +// CHECK-NEXT: yul.mstore %c128_i256, %12 loc(#loc23) +// CHECK-NEXT: %c64_i256_1 = arith.constant 64 : i256 loc(#loc24) +// CHECK-NEXT: %c96_i256_2 = arith.constant 96 : i256 loc(#loc25) +// CHECK-NEXT: yul.return %c64_i256_1, %c96_i256_2 loc(#loc26) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:19) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:13) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:8) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:19) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:13) +// CHECK-NEXT: #loc7 = loc({{.*}}:5:4) +// CHECK-NEXT: #loc8 = loc({{.*}}:5:8) +// CHECK-NEXT: #loc9 = loc({{.*}}:6:11) +// CHECK-NEXT: #loc10 = loc({{.*}}:6:22) +// CHECK-NEXT: #loc11 = loc({{.*}}:6:19) +// CHECK-NEXT: #loc12 = loc({{.*}}:6:15) +// CHECK-NEXT: #loc13 = loc({{.*}}:6:4) +// CHECK-NEXT: #loc14 = loc({{.*}}:7:11) +// CHECK-NEXT: #loc15 = loc({{.*}}:7:22) +// CHECK-NEXT: #loc16 = loc({{.*}}:7:19) +// CHECK-NEXT: #loc17 = loc({{.*}}:7:15) +// CHECK-NEXT: #loc18 = loc({{.*}}:7:4) +// CHECK-NEXT: #loc19 = loc({{.*}}:8:11) +// CHECK-NEXT: #loc20 = loc({{.*}}:8:23) +// CHECK-NEXT: #loc21 = loc({{.*}}:8:20) +// CHECK-NEXT: #loc22 = loc({{.*}}:8:16) +// CHECK-NEXT: #loc23 = loc({{.*}}:8:4) +// CHECK-NEXT: #loc24 = loc({{.*}}:9:11) +// CHECK-NEXT: #loc25 = loc({{.*}}:9:15) +// CHECK-NEXT: #loc26 = loc({{.*}}:9:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/signextend.yul b/test/lit/mlirCodegen/yul/signextend.yul new file mode 100644 index 000000000..dc94b046d --- /dev/null +++ b/test/lit/mlirCodegen/yul/signextend.yul @@ -0,0 +1,29 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, signextend(mload(0), mload(32))) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc2) +// CHECK-NEXT: %0 = yul.mload %c0_i256_0 loc(#loc3) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc4) +// CHECK-NEXT: %1 = yul.mload %c32_i256 loc(#loc5) +// CHECK-NEXT: %2 = yul.signextend %0, %1 loc(#loc6) +// CHECK-NEXT: yul.mstore %c0_i256, %2 loc(#loc7) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:31) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:25) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:41) +// CHECK-NEXT: #loc5 = loc({{.*}}:4:35) +// CHECK-NEXT: #loc6 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc7 = loc({{.*}}:4:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/timestamp.yul b/test/lit/mlirCodegen/yul/timestamp.yul new file mode 100644 index 000000000..085f900bf --- /dev/null +++ b/test/lit/mlirCodegen/yul/timestamp.yul @@ -0,0 +1,28 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + mstore(0, timestamp()) + return(0, 32) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %0 = yul.timestamp loc(#loc2) +// CHECK-NEXT: yul.mstore %c0_i256, %0 loc(#loc3) +// CHECK-NEXT: %c0_i256_0 = arith.constant 0 : i256 loc(#loc4) +// CHECK-NEXT: %c32_i256 = arith.constant 32 : i256 loc(#loc5) +// CHECK-NEXT: yul.return %c0_i256_0, %c32_i256 loc(#loc6) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:4) +// CHECK-NEXT: #loc4 = loc({{.*}}:5:11) +// CHECK-NEXT: #loc5 = loc({{.*}}:5:14) +// CHECK-NEXT: #loc6 = loc({{.*}}:5:4) +// CHECK-EMPTY: diff --git a/test/lit/mlirCodegen/yul/tstorage.yul b/test/lit/mlirCodegen/yul/tstorage.yul new file mode 100644 index 000000000..e94552d2a --- /dev/null +++ b/test/lit/mlirCodegen/yul/tstorage.yul @@ -0,0 +1,23 @@ +// RUN: solc --strict-assembly --mlir-action=print-init --mmlir --mlir-print-debuginfo %s | FileCheck %s + +object "Test" { + code { + tstore(0, tload(1)) + } +} +// NOTE: Assertions have been autogenerated by test/updFileCheckTest.py +// CHECK: #Prague = #sol +// CHECK-NEXT: module attributes {sol.evm_version = #Prague} { +// CHECK-NEXT: yul.object @Test { +// CHECK-NEXT: %c0_i256 = arith.constant 0 : i256 loc(#loc1) +// CHECK-NEXT: %c1_i256 = arith.constant 1 : i256 loc(#loc2) +// CHECK-NEXT: %0 = yul.tload %c1_i256 loc(#loc3) +// CHECK-NEXT: yul.tstore %c0_i256, %0 loc(#loc4) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: } loc(#loc) +// CHECK-NEXT: #loc = loc(unknown) +// CHECK-NEXT: #loc1 = loc({{.*}}:4:11) +// CHECK-NEXT: #loc2 = loc({{.*}}:4:20) +// CHECK-NEXT: #loc3 = loc({{.*}}:4:14) +// CHECK-NEXT: #loc4 = loc({{.*}}:4:4) +// CHECK-EMPTY: