Open akiramenai opened 3 weeks ago
Note that sometimes, eager cleanup is preferable:
define i256 @swap_first_no_junk(i256 %a1, i256 %a2, i256 %a3, i256 %a4) nounwind {
; CHECK-LABEL: swap_first_no_junk:
; CHECK: ; %bb.0:
; CHECK-NEXT: JUMPDEST
; CHECK-NEXT: SWAP2
; CHECK-NEXT: POP
; CHECK-NEXT: POP
; CHECK-NEXT: SUB
; CHECK-NEXT: SWAP1
; CHECK-NEXT: JUMP
%x1 = sub i256 %a1, %a4
ret i256 %x1
}
Here it's better to cleanup first and then subtract.
The best way to reproduce is
declare i256 @foo(i256, i256, i256, i256)
define i256 @eager_cleanup(i256 %a1, i256 %a2, i256 %a3, i256 %a4, i256 %junk) {
%result = call i256 @foo(i256 %a1, i256 %a2, i256 %a3, i256 %a4)
ret i256 %result
}
It looks like stackification attempts to clean up the stack before doing computations. Consider the following example:
Instead of moving
%a3
on top of the stack, popping it, and then subtracting, subtracting and then cleaning up would result in better assembly:Other examples showing the same pattern can be found in
test/CodeGen/EVM/stack-ops.ll
andtest/CodeGen/EVM/stack-ops-commutable.ll
(e.g.same_arg_alive_with_junk
).