diff --git a/llvm/test/CodeGen/EVM/stack-ops-commutable.ll b/llvm/test/CodeGen/EVM/stack-ops-commutable.ll new file mode 100644 index 000000000000..9a14eb4c59cb --- /dev/null +++ b/llvm/test/CodeGen/EVM/stack-ops-commutable.ll @@ -0,0 +1,258 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc < %s | FileCheck %s + +target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256" +target triple = "evm" + +define void @no_manipulations_needed_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: no_manipulations_needed_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = add i256 %a1, %a2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +define i256 @no_manipulations_needed_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: no_manipulations_needed_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a1, %a2 + ret i256 %x1 +} + +define void @reorder_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: reorder_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = add i256 %a2, %a1 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +define i256 @reorder_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: reorder_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a2, %a1 + ret i256 %x1 +} + +define void @swap_first_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: swap_first_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = add i256 %a3, %a2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +define void @swap_second_with_junk(i256 %a1, i256 %a2, i256 %a3, i256 %a4) noreturn { +; CHECK-LABEL: swap_second_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: DUP4 +; CHECK-NEXT: ADD +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = add i256 %a1, %a4 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +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: SWAP3 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: POP +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a1, %a4 + ret i256 %x1 +} + +define i256 @swap_second_no_junk(i256 %a1, i256 %a2, i256 %a3, i256 %a4) nounwind { +; CHECK-LABEL: swap_second_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: POP +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a4, %a1 + ret i256 %x1 +} + +define void @first_arg_alive_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: first_arg_alive_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DUP4 +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = add i256 %a1, %a2 + %x2 = sub i256 %a1, 4 + %x3 = udiv i256 %x2, %x1 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x3) + unreachable +} + +define i256 @first_arg_alive_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: first_arg_alive_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: DUP1 +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: POP +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a1, %a2 + %x2 = sub i256 %a1, 4 + %x3 = udiv i256 %x2, %x1 + ret i256 %x3 +} + +define void @second_arg_alive_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: second_arg_alive_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: DUP2 +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = add i256 %a1, %a2 + %x2 = sub i256 %a2, 4 + %x3 = udiv i256 %x2, %x1 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x3) + unreachable +} + +define i256 @second_arg_alive_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: second_arg_alive_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: DUP2 +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a1, %a2 + %x2 = sub i256 %a2, 4 + %x3 = udiv i256 %x2, %x1 + ret i256 %x3 +} + +define void @both_arg_alive_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: both_arg_alive_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: ADD +; CHECK-NEXT: ADD +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = add i256 %a1, %a2 + %x2 = udiv i256 %a2, %a1 + %x3 = add i256 %x1, %x2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x3) + unreachable +} + +define i256 @both_arg_alive_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: both_arg_alive_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: ADD +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a1, %a2 + %x2 = udiv i256 %a2, %a1 + %x3 = add i256 %x1, %x2 + ret i256 %x3 +} + +define i256 @same_arg_dead_with_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: same_arg_dead_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: POP +; CHECK-NEXT: DUP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT +; CHECK-NEXT: JUMP + %x1 = add i256 %a2, %a2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + ret i256 %x1 +} + +declare void @llvm.evm.revert(ptr addrspace(1), i256) diff --git a/llvm/test/CodeGen/EVM/stack-ops.ll b/llvm/test/CodeGen/EVM/stack-ops.ll new file mode 100644 index 000000000000..88dc1a397327 --- /dev/null +++ b/llvm/test/CodeGen/EVM/stack-ops.ll @@ -0,0 +1,313 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc < %s | FileCheck %s + +target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256" +target triple = "evm" + +define void @no_manipulations_needed_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: no_manipulations_needed_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SUB +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = sub i256 %a1, %a2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +define i256 @no_manipulations_needed_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: no_manipulations_needed_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: SUB +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = sub i256 %a1, %a2 + ret i256 %x1 +} + +define void @reorder_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: reorder_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: SUB +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = sub i256 %a2, %a1 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +define i256 @reorder_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: reorder_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: SUB +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = sub i256 %a2, %a1 + ret i256 %x1 +} + +define void @swap_first_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: swap_first_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: SUB +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = sub i256 %a3, %a2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +define void @swap_second_with_junk(i256 %a1, i256 %a2, i256 %a3, i256 %a4) noreturn { +; CHECK-LABEL: swap_second_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: DUP4 +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: SUB +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = sub i256 %a1, %a4 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + unreachable +} + +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 +} + +define i256 @swap_second_no_junk(i256 %a1, i256 %a2, i256 %a3, i256 %a4) nounwind { +; CHECK-LABEL: swap_second_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: POP +; CHECK-NEXT: SUB +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = sub i256 %a4, %a1 + ret i256 %x1 +} + +define void @first_arg_alive_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: first_arg_alive_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: DUP3 +; CHECK-NEXT: DUP3 +; CHECK-NEXT: SUB +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = sub i256 %a1, %a2 + %x2 = sub i256 %a1, 4 + %x3 = udiv i256 %x2, %x1 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x3) + unreachable +} + +define i256 @first_arg_alive_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: first_arg_alive_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: DUP3 +; CHECK-NEXT: SUB +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = sub i256 %a1, %a2 + %x2 = sub i256 %a1, 4 + %x3 = udiv i256 %x2, %x1 + ret i256 %x3 +} + +define void @second_arg_alive_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: second_arg_alive_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: DUP2 +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = sub i256 %a1, %a2 + %x2 = sub i256 %a2, 4 + %x3 = udiv i256 %x2, %x1 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x3) + unreachable +} + +define i256 @second_arg_alive_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: second_arg_alive_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: DUP2 +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: PUSH1 4 +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = sub i256 %a1, %a2 + %x2 = sub i256 %a2, 4 + %x3 = udiv i256 %x2, %x1 + ret i256 %x3 +} + +define void @both_arg_alive_with_junk(i256 %a1, i256 %a2, i256 %a3) noreturn { +; CHECK-LABEL: both_arg_alive_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: ADD +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT + %x1 = sub i256 %a1, %a2 + %x2 = udiv i256 %a2, %a1 + %x3 = add i256 %x1, %x2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x3) + unreachable +} + +define i256 @both_arg_alive_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: both_arg_alive_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: POP +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: DIV +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = sub i256 %a1, %a2 + %x2 = udiv i256 %a2, %a1 + %x3 = add i256 %x1, %x2 + ret i256 %x3 +} + +define i256 @same_arg_dead_with_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: same_arg_dead_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: POP +; CHECK-NEXT: DUP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT +; CHECK-NEXT: JUMP + %x1 = add i256 %a2, %a2 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x1) + ret i256 %x1 +} + +define i256 @same_arg_dead_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: same_arg_dead_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: POP +; CHECK-NEXT: DUP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a2, %a2 + ret i256 %x1 +} + +define i256 @same_arg_alive_with_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: same_arg_alive_with_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: POP +; CHECK-NEXT: DUP1 +; CHECK-NEXT: DUP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: DUP2 +; CHECK-NEXT: PUSH0 +; CHECK-NEXT: REVERT +; CHECK-NEXT: JUMP + %x1 = add i256 %a2, %a2 + %x2 = add i256 %a2, %x1 + call void @llvm.evm.revert(ptr addrspace(1) null, i256 %x2) + ret i256 %x2 +} + +define i256 @same_arg_alive_no_junk(i256 %a1, i256 %a2, i256 %a3) nounwind { +; CHECK-LABEL: same_arg_alive_no_junk: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: POP +; CHECK-NEXT: DUP1 +; CHECK-NEXT: DUP1 +; CHECK-NEXT: ADD +; CHECK-NEXT: ADD +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: JUMP + %x1 = add i256 %a2, %a2 + %x2 = add i256 %a2, %x1 + ret i256 %x2 +} + +declare void @llvm.evm.revert(ptr addrspace(1), i256)