Skip to content

Use native shift instructions on Constantinople#3797

Merged
chriseth merged 6 commits intodevelopfrom
shift-constantinople
May 2, 2018
Merged

Use native shift instructions on Constantinople#3797
chriseth merged 6 commits intodevelopfrom
shift-constantinople

Conversation

@axic
Copy link
Contributor

@axic axic commented Mar 29, 2018

No description provided.

@axic axic requested a review from chriseth March 29, 2018 11:02
@axic
Copy link
Contributor Author

axic commented Mar 29, 2018

@pirapira this will help in testing cpp-ethereum 😉

@axic
Copy link
Contributor Author

axic commented Mar 29, 2018

Before merging this we need to adjust test to run on constantinople: https://github.com/ethereum/solidity/blob/develop/scripts/tests.sh#L106

@axic
Copy link
Contributor Author

axic commented Mar 30, 2018

@chriseth do you have instructions somewhere how do you compile the eth binaries used in testing?

@chriseth
Copy link
Contributor

chriseth commented Apr 3, 2018

@axic no special instructions for building... But yeah, we should perhaps automate that.

@axic
Copy link
Contributor Author

axic commented Apr 5, 2018

Ran this with a local cpp-ethereum copy and weirdly enough it seems to be passing :)

chriseth
chriseth previously approved these changes Apr 5, 2018
@chriseth
Copy link
Contributor

chriseth commented Apr 5, 2018

Conflict in the changelog. Also you might want to do a similar change in ABIFunctions.cpp

@axic
Copy link
Contributor Author

axic commented Apr 5, 2018

In ABIFunctions there is shiftLeftFunction and shiftRightFunction and also 3 other places use mul(<x>, 2)

}
)")
("functionName", functionName)
("shiftOp", _signed ? "sar" : "shl")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: shl -> shr

