Browse Source

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.
cl-refactor
Paweł Bylica 10 years ago
parent
commit
609a811753
  1. 58
      evmjit/libevmjit/Arith256.cpp
  2. 5
      evmjit/libevmjit/BasicBlock.cpp
  3. 8
      evmjit/libevmjit/Memory.cpp

58
evmjit/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<llvm::ConstantInt>(_arg1))
{
if (auto c2 = llvm::dyn_cast<llvm::ConstantInt>(_arg2))
{
if (auto c3 = llvm::dyn_cast<llvm::ConstantInt>(_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<llvm::ConstantInt>(_arg1))
// {
// if (auto c2 = llvm::dyn_cast<llvm::ConstantInt>(_arg2))
// {
// if (auto c3 = llvm::dyn_cast<llvm::ConstantInt>(_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<llvm::ConstantInt>(_arg1))
{
if (auto c2 = llvm::dyn_cast<llvm::ConstantInt>(_arg2))
{
if (auto c3 = llvm::dyn_cast<llvm::ConstantInt>(_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<llvm::ConstantInt>(_arg1))
// {
// if (auto c2 = llvm::dyn_cast<llvm::ConstantInt>(_arg2))
// {
// if (auto c3 = llvm::dyn_cast<llvm::ConstantInt>(_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});
}

5
evmjit/libevmjit/BasicBlock.cpp

@ -236,7 +236,7 @@ void BasicBlock::linkLocalStacks(std::vector<BasicBlock*> 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<BasicBlock*> 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

8
evmjit/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);
}
}

Loading…
Cancel
Save