From 17cc7420a7a9fe0597ac863fe598c5c3f755afa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 18 Mar 2015 19:08:59 +0100 Subject: [PATCH] Fixes and workarounds - Fix data copy: padding memory was not zero'd. - Fix inter-block stack optimization: incorrect phi node in first block. - Workaround incorrect llvm::APInt::urem() implementation. --- libevmjit/Arith256.cpp | 58 +++++++++++++++++++++------------------- libevmjit/BasicBlock.cpp | 5 +++- libevmjit/Memory.cpp | 8 +++--- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/libevmjit/Arith256.cpp b/libevmjit/Arith256.cpp index c22a642b0..f24626750 100644 --- a/libevmjit/Arith256.cpp +++ b/libevmjit/Arith256.cpp @@ -456,40 +456,42 @@ llvm::Value* Arith256::exp(llvm::Value* _arg1, llvm::Value* _arg2) llvm::Value* Arith256::addmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3) { - if (auto c1 = llvm::dyn_cast(_arg1)) - { - if (auto c2 = llvm::dyn_cast(_arg2)) - { - if (auto c3 = llvm::dyn_cast(_arg3)) - { - if (!c3->getValue()) - return Constant::get(0); - auto s = c1->getValue().zext(256+64) + c2->getValue().zext(256+64); - auto r = s.urem(c3->getValue().zext(256+64)).trunc(256); - return Constant::get(r); - } - } - } + // FIXME: Disabled because of llvm::APInt::urem bug +// if (auto c1 = llvm::dyn_cast(_arg1)) +// { +// if (auto c2 = llvm::dyn_cast(_arg2)) +// { +// if (auto c3 = llvm::dyn_cast(_arg3)) +// { +// if (!c3->getValue()) +// return Constant::get(0); +// auto s = c1->getValue().zext(256+64) + c2->getValue().zext(256+64); +// auto r = s.urem(c3->getValue().zext(256+64)).trunc(256); +// return Constant::get(r); +// } +// } +// } return createCall(getAddModFunc(), {_arg1, _arg2, _arg3}); } llvm::Value* Arith256::mulmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3) { - if (auto c1 = llvm::dyn_cast(_arg1)) - { - if (auto c2 = llvm::dyn_cast(_arg2)) - { - if (auto c3 = llvm::dyn_cast(_arg3)) - { - if (!c3->getValue()) - return Constant::get(0); - auto p = c1->getValue().zext(512) * c2->getValue().zext(512); - auto r = p.urem(c3->getValue().zext(512)).trunc(256); - return Constant::get(r); - } - } - } + // FIXME: Disabled because of llvm::APInt::urem bug +// if (auto c1 = llvm::dyn_cast(_arg1)) +// { +// if (auto c2 = llvm::dyn_cast(_arg2)) +// { +// if (auto c3 = llvm::dyn_cast(_arg3)) +// { +// if (!c3->getValue()) +// return Constant::get(0); +// auto p = c1->getValue().zext(512) * c2->getValue().zext(512); +// auto r = p.urem(c3->getValue().zext(512)).trunc(256); +// return Constant::get(r); +// } +// } +// } return createCall(getMulModFunc(), {_arg1, _arg2, _arg3}); } diff --git a/libevmjit/BasicBlock.cpp b/libevmjit/BasicBlock.cpp index 57d176b7a..93d73b991 100644 --- a/libevmjit/BasicBlock.cpp +++ b/libevmjit/BasicBlock.cpp @@ -236,7 +236,7 @@ void BasicBlock::linkLocalStacks(std::vector basicBlocks, llvm::IRB for (auto predIt = llvm::pred_begin(bb); predIt != llvm::pred_end(bb); ++predIt) { auto predInfoEntry = cfg.find(*predIt); - if (predInfoEntry != cfg.end()) + if (predInfoEntry != cfg.end()) // FIXME: It is wrong - will skip entry block info.predecessors.push_back(&predInfoEntry->second); } } @@ -258,6 +258,9 @@ void BasicBlock::linkLocalStacks(std::vector basicBlocks, llvm::IRB { auto& info = pair.second; + if (&info.bblock == basicBlocks.front()) + info.inputItems = 0; // we cannot use phi nodes for first block as it is a successor of entry block + if (info.predecessors.empty()) info.inputItems = 0; // no consequences for other blocks, so leave valuesChanged false diff --git a/libevmjit/Memory.cpp b/libevmjit/Memory.cpp index 27afab62c..79a82a8ae 100644 --- a/libevmjit/Memory.cpp +++ b/libevmjit/Memory.cpp @@ -231,14 +231,16 @@ void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* auto dataLeftSize = m_builder.CreateNUWSub(size64, idx64); auto outOfBound = m_builder.CreateICmpUGT(reqBytes, dataLeftSize); auto bytesToCopyInner = m_builder.CreateSelect(outOfBound, dataLeftSize, reqBytes); - auto bytesToCopy = m_builder.CreateSelect(isOutsideData, m_builder.getInt64(0), bytesToCopyInner); + auto bytesToCopy = m_builder.CreateSelect(isOutsideData, m_builder.getInt64(0), bytesToCopyInner, "bytesToCopy"); + auto bytesToZero = m_builder.CreateNUWSub(reqBytes, bytesToCopy, "bytesToZero"); auto src = m_builder.CreateGEP(_srcPtr, idx64, "src"); auto dstIdx = m_builder.CreateTrunc(_destMemIdx, Type::Size, "dstIdx"); // Never allow memory index be a type bigger than i64 + auto padIdx = m_builder.CreateNUWAdd(dstIdx, bytesToCopy, "padIdx"); auto dst = m_memory.getPtr(getRuntimeManager().getMem(), dstIdx); - auto dst2 = m_builder.CreateGEP(getData(), dstIdx, "dst2"); + auto pad = m_memory.getPtr(getRuntimeManager().getMem(), padIdx); m_builder.CreateMemCpy(dst, src, bytesToCopy, 0); - m_builder.CreateMemCpy(dst2, src, bytesToCopy, 0); + m_builder.CreateMemSet(pad, m_builder.getInt8(0), bytesToZero, 0); } }