diff --git a/lld/lld-c/LLDAsLibraryC.cpp b/lld/lld-c/LLDAsLibraryC.cpp index 0232268f8e81..e43472a74e6e 100644 --- a/lld/lld-c/LLDAsLibraryC.cpp +++ b/lld/lld-c/LLDAsLibraryC.cpp @@ -36,6 +36,13 @@ std::string getLinkerIndexedName(StringRef Name, unsigned SubIdx); std::string getLinkerSymbolSectionName(StringRef Name); std::string stripLinkerSymbolNameIndex(StringRef Name); } // namespace EraVM + +namespace EVM { +std::string getLinkerSymbolHash(StringRef SymName); +std::string getLinkerSymbolSectionName(StringRef Name); +std::string getDataSizeSymbol(StringRef SymbolName); +std::string getDataOffsetSymbol(StringRef SymbolName); +} // namespace EVM } // namespace llvm constexpr static unsigned linkerSubSymbolRelocSize = sizeof(uint32_t); @@ -486,12 +493,17 @@ static std::string creteEVMLinkerScript(ArrayRef memBufs, ArrayRef bufIDs) { assert(memBufs.size() == bufIDs.size()); size_t numObjectsToLink = memBufs.size(); - StringRef dataSizePrefix("__datasize_"); - StringRef dataOffsetPrefix("__dataoffset_"); + + auto getDataOffsetName = [](StringRef name) { + return EVM::getDataOffsetSymbol(EVM::getLinkerSymbolHash(name)); + }; + auto getDataSizeName = [](StringRef name) { + return EVM::getDataSizeSymbol(EVM::getLinkerSymbolHash(name)); + }; // Define the script part related to the top-level contract. - StringRef topName(bufIDs[0]); - StringRef deployed(bufIDs[1]); + std::string topName = EVM::getLinkerSymbolHash(bufIDs[0]); + std::string deployed = EVM::getLinkerSymbolHash(bufIDs[1]); // Contains the linker script part corresponding to the top-level contract. // For the example above, this contains: @@ -499,54 +511,58 @@ static std::string creteEVMLinkerScript(ArrayRef memBufs, // __dataoffset_D_105_deployed = .; // D_105_deployed(.text); // __datasize_D_105_deployed = . - __dataoffset_D_105_deployed; - std::string topLevel = - (topName + "(.text);\n" + dataOffsetPrefix + deployed + " = .;\n" + - deployed + "(.text);\n" + dataSizePrefix + deployed + " = . - " + - dataOffsetPrefix + deployed + ";\n") - .str(); + std::string topLevelBuf; + raw_string_ostream topLevel(topLevelBuf); + topLevel << topName << "(.text);\n" + << EVM::getDataOffsetSymbol(deployed) << " = .;\n" + << deployed << "(.text);\n" + << EVM::getDataSizeSymbol(deployed) << " = . - " + << EVM::getDataOffsetSymbol(deployed) + ";\n"; // Contains symbols whose values are the sizes of the dependent contracts. // For the example above, this contains: // __datasize_B_40 = 1384; - std::string symDatasizeDeps; + std::string dataSizeBuf; + raw_string_ostream symDatasizeDeps(dataSizeBuf); // Contains symbols whose values are the offsets of the dependent contracts. // For the example above, this contains: // __dataoffset_B_40 = .; - std::string symDataOffsetDeps; + std::string dataOffsetBuf; + raw_string_ostream symDataOffsetDeps(dataOffsetBuf); if (numObjectsToLink > 2) { // Define datasize symbols for the dependent contracts. They start after // {deploy, deployed} pair of the top-level contract, i.e. at index 2. for (unsigned idx = 2; idx < numObjectsToLink; ++idx) - symDatasizeDeps += (dataSizePrefix + bufIDs[idx] + " = " + - Twine(LLVMGetBufferSize(memBufs[idx])) + ";\n") - .str(); + symDatasizeDeps << getDataSizeName(bufIDs[idx]) << " = " + << LLVMGetBufferSize(memBufs[idx]) << ";\n"; - symDataOffsetDeps = (dataOffsetPrefix + bufIDs[2] + " = .;\n").str(); + symDataOffsetDeps << getDataOffsetName(bufIDs[2]) << " = .;\n"; for (unsigned idx = 3; idx < numObjectsToLink; ++idx) - symDataOffsetDeps += - (dataOffsetPrefix + bufIDs[idx] + " = " + dataOffsetPrefix + - bufIDs[idx - 1] + " + " + dataSizePrefix + bufIDs[idx - 1] + ";\n") - .str(); + symDataOffsetDeps << getDataOffsetName(bufIDs[idx]) << " = " + << getDataOffsetName(bufIDs[idx - 1]) << " + " + << getDataSizeName(bufIDs[idx - 1]) << ";\n"; } // Contains a symbol whose value is the total size of the top-level contract // with all the dependencies. - std::string symDatasizeTop = (dataSizePrefix + topName + " = ").str(); + std::string dataSizeTopBuf; + raw_string_ostream symDatasizeTop(dataSizeTopBuf); + symDatasizeTop << EVM::getDataSizeSymbol(topName) << " = "; if (numObjectsToLink > 2) - symDatasizeTop += (dataOffsetPrefix + bufIDs.back() + " + " + - dataSizePrefix + bufIDs.back() + ";\n") - .str(); + symDatasizeTop << getDataOffsetName(bufIDs.back()) << " + " + << getDataSizeName(bufIDs.back()) << ";\n"; else - symDatasizeTop += ".;\n"; + symDatasizeTop << ".;\n"; // Emit size of the deploy code offset as the 4-byte unsigned integer. // This is needed to determine which offset the deployed code starts at // in the linked binary. std::string deploySize = - ("LONG(" + dataOffsetPrefix + deployed + ");\n").str(); + "LONG(" + EVM::getDataOffsetSymbol(deployed) + ");\n"; - std::string script = formatv("{0}\n\ + std::string script = + formatv("{0}\n\ ENTRY(0);\n\ SECTIONS {\n\ . = 0;\n\ @@ -558,8 +574,8 @@ SECTIONS {\n\ }\n\ }\n\ ", - symDatasizeDeps, topLevel, symDataOffsetDeps, - symDatasizeTop, deploySize); + symDatasizeDeps.str(), topLevel.str(), symDataOffsetDeps.str(), + symDatasizeTop.str(), deploySize); return script; } @@ -570,16 +586,21 @@ LLVMBool LLVMLinkEVM(LLVMMemoryBufferRef inBuffers[], assert(numInBuffers > 1); SmallVector localInMemBufRefs(3); SmallVector> localInMemBufs(3); + + // TODO: #740. Verify that the object files contain sections with original + // inBuffersIDs, i.e. before taking hash. for (unsigned idx = 0; idx < 2; ++idx) { MemoryBufferRef ref = *unwrap(inBuffers[idx]); - localInMemBufs[idx] = - MemoryBuffer::getMemBuffer(ref.getBuffer(), inBuffersIDs[idx], - /*RequiresNullTerminator*/ false); + // We need to copy buffers to be able to change their names, as this matters + // for the linker. + localInMemBufs[idx] = MemoryBuffer::getMemBufferCopy( + ref.getBuffer(), EVM::getLinkerSymbolHash(inBuffersIDs[idx])); localInMemBufRefs[idx] = localInMemBufs[idx]->getMemBufferRef(); } std::string linkerScript = creteEVMLinkerScript( ArrayRef(inBuffers, numInBuffers), ArrayRef(inBuffersIDs, numInBuffers)); + std::unique_ptr scriptBuf = MemoryBuffer::getMemBuffer(linkerScript, "script.x"); localInMemBufRefs[2] = scriptBuf->getMemBufferRef(); @@ -592,19 +613,20 @@ LLVMBool LLVMLinkEVM(LLVMMemoryBufferRef inBuffers[], // Use remapping of file names (a linker feature) to replace file names with // indexes in the array of memory buffers. const std::string remapStr("--remap-inputs="); - std::string remapDeployStr = remapStr + inBuffersIDs[0] + "=0"; + std::string topHash = EVM::getLinkerSymbolHash(inBuffersIDs[0]); + std::string deployedHash = EVM::getLinkerSymbolHash(inBuffersIDs[1]); + std::string remapDeployStr = remapStr + topHash + "=0"; lldArgs.push_back(remapDeployStr.c_str()); - std::string remapDeployedStr = remapStr + inBuffersIDs[1] + "=1"; + std::string remapDeployedStr = remapStr + deployedHash + "=1"; lldArgs.push_back(remapDeployedStr.c_str()); lldArgs.push_back("--remap-inputs=script.x=2"); // Deploy code - lldArgs.push_back(inBuffersIDs[0]); + lldArgs.push_back(topHash.c_str()); // Deployed code - lldArgs.push_back(inBuffersIDs[1]); - + lldArgs.push_back(deployedHash.c_str()); lldArgs.push_back("--oformat=binary"); SmallString<0> codeString; diff --git a/llvm/lib/Target/EVM/EVMAsmPrinter.cpp b/llvm/lib/Target/EVM/EVMAsmPrinter.cpp index 22b3d476d072..999ac042d2bd 100644 --- a/llvm/lib/Target/EVM/EVMAsmPrinter.cpp +++ b/llvm/lib/Target/EVM/EVMAsmPrinter.cpp @@ -13,13 +13,20 @@ #include "EVMMCInstLower.h" #include "EVMTargetMachine.h" +#include "MCTargetDesc/EVMMCTargetDesc.h" +#include "MCTargetDesc/EVMTargetStreamer.h" #include "TargetInfo/EVMTargetInfo.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/TargetRegistry.h" + using namespace llvm; #define DEBUG_TYPE "asm-printer" @@ -50,6 +57,9 @@ class EVMAsmPrinter : public AsmPrinter { /// fall-through. bool isBlockOnlyReachableByFallthrough( const MachineBasicBlock *MBB) const override; + +private: + void emitLinkerSymbol(const MachineInstr *MI); }; } // end of anonymous namespace @@ -94,6 +104,13 @@ void EVMAsmPrinter::emitFunctionEntryLabel() { void EVMAsmPrinter::emitInstruction(const MachineInstr *MI) { EVMMCInstLower MCInstLowering(OutContext, *this, VRegMapping, MF->getRegInfo()); + + unsigned Opc = MI->getOpcode(); + if (Opc == EVM::DATASIZE_S || Opc == EVM::DATAOFFSET_S) { + emitLinkerSymbol(MI); + return; + } + MCInst TmpInst; MCInstLowering.Lower(MI, TmpInst); EmitToStreamer(*OutStreamer, TmpInst); @@ -105,6 +122,26 @@ bool EVMAsmPrinter::isBlockOnlyReachableByFallthrough( return false; } +void EVMAsmPrinter::emitLinkerSymbol(const MachineInstr *MI) { + MCSymbol *LinkerSymbol = MI->getOperand(0).getMCSymbol(); + StringRef LinkerSymbolName = LinkerSymbol->getName(); + unsigned Opc = MI->getOpcode(); + assert(Opc == EVM::DATASIZE_S || Opc == EVM::DATAOFFSET_S); + + std::string SymbolNameHash = EVM::getLinkerSymbolHash(LinkerSymbolName); + std::string DataSymbolNameHash = + (Opc == EVM::DATASIZE_S) ? EVM::getDataSizeSymbol(SymbolNameHash) + : EVM::getDataOffsetSymbol(SymbolNameHash); + + MCInst MCI; + MCI.setOpcode(EVM::PUSH4_S); + MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VariantKind::VK_EVM_DATA; + MCOperand MCOp = MCOperand::createExpr( + MCSymbolRefExpr::create(DataSymbolNameHash, Kind, OutContext)); + MCI.addOperand(MCOp); + EmitToStreamer(*OutStreamer, MCI); +} + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeEVMAsmPrinter() { const RegisterAsmPrinter X(getTheEVMTarget()); } diff --git a/llvm/lib/Target/EVM/EVMISelLowering.cpp b/llvm/lib/Target/EVM/EVMISelLowering.cpp index 3dc92eb5f5b3..7f83fb39adef 100644 --- a/llvm/lib/Target/EVM/EVMISelLowering.cpp +++ b/llvm/lib/Target/EVM/EVMISelLowering.cpp @@ -153,28 +153,21 @@ SDValue EVMTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, default: return SDValue(); case Intrinsic::evm_datasize: - case Intrinsic::evm_dataoffset: - return lowerIntrinsicDataSize(IntrID, Op, DAG); + case Intrinsic::evm_dataoffset: { + const SDLoc DL(Op); + EVT Ty = Op.getValueType(); + MachineFunction &MF = DAG.getMachineFunction(); + const MDNode *Metadata = cast(Op.getOperand(1))->getMD(); + StringRef ContractID = cast(Metadata->getOperand(0))->getString(); + MCSymbol *Sym = MF.getContext().getOrCreateSymbol(ContractID); + unsigned Opc = + (IntrID == Intrinsic::evm_datasize) ? EVM::DATASIZE : EVM::DATAOFFSET; + return SDValue( + DAG.getMachineNode(Opc, DL, Ty, DAG.getMCSymbol(Sym, MVT::i256)), 0); + } break; } } -SDValue EVMTargetLowering::lowerIntrinsicDataSize(unsigned IntrID, SDValue Op, - SelectionDAG &DAG) const { - const SDLoc DL(Op); - EVT Ty = Op.getValueType(); - - MachineFunction &MF = DAG.getMachineFunction(); - const MDNode *Metadata = cast(Op.getOperand(1))->getMD(); - StringRef ContractID = cast(Metadata->getOperand(0))->getString(); - bool IsDataSize = IntrID == Intrinsic::evm_datasize; - std::string SymbolReloc = - (Twine(IsDataSize ? "__datasize_" : "__dataoffset_") + ContractID).str(); - MCSymbol *Sym = MF.getContext().getOrCreateSymbol(SymbolReloc); - return SDValue( - DAG.getMachineNode(EVM::DATA, DL, Ty, DAG.getMCSymbol(Sym, MVT::i256)), - 0); -} - SDValue EVMTargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const { const SDLoc DL(Op); auto *Load = cast(Op); diff --git a/llvm/lib/Target/EVM/EVMISelLowering.h b/llvm/lib/Target/EVM/EVMISelLowering.h index 3c20d090c4d8..c47b593917d2 100644 --- a/llvm/lib/Target/EVM/EVMISelLowering.h +++ b/llvm/lib/Target/EVM/EVMISelLowering.h @@ -133,9 +133,6 @@ class EVMTargetLowering final : public TargetLowering { SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; - SDValue lowerIntrinsicDataSize(unsigned IntrID, SDValue Op, - SelectionDAG &DAG) const; - SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/EVM/EVMInstrInfo.td b/llvm/lib/Target/EVM/EVMInstrInfo.td index 8700834e45d8..fe34e814aff9 100644 --- a/llvm/lib/Target/EVM/EVMInstrInfo.td +++ b/llvm/lib/Target/EVM/EVMInstrInfo.td @@ -1122,7 +1122,12 @@ def PUSH32_S : NI<(outs), (ins i256imm:$imm), [], true, "PUSH32 $imm", } // Pseudo instructions for linkage -let isCodeGenOnly = 1, BaseName = "DATA" in { - def DATA : NI<(outs GPR:$dst), (ins jmptarget:$reloc), [], false, "", 0, 0>; - def DATA_S : NI<(outs), (ins jmptarget:$reloc), [], true, "", 0, 0>; +let isCodeGenOnly = 1, BaseName = "DATASIZE" in { + def DATASIZE : NI<(outs GPR:$dst), (ins jmptarget:$reloc), [], false, "", 0, 0>; + def DATASIZE_S : NI<(outs), (ins jmptarget:$reloc), [], true, "", 0, 0>; +} + +let isCodeGenOnly = 1, BaseName = "DATAOFFSET" in { + def DATAOFFSET : NI<(outs GPR:$dst), (ins jmptarget:$reloc), [], false, "", 0, 0>; + def DATAOFFSET_S : NI<(outs), (ins jmptarget:$reloc), [], true, "", 0, 0>; } diff --git a/llvm/lib/Target/EVM/EVMMCInstLower.cpp b/llvm/lib/Target/EVM/EVMMCInstLower.cpp index 297385478bb7..3278761f0d95 100644 --- a/llvm/lib/Target/EVM/EVMMCInstLower.cpp +++ b/llvm/lib/Target/EVM/EVMMCInstLower.cpp @@ -39,7 +39,7 @@ static void stackifyInstruction(const MachineInstr *MI, MCInst &OutMI) { // Set up final opcodes for the following codegen-only instructions. unsigned Opcode = OutMI.getOpcode(); - if (Opcode == EVM::PUSH_LABEL || Opcode == EVM::DATA_S) + if (Opcode == EVM::PUSH_LABEL) OutMI.setOpcode(EVM::PUSH4_S); // Check that all the instructions are in the 'stack' form. @@ -125,9 +125,11 @@ void EVMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) { } break; case MachineOperand::MO_MCSymbol: { MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VariantKind::VK_None; +#ifndef NDEBUG unsigned Opc = MI->getOpcode(); - if (Opc == EVM::DATA_S) - Kind = MCSymbolRefExpr::VariantKind::VK_EVM_DATA; + // We handle the linkage-related instructions in the EVMAsmPrinter. + assert(Opc != EVM::DATASIZE_S && Opc != EVM::DATAOFFSET_S); +#endif // NDEBUG MCOp = MCOperand::createExpr( MCSymbolRefExpr::create(MO.getMCSymbol(), Kind, Ctx)); diff --git a/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.cpp b/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.cpp index 8deb0324f206..df8887bf6912 100644 --- a/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.cpp +++ b/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.cpp @@ -15,10 +15,12 @@ #include "EVMMCAsmInfo.h" #include "EVMTargetStreamer.h" #include "TargetInfo/EVMTargetInfo.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/KECCAK.h" using namespace llvm; @@ -114,3 +116,20 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeEVMTargetMC() { // Register the null target streamer. TargetRegistry::RegisterNullTargetStreamer(T, createEVMNullTargetStreamer); } + +// Returs a string of the following format: +// '__$KECCAK256(SymName)$__' +std::string EVM::getLinkerSymbolHash(StringRef SymName) { + std::array Hash = KECCAK::KECCAK_256(SymName); + SmallString<72> HexHash; + toHex(Hash, /*LowerCase*/ true, HexHash); + return (Twine("__$") + HexHash + "$__").str(); +} + +std::string EVM::getDataSizeSymbol(StringRef SymbolName) { + return (Twine("__datasize") + SymbolName).str(); +} + +std::string EVM::getDataOffsetSymbol(StringRef SymbolName) { + return (Twine("__dataoffset") + SymbolName).str(); +} diff --git a/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.h b/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.h index 639ae49357b1..55463908ee02 100644 --- a/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.h +++ b/llvm/lib/Target/EVM/MCTargetDesc/EVMMCTargetDesc.h @@ -13,6 +13,7 @@ #ifndef LLVM_LIB_TARGET_EVM_MCTARGETDESC_EVMMCTARGETDESC_H #define LLVM_LIB_TARGET_EVM_MCTARGETDESC_EVMMCTARGETDESC_H +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include @@ -36,6 +37,11 @@ MCAsmBackend *createEVMMCAsmBackend(const Target &T, const MCSubtargetInfo &STI, std::unique_ptr createEVMELFObjectWriter(uint8_t OSABI); +namespace EVM { +std::string getLinkerSymbolHash(StringRef SymName); +std::string getDataSizeSymbol(StringRef SymbolName); +std::string getDataOffsetSymbol(StringRef SymbolName); +} // namespace EVM } // namespace llvm // Defines symbolic names for EVM registers. diff --git a/llvm/test/MC/EVM/data-linker-symbol-relocs.ll b/llvm/test/MC/EVM/data-linker-symbol-relocs.ll new file mode 100644 index 000000000000..8c0fb82b1e84 --- /dev/null +++ b/llvm/test/MC/EVM/data-linker-symbol-relocs.ll @@ -0,0 +1,34 @@ +; RUN: llc -O2 -filetype=obj --mtriple=evm %s -o - | llvm-objdump -r - | FileCheck %s + +; CHECK: RELOCATION RECORDS FOR [.text]: +; CHECK-NEXT: OFFSET TYPE VALUE +; CHECK-NEXT: {{\d*}} R_EVM_DATA __dataoffset__$0336fd807c0716a535e520df5b63ecc41ba7984875fdfa2241fcf3c8d0107e26$__ +; CHECK-NEXT: {{\d*}} R_EVM_DATA __datasize__$0336fd807c0716a535e520df5b63ecc41ba7984875fdfa2241fcf3c8d0107e26$__ +; CHECK-NEXT: {{\d*}} R_EVM_DATA __dataoffset__$0336fd807c0716a535e520df5b63ecc41ba7984875fdfa2241fcf3c8d0107e26$__ +; CHECK-NEXT: {{\d*}} R_EVM_DATA __datasize__$0336fd807c0716a535e520df5b63ecc41ba7984875fdfa2241fcf3c8d0107e26$__ + +; TODO: CRP-1575. Rewrite the test in assembly. +target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256" +target triple = "evm-unknown-unknown" + +; Function Attrs: nounwind +declare i256 @llvm.evm.datasize(metadata) +declare i256 @llvm.evm.dataoffset(metadata) + +define i256 @foo() { +entry: + %deployed_size = tail call i256 @llvm.evm.datasize(metadata !1) + %deployed_off = tail call i256 @llvm.evm.dataoffset(metadata !1) + %res = add i256 %deployed_size, %deployed_off + ret i256 %res +} + +define i256 @bar() { +entry: + %deployed_size = tail call i256 @llvm.evm.datasize(metadata !1) + %deployed_off = tail call i256 @llvm.evm.dataoffset(metadata !1) + %res = sub i256 %deployed_size, %deployed_off + ret i256 %res +} + +!1 = !{!"D_105_deployed"} diff --git a/llvm/test/MC/EVM/datasize_relocation.ll b/llvm/test/MC/EVM/datasize_relocation.ll deleted file mode 100644 index 906aee7bc15a..000000000000 --- a/llvm/test/MC/EVM/datasize_relocation.ll +++ /dev/null @@ -1,51 +0,0 @@ -; RUN: llc -O2 -filetype=obj --mtriple=evm %s -o - | llvm-objdump -r - | FileCheck %s - -; CHECK: RELOCATION RECORDS FOR [.text]: -; CHECK-NEXT: OFFSET TYPE VALUE -; CHECK-NEXT: {{\d*}} R_EVM_DATA __datasize_D_105_deployed -; CHECK-NEXT: {{\d*}} R_EVM_DATA __dataoffset_D_105_deployed - -; TODO: CRP-1575. Rewrite the test in assembly. -target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256" -target triple = "evm-unknown-unknown" - -; Function Attrs: nounwind -declare i256 @llvm.evm.callvalue() -declare i256 @llvm.evm.datasize(metadata) -declare i256 @llvm.evm.dataoffset(metadata) -declare i256 @llvm.evm.codesize() - -declare void @llvm.memcpy.p1i256.p4i256.i256(ptr addrspace(1) noalias nocapture writeonly, ptr addrspace(4) noalias nocapture readonly, i256, i1 immarg) - -; Function Attrs: noreturn nounwind -declare void @llvm.evm.return(ptr addrspace(1), i256) #1 - -; Function Attrs: noreturn nounwind -declare void @llvm.evm.revert(ptr addrspace(1), i256) #1 - -; Function Attrs: nofree noinline noreturn null_pointer_is_valid -define void @__entry() local_unnamed_addr #2 { -entry: - store i256 128, ptr addrspace(1) inttoptr (i256 64 to ptr addrspace(1)), align 64 - %callvalue = tail call i256 @llvm.evm.callvalue() - %if_condition_compared.not = icmp eq i256 %callvalue, 0 - br i1 %if_condition_compared.not, label %if_join, label %if_main - -if_main: ; preds = %entry - tail call void @llvm.evm.revert(ptr addrspace(1) noalias nocapture nofree noundef nonnull align 32 null, i256 0) - unreachable - -if_join: ; preds = %entry - %deployed_size = tail call i256 @llvm.evm.datasize(metadata !1) - %deployed_off = tail call i256 @llvm.evm.dataoffset(metadata !1) - %rt_ptr = inttoptr i256 %deployed_off to ptr addrspace(4) - call void @llvm.memcpy.p1i256.p4i256.i256(ptr addrspace(1) inttoptr (i256 128 to ptr addrspace(1)), ptr addrspace(4) %rt_ptr, i256 %deployed_size, i1 false) - tail call void @llvm.evm.return(ptr addrspace(1) noalias nocapture nofree noundef nonnull align 32 inttoptr (i256 128 to ptr addrspace(1)), i256 %deployed_size) - unreachable -} - -attributes #0 = { nounwind } -attributes #1 = { noreturn nounwind } -attributes #2 = { nofree noinline noreturn null_pointer_is_valid } - -!1 = !{!"D_105_deployed"}