@axic axic force-pushed the shift-constantinople branch 2 times, most recently from f6d2f9c to 69ce190 Compare April 5, 2018 15:12
@chriseth chriseth force-pushed the shift-constantinople branch from 69ce190 to 9794c50 Compare April 5, 2018 15:44
.render();
Whiskers templ(R"(
function <functionName>(value) -> newValue {
newValue := <shiftOp>(value, <secondArg>)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think this is broken because the top of the stack is secondArg for shifts, which in inline assembly would be shl(<secondArg>, value)

@axic axic force-pushed the shift-constantinople branch from 9794c50 to 9a6a94e Compare April 5, 2018 16:25
@axic
Copy link
Contributor Author

axic commented Apr 5, 2018

@chriseth pushed the old version, but with the correct operand order

case Token::SHL:
m_context << Instruction::SWAP1 << u256(2) << Instruction::EXP << Instruction::MUL;
if (m_context.evmVersion().hasBitwiseShifting())
m_context << Instruction::SHL;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a SWAP1 then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The swap is added above.

@axic axic force-pushed the shift-constantinople branch 4 times, most recently from 2ea8c65 to b5e879e Compare April 6, 2018 11:41
@axic
Copy link
Contributor Author

axic commented Apr 6, 2018

The SAR test failures reminded me that SAR rounds differently to SDIV, it also shows that there is no test for this in ABIFunctions::shiftRightFunction because it didn't trigger a test failure 😉

break;
case Token::SAR:
m_context << Instruction::SWAP1 << u256(2) << Instruction::EXP << Instruction::SWAP1 << (c_valueSigned ? Instruction::SDIV : Instruction::DIV);
// NOTE: SAR rounds differently than SDIV
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And because of that, this would be a breaking change, wouldn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We could think about having that as a breaking change though to fix signed right shifts.

case Token::SHL:
m_context << Instruction::SWAP1 << u256(2) << Instruction::EXP << Instruction::MUL;
if (m_context.evmVersion().hasBitwiseShifting())
m_context << Instruction::SWAP1 << Instruction::SHL;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this SWAP1 is invalid here, it is done outside the switch already.

@axic axic force-pushed the shift-constantinople branch 2 times, most recently from 84afba5 to ac9f667 Compare April 11, 2018 14:41
@axic axic force-pushed the shift-constantinople branch from ac9f667 to 49c0ae1 Compare April 11, 2018 15:41
@axic axic force-pushed the shift-constantinople branch from 49c0ae1 to 599c2b2 Compare April 18, 2018 22:03
Changelog.md Outdated
Features:
* Code Generator: Initialize arrays without using ``msize()``.
* Code Generator: More specialized and thus optimized implementation for ``x.push(...)``
* Code Generator: Use native shift instructions on target Constantinople.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to move this.

@axic axic force-pushed the shift-constantinople branch from 599c2b2 to 1c79613 Compare April 23, 2018 01:11
@axic
Copy link
Contributor Author

axic commented Apr 23, 2018

For example this test fails "regular_functions_exclude_fallback - GasMeterTests".

Code:

                contract A {
                        uint public x;
                        function() { x = 2; }
                }

Byzantium mode:

construction:
   87 + 35000 = 35087
external:
   fallback:	20123
   x():	394
EVM assembly:
    /* "9613.sol":16:131  contract A {... */
  mstore(0x40, 0x80)
  callvalue
    /* "--CODEGEN--":8:17   */
  dup1
    /* "--CODEGEN--":5:7   */
  iszero
  tag_1
  jumpi
    /* "--CODEGEN--":30:31   */
  0x0
    /* "--CODEGEN--":27:28   */
  dup1
    /* "--CODEGEN--":20:32   */
  revert
    /* "--CODEGEN--":5:7   */
tag_1:
    /* "9613.sol":16:131  contract A {... */
  pop
  dataSize(sub_0)
  dup1
  dataOffset(sub_0)
  0x0
  codecopy
  0x0
  return
stop

sub_0: assembly {
        /* "9613.sol":16:131  contract A {... */
      mstore(0x40, 0x80)
      jumpi(tag_1, lt(calldatasize, 0x4))
      calldataload(0x0)
      0x100000000000000000000000000000000000000000000000000000000
      swap1
      div
      0xffffffff
      and
      dup1
      0xc55699c
      eq
      tag_2
      jumpi
    tag_1:
...

Constantinople

construction:
   81 + 29200 = 29281
external:
   fallback:	20118
   x():	20118
EVM assembly:
    /* "9613.sol":16:131  contract A {... */
  mstore(0x40, 0x80)
  callvalue
    /* "--CODEGEN--":8:17   */
  dup1
    /* "--CODEGEN--":5:7   */
  iszero
  tag_1
  jumpi
    /* "--CODEGEN--":30:31   */
  0x0
    /* "--CODEGEN--":27:28   */
  dup1
    /* "--CODEGEN--":20:32   */
  revert
    /* "--CODEGEN--":5:7   */
tag_1:
    /* "9613.sol":16:131  contract A {... */
  pop
  dataSize(sub_0)
  dup1
  dataOffset(sub_0)
  0x0
  codecopy
  0x0
  return
stop

sub_0: assembly {
        /* "9613.sol":16:131  contract A {... */
      mstore(0x40, 0x80)
      jumpi(tag_1, lt(calldatasize, 0x4))
      and(0xffffffff, shr(0xe0, calldataload(0x0)))
      dup1
      0xc55699c
      eq
      tag_2
      jumpi
    tag_1:
...

I am not sure what is causing the 6000 higher gas cost on deployment, given the constant optimiser i not turned on, and the byzantium version has a large number with a lot zeroes for which no gas should be charged.

@chriseth
Copy link
Contributor

zeros are only free in transaction data, but not for code deployment.

@axic axic force-pushed the shift-constantinople branch from 1c79613 to 971941b Compare April 30, 2018 20:23
@axic
Copy link
Contributor Author

axic commented Apr 30, 2018

@chriseth this seems to be working now

@chriseth chriseth merged commit a856135 into develop May 2, 2018
@axic axic deleted the shift-constantinople branch May 3, 2018 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments