Skip to content

Commit 19eef91

Browse files
committed
[EVM] Support OR in conditional jump optimization
* `ISZERO ISZERO OR* PseudoJUMPI` -> `OR* PseudoJUMPI` * `EQ ISZERO OR* PseudoJUMPI` -> `SUB OR* PseudoJUMPI` * `SUB ISZERO OR* PseudoJUMPI` -> `EQ OR* PseudoJUMPI`
1 parent ba4aae2 commit 19eef91

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

llvm/lib/Target/EVM/EVMPeephole.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,18 @@ bool EVMPeephole::runOnMachineFunction(MachineFunction &MF) {
4545
return Changed;
4646
}
4747

48-
static bool isNegatadAndJumpedOn(const MachineBasicBlock &MBB,
48+
static bool isNegatedAndJumpedOn(const MachineBasicBlock &MBB,
4949
MachineBasicBlock::const_iterator I) {
5050
if (I == MBB.end() || I->getOpcode() != EVM::ISZERO_S)
5151
return false;
5252
++I;
53-
if (I == MBB.end())
54-
return false;
55-
if (I->getOpcode() == EVM::PseudoJUMPI)
56-
return true;
57-
if (I->getOpcode() != EVM::PUSH4_S)
58-
return false;
59-
++I;
60-
return I != MBB.end() && I->getOpcode() == EVM::JUMPI;
53+
// When a conditional jump’s predicate is a (possibly nested) bitwise `or`,
54+
// both operands are eligible for folding. Currently we only fold the operand
55+
// computed last.
56+
// TODO: #887 Apply folding to all operands.
57+
while (I != MBB.end() && I->getOpcode() == EVM::OR_S)
58+
++I;
59+
return I != MBB.end() && I->getOpcode() == EVM::PseudoJUMPI;
6160
}
6261

6362
bool EVMPeephole::optimizeConditionaJumps(MachineBasicBlock &MBB) const {
@@ -67,23 +66,23 @@ bool EVMPeephole::optimizeConditionaJumps(MachineBasicBlock &MBB) const {
6766
while (I != MBB.end()) {
6867
// Fold ISZERO ISZERO to nothing, only if it's a predicate to JUMPI.
6968
if (I->getOpcode() == EVM::ISZERO_S &&
70-
isNegatadAndJumpedOn(MBB, std::next(I))) {
69+
isNegatedAndJumpedOn(MBB, std::next(I))) {
7170
std::next(I)->eraseFromParent();
7271
I->eraseFromParent();
7372
return true;
7473
}
7574

7675
// Fold EQ ISZERO to SUB, only if it's a predicate to JUMPI.
7776
if (I->getOpcode() == EVM::EQ_S &&
78-
isNegatadAndJumpedOn(MBB, std::next(I))) {
77+
isNegatedAndJumpedOn(MBB, std::next(I))) {
7978
I->setDesc(TII->get(EVM::SUB_S));
8079
std::next(I)->eraseFromParent();
8180
return true;
8281
}
8382

8483
// Fold SUB ISZERO to EQ, only if it's a predicate to JUMPI.
8584
if (I->getOpcode() == EVM::SUB_S &&
86-
isNegatadAndJumpedOn(MBB, std::next(I))) {
85+
isNegatedAndJumpedOn(MBB, std::next(I))) {
8786
I->setDesc(TII->get(EVM::EQ_S));
8887
std::next(I)->eraseFromParent();
8988
return true;

llvm/test/CodeGen/EVM/brcond.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,31 @@ false:
423423
unreachable
424424
}
425425

426+
define void @br_or(i256 %a, i256 %b, i256 %c) {
427+
; CHECK-LABEL: br_or:
428+
; CHECK: ; %bb.0:
429+
; CHECK-NEXT: JUMPDEST
430+
; CHECK-NEXT: SWAP3
431+
; CHECK-NEXT: POP
432+
; CHECK-NEXT: SWAP1
433+
; CHECK-NEXT: DUP3
434+
; CHECK-NEXT: SWAP1
435+
; CHECK-NEXT: EQ
436+
; CHECK-NEXT: ISZERO
437+
; CHECK-NEXT: SWAP2
438+
; CHECK-NEXT: SUB
439+
; CHECK-NEXT: OR
440+
; CHECK-NEXT: PUSH4 @.BB20_2
441+
; CHECK-NEXT: JUMPI
442+
; CHECK-NEXT: ; %bb.1: ; %false
443+
; CHECK-NEXT: .BB20_2: ; %true
444+
; CHECK-NEXT: JUMPDEST
445+
%cond1 = icmp ne i256 %a, %b
446+
%cond2 = icmp ne i256 %a, %c
447+
%cond = or i1 %cond1, %cond2
448+
br i1 %cond, label %true, label %false
449+
false:
450+
unreachable
451+
true:
452+
unreachable
453+
}

0 commit comments

Comments
 (0)