diff --git a/examples/sizes.txt b/examples/sizes.txt index 29120b396a..c9498983e0 100644 --- a/examples/sizes.txt +++ b/examples/sizes.txt @@ -28,6 +28,7 @@ biguint_binary_ops/BiguintBinaryOps 189 77 112 77 0 boolean_binary_ops/BooleanBinaryOps 1154 471 683 471 0 box_storage/Box 1860 1435 425 1435 0 + bug_load_store_load_store 78 73 5 73 0 bytes_ops/BiguintBinaryOps 139 139 0 139 0 calculator 349 317 32 315 2 callsub 32 32 0 32 0 diff --git a/src/puya/mir/stack_allocation/peephole.py b/src/puya/mir/stack_allocation/peephole.py index 7b623494c5..e12bd18c0d 100644 --- a/src/puya/mir/stack_allocation/peephole.py +++ b/src/puya/mir/stack_allocation/peephole.py @@ -95,12 +95,16 @@ def optimize_pair( match a, b: case mir.LoadLStack(copy=False) as load, mir.StoreLStack(copy=True): return attrs.evolve(load, copy=True), *maybe_virtuals + # consider this sequence Load*, Virtual(Store*), Virtual(Load*), Store* + # can't just remove outer virtuals because inner virtual ops assume "something" + # loaded a value onto the stack, so need to keep entire sequence around as + # virtual ops case mir.LoadXStack(), mir.StoreXStack(copy=False): - return maybe_virtuals + return mir.VirtualStackOp(a), *maybe_virtuals, mir.VirtualStackOp(b) case mir.LoadFStack(), mir.StoreFStack(): - return maybe_virtuals + return mir.VirtualStackOp(a), *maybe_virtuals, mir.VirtualStackOp(b) case mir.LoadVirtual(), mir.StoreVirtual(): - return maybe_virtuals + return mir.VirtualStackOp(a), *maybe_virtuals, mir.VirtualStackOp(b) else: match a, b: case ( diff --git a/test_cases/bug_load_store_load_store/contract.py b/test_cases/bug_load_store_load_store/contract.py new file mode 100644 index 0000000000..7b372ef9b1 --- /dev/null +++ b/test_cases/bug_load_store_load_store/contract.py @@ -0,0 +1,21 @@ +from algopy import Contract, UInt64, subroutine, urange + + +@subroutine +def get_bool() -> bool: + return True + + +class MyContract(Contract): + def approval_program(self) -> UInt64: + val = UInt64(0) + for _idx in urange(2): + if get_bool(): + pass + elif get_bool(): # noqa: SIM102 + if not get_bool(): + val += UInt64(123) + return val + + def clear_state_program(self) -> bool: + return True diff --git a/test_cases/bug_load_store_load_store/out/MyContract.approval.mir b/test_cases/bug_load_store_load_store/out/MyContract.approval.mir new file mode 100644 index 0000000000..e9af5a887b --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/MyContract.approval.mir @@ -0,0 +1,90 @@ +// Op // Op Description Stack (out) Source code Source line + +#pragma version 10 + +// test_cases.bug_load_store_load_store.contract.MyContract.approval_program() -> uint64: +main: + byte "" // allocate 1 to stack (𝕗) val#11 | + +main_block@0: + int 0 // (𝕗) val#11 | 0 UInt64(0) bug_load_store_load_store/contract.py:11 + // virtual: store val#0 to f-stack (𝕗) val#11,val#0 | val = UInt64(0) bug_load_store_load_store/contract.py:11 + int 0 // (𝕗) val#11,val#0 | 0 urange(2) bug_load_store_load_store/contract.py:12 + // virtual: store _idx#0 to f-stack (𝕗) val#11,val#0,_idx#0 | _idx bug_load_store_load_store/contract.py:12 + // Implicit fall through to main_for_header@1 // (𝕗) val#11,val#0,_idx#0 | + +main_for_header@1: + dup // load _idx#0 from f-stack (𝕗) val#11,val#0,_idx#0 | _idx#0 urange(2) bug_load_store_load_store/contract.py:12 + int 2 // (𝕗) val#11,val#0,_idx#0 | _idx#0,2 2 bug_load_store_load_store/contract.py:12 + < // (𝕗) val#11,val#0,_idx#0 | {<} urange(2) bug_load_store_load_store/contract.py:12 + // virtual: store continue_looping%0#0 to l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | continue_looping%0#0 urange(2) bug_load_store_load_store/contract.py:12 + // virtual: load continue_looping%0#0 from l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | continue_looping%0#0 for _idx in urange(2): bug_load_store_load_store/contract.py:12 + bz main_after_for@11 // (𝕗) val#11,val#0,_idx#0 | for _idx in urange(2): bug_load_store_load_store/contract.py:12 + // Implicit fall through to main_for_body@2 // (𝕗) val#11,val#0,_idx#0 | for _idx in urange(2): bug_load_store_load_store/contract.py:12 + +main_for_body@2: + callsub get_bool // (𝕗) val#11,val#0,_idx#0 | {get_bool} get_bool() bug_load_store_load_store/contract.py:13 + // virtual: store tmp%0#0 to l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | tmp%0#0 get_bool() bug_load_store_load_store/contract.py:13 + // virtual: load tmp%0#0 from l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | tmp%0#0 if get_bool(): bug_load_store_load_store/contract.py:13 + bnz main_after_if_else@9 // (𝕗) val#11,val#0,_idx#0 | if get_bool(): bug_load_store_load_store/contract.py:13 + // Implicit fall through to main_else_body@4 // (𝕗) val#11,val#0,_idx#0 | if get_bool(): bug_load_store_load_store/contract.py:13 + +main_else_body@4: + callsub get_bool // (𝕗) val#11,val#0,_idx#0 | {get_bool} get_bool() bug_load_store_load_store/contract.py:15 + // virtual: store tmp%1#0 to l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | tmp%1#0 get_bool() bug_load_store_load_store/contract.py:15 + dig 2 // load val#0 from f-stack (𝕗) val#11,val#0,_idx#0 | tmp%1#0,val#0 + bury 4 // store val#11 to f-stack (𝕗) val#11,val#0,_idx#0 | tmp%1#0 + // virtual: load tmp%1#0 from l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | tmp%1#0 elif get_bool(): # noqa: SIM102 bug_load_store_load_store/contract.py:15 + bz main_after_if_else@8 // (𝕗) val#11,val#0,_idx#0 | elif get_bool(): # noqa: SIM102 bug_load_store_load_store/contract.py:15 + // Implicit fall through to main_if_body@5 // (𝕗) val#11,val#0,_idx#0 | elif get_bool(): # noqa: SIM102 bug_load_store_load_store/contract.py:15 + +main_if_body@5: + callsub get_bool // (𝕗) val#11,val#0,_idx#0 | {get_bool} get_bool() bug_load_store_load_store/contract.py:16 + // virtual: store tmp%2#0 to l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | tmp%2#0 get_bool() bug_load_store_load_store/contract.py:16 + dig 2 // load val#0 from f-stack (𝕗) val#11,val#0,_idx#0 | tmp%2#0,val#0 + bury 4 // store val#11 to f-stack (𝕗) val#11,val#0,_idx#0 | tmp%2#0 + // virtual: load tmp%2#0 from l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | tmp%2#0 not get_bool() bug_load_store_load_store/contract.py:16 + bnz main_after_if_else@7 // (𝕗) val#11,val#0,_idx#0 | not get_bool() bug_load_store_load_store/contract.py:16 + // Implicit fall through to main_if_body@6 // (𝕗) val#11,val#0,_idx#0 | not get_bool() bug_load_store_load_store/contract.py:16 + +main_if_body@6: + dig 1 // load val#0 from f-stack (𝕗) val#11,val#0,_idx#0 | val#0 val += UInt64(123) bug_load_store_load_store/contract.py:17 + int 123 // (𝕗) val#11,val#0,_idx#0 | val#0,123 UInt64(123) bug_load_store_load_store/contract.py:17 + + // (𝕗) val#11,val#0,_idx#0 | {+} val += UInt64(123) bug_load_store_load_store/contract.py:17 + // virtual: store val#0 to l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | val#0 val += UInt64(123) bug_load_store_load_store/contract.py:17 + // virtual: load val#0 from l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | val#0 + bury 3 // store val#11 to f-stack (𝕗) val#11,val#0,_idx#0 | + // Implicit fall through to main_after_if_else@7 // (𝕗) val#11,val#0,_idx#0 | + +main_after_if_else@7: + // virtual: load val#11 (𝕗) val#11,val#0,_idx#0 | val#11 + // virtual: store val#0 to l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | val#0 + // virtual: load val#0 from l-stack (no copy) (𝕗) val#11,val#0,_idx#0 | val#0 + // virtual: store val#11 (𝕗) val#11,val#0,_idx#0 | + // Implicit fall through to main_after_if_else@8 // (𝕗) val#11,val#0,_idx#0 | + +main_after_if_else@8: + dig 2 // load val#11 from f-stack (𝕗) val#11,val#0,_idx#0 | val#11 + bury 2 // store val#0 to f-stack (𝕗) val#11,val#0,_idx#0 | + // Implicit fall through to main_after_if_else@9 // (𝕗) val#11,val#0,_idx#0 | + +main_after_if_else@9: + dup // load _idx#0 from f-stack (𝕗) val#11,val#0,_idx#0 | _idx#0 urange(2) bug_load_store_load_store/contract.py:12 + int 1 // (𝕗) val#11,val#0,_idx#0 | _idx#0,1 urange(2) bug_load_store_load_store/contract.py:12 + + // (𝕗) val#11,val#0,_idx#0 | {+} urange(2) bug_load_store_load_store/contract.py:12 + bury 1 // store _idx#0 to f-stack (𝕗) val#11,val#0,_idx#0 | urange(2) bug_load_store_load_store/contract.py:12 + b main_for_header@1 // (𝕗) val#11,val#0,_idx#0 | + +main_after_for@11: + dig 1 // load val#0 from f-stack (𝕗) val#11,val#0,_idx#0 | val#0 return val bug_load_store_load_store/contract.py:18 + return // (𝕗) val#11,val#0,_idx#0 | return val bug_load_store_load_store/contract.py:18 + + +// test_cases.bug_load_store_load_store.contract.get_bool() -> uint64: +get_bool: + proto 0 1 // @subroutine\ndef get_bool() -> bool: bug_load_store_load_store/contract.py:4-5 + +get_bool_block@0: + int 1 // 1 True bug_load_store_load_store/contract.py:6 + retsub // 1 return True bug_load_store_load_store/contract.py:6 + diff --git a/test_cases/bug_load_store_load_store/out/MyContract.approval.teal b/test_cases/bug_load_store_load_store/out/MyContract.approval.teal new file mode 100644 index 0000000000..2860e5e5d2 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/MyContract.approval.teal @@ -0,0 +1,73 @@ +#pragma version 10 + +test_cases.bug_load_store_load_store.contract.MyContract.approval_program: + byte "" + // bug_load_store_load_store/contract.py:11 + // val = UInt64(0) + int 0 + // bug_load_store_load_store/contract.py:12 + // for _idx in urange(2): + dup + +main_for_header@1: + // bug_load_store_load_store/contract.py:12 + // for _idx in urange(2): + dup + int 2 + < + bz main_after_for@11 + // bug_load_store_load_store/contract.py:13 + // if get_bool(): + callsub get_bool + bnz main_after_if_else@9 + // bug_load_store_load_store/contract.py:15 + // elif get_bool(): # noqa: SIM102 + callsub get_bool + dig 2 + bury 4 + bz main_after_if_else@8 + // bug_load_store_load_store/contract.py:16 + // if not get_bool(): + callsub get_bool + dig 2 + bury 4 + bnz main_after_if_else@7 + // bug_load_store_load_store/contract.py:17 + // val += UInt64(123) + dig 1 + int 123 + + + bury 3 + +main_after_if_else@7: + +main_after_if_else@8: + dig 2 + bury 2 + +main_after_if_else@9: + // bug_load_store_load_store/contract.py:12 + // for _idx in urange(2): + dup + int 1 + + + bury 1 + b main_for_header@1 + +main_after_for@11: + // bug_load_store_load_store/contract.py:18 + // return val + dig 1 + return + + +// test_cases.bug_load_store_load_store.contract.get_bool() -> uint64: +get_bool: + // bug_load_store_load_store/contract.py:4-5 + // @subroutine + // def get_bool() -> bool: + proto 0 1 + // bug_load_store_load_store/contract.py:6 + // return True + int 1 + retsub diff --git a/test_cases/bug_load_store_load_store/out/MyContract.clear.mir b/test_cases/bug_load_store_load_store/out/MyContract.clear.mir new file mode 100644 index 0000000000..93cb780370 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/MyContract.clear.mir @@ -0,0 +1,9 @@ +// Op // Stack (out) Source code Source line + +#pragma version 10 + +// test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program() -> uint64: +main_block@0: + int 1 // 1 True bug_load_store_load_store/contract.py:21 + return // return True bug_load_store_load_store/contract.py:21 + diff --git a/test_cases/bug_load_store_load_store/out/MyContract.clear.teal b/test_cases/bug_load_store_load_store/out/MyContract.clear.teal new file mode 100644 index 0000000000..42655fbf1f --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/MyContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program: + // bug_load_store_load_store/contract.py:21 + // return True + int 1 + return diff --git a/test_cases/bug_load_store_load_store/out/MyContract.destructured.ir b/test_cases/bug_load_store_load_store/out/MyContract.destructured.ir new file mode 100644 index 0000000000..333ae2a710 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/MyContract.destructured.ir @@ -0,0 +1,46 @@ +contract test_cases.bug_load_store_load_store.contract.MyContract: + program approval: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.approval_program() -> uint64: + block@0: // L10 + let val#0: uint64 = 0u + let _idx#0: uint64 = 0u + goto block@1 + block@1: // for_header_L12 + let continue_looping%0#0: bool = (< _idx#0 2u) + goto continue_looping%0#0 ? block@2 : block@11 + block@2: // for_body_L13 + let tmp%0#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%0#0 ? block@9 : block@4 + block@4: // else_body_L15 + let tmp%1#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + let val#11: uint64 = val#0 + goto tmp%1#0 ? block@5 : block@8 + block@5: // if_body_L16 + let tmp%2#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + let val#11: uint64 = val#0 + goto tmp%2#0 ? block@7 : block@6 + block@6: // if_body_L17 + let val#0: uint64 = (+ val#0 123u) + let val#11: uint64 = val#0 + goto block@7 + block@7: // after_if_else_L16 + let val#0: uint64 = val#11 + let val#11: uint64 = val#0 + goto block@8 + block@8: // after_if_else_L15 + let val#0: uint64 = val#11 + goto block@9 + block@9: // after_if_else_L13 + let _idx#0: uint64 = (+ _idx#0 1u) + goto block@1 + block@11: // after_for_L12 + return val#0 + + subroutine test_cases.bug_load_store_load_store.contract.get_bool() -> bool: + block@0: // L4 + return 1u + + program clear-state: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program() -> bool: + block@0: // L20 + return 1u \ No newline at end of file diff --git a/test_cases/bug_load_store_load_store/out/MyContract.ssa.ir b/test_cases/bug_load_store_load_store/out/MyContract.ssa.ir new file mode 100644 index 0000000000..3884ca7347 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/MyContract.ssa.ir @@ -0,0 +1,50 @@ +contract test_cases.bug_load_store_load_store.contract.MyContract: + program approval: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.approval_program() -> uint64: + block@0: // L10 + let val#0: uint64 = 0u + (assert 1u) // Step cannot be zero + let _idx#0: uint64 = 0u + goto block@1 + block@1: // for_header_L12 + let _idx#1: uint64 = φ(_idx#0 <- block@0, _idx#2 <- block@10) + let val#1: uint64 = φ(val#0 <- block@0, val#3 <- block@10) + let continue_looping%0#0: bool = (< _idx#1 2u) + goto continue_looping%0#0 ? block@2 : block@11 + block@2: // for_body_L13 + let tmp%0#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%0#0 ? block@3 : block@4 + block@3: // if_body_L14 + goto block@9 + block@4: // else_body_L15 + let tmp%1#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%1#0 ? block@5 : block@8 + block@5: // if_body_L16 + let tmp%2#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%2#0 ? block@7 : block@6 + block@6: // if_body_L17 + let val#2: uint64 = (+ val#1 123u) + goto block@7 + block@7: // after_if_else_L16 + let val#5: uint64 = φ(val#1 <- block@5, val#2 <- block@6) + goto block@8 + block@8: // after_if_else_L15 + let val#4: uint64 = φ(val#1 <- block@4, val#5 <- block@7) + goto block@9 + block@9: // after_if_else_L13 + let val#3: uint64 = φ(val#1 <- block@3, val#4 <- block@8) + goto block@10 + block@10: // for_footer_L12 + let _idx#2: uint64 = (+ _idx#1 1u) + goto block@1 + block@11: // after_for_L12 + return val#1 + + subroutine test_cases.bug_load_store_load_store.contract.get_bool() -> bool: + block@0: // L4 + return 1u + + program clear-state: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program() -> bool: + block@0: // L20 + return 1u \ No newline at end of file diff --git a/test_cases/bug_load_store_load_store/out/MyContract.ssa.opt_pass_1.ir b/test_cases/bug_load_store_load_store/out/MyContract.ssa.opt_pass_1.ir new file mode 100644 index 0000000000..d31ee27a35 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/MyContract.ssa.opt_pass_1.ir @@ -0,0 +1,47 @@ +contract test_cases.bug_load_store_load_store.contract.MyContract: + program approval: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.approval_program() -> uint64: + block@0: // L10 + let val#0: uint64 = 0u + let _idx#0: uint64 = 0u + goto block@1 + block@1: // for_header_L12 + let _idx#1: uint64 = φ(_idx#0 <- block@0, _idx#2 <- block@9) + let val#1: uint64 = φ(val#0 <- block@0, val#3 <- block@9) + let continue_looping%0#0: bool = (< _idx#1 2u) + goto continue_looping%0#0 ? block@2 : block@11 + block@2: // for_body_L13 + let tmp%0#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%0#0 ? block@3 : block@4 + block@3: // if_body_L14 + goto block@9 + block@4: // else_body_L15 + let tmp%1#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%1#0 ? block@5 : block@8 + block@5: // if_body_L16 + let tmp%2#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%2#0 ? block@7 : block@6 + block@6: // if_body_L17 + let val#2: uint64 = (+ val#1 123u) + goto block@7 + block@7: // after_if_else_L16 + let val#5: uint64 = φ(val#1 <- block@5, val#2 <- block@6) + goto block@8 + block@8: // after_if_else_L15 + let val#4: uint64 = φ(val#1 <- block@4, val#5 <- block@7) + goto block@9 + block@9: // after_if_else_L13 + let val#3: uint64 = φ(val#1 <- block@3, val#4 <- block@8) + let _idx#2: uint64 = (+ _idx#1 1u) + goto block@1 + block@11: // after_for_L12 + return val#1 + + subroutine test_cases.bug_load_store_load_store.contract.get_bool() -> bool: + block@0: // L4 + return 1u + + program clear-state: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program() -> bool: + block@0: // L20 + return 1u \ No newline at end of file diff --git a/test_cases/bug_load_store_load_store/out/module.awst b/test_cases/bug_load_store_load_store/out/module.awst new file mode 100644 index 0000000000..4dcc5607e0 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out/module.awst @@ -0,0 +1,28 @@ +subroutine get_bool(): bool +{ + return true +} + +contract MyContract +{ + approval_program(): uint64 + { + val: uint64 = 0u + for _idx in range(0u, 2u, 1u) { + if (test_cases.bug_load_store_load_store.contract.get_bool()) { + } else { + if (test_cases.bug_load_store_load_store.contract.get_bool()) { + if (!(test_cases.bug_load_store_load_store.contract.get_bool())) { + val += 123u + } + } + } + } + return val + } + + clear_state_program(): bool + { + return true + } +} \ No newline at end of file diff --git a/test_cases/bug_load_store_load_store/out_O2/MyContract.approval.teal b/test_cases/bug_load_store_load_store/out_O2/MyContract.approval.teal new file mode 100644 index 0000000000..1be3f987ca --- /dev/null +++ b/test_cases/bug_load_store_load_store/out_O2/MyContract.approval.teal @@ -0,0 +1,50 @@ +#pragma version 10 + +test_cases.bug_load_store_load_store.contract.MyContract.approval_program: + byte "" + int 0 + dup + +main_for_header@1: + dup + int 2 + < + bz main_after_for@11 + callsub get_bool + bnz main_after_if_else@9 + callsub get_bool + dig 2 + bury 4 + bz main_after_if_else@8 + callsub get_bool + dig 2 + bury 4 + bnz main_after_if_else@7 + dig 1 + int 123 + + + bury 3 + +main_after_if_else@7: + +main_after_if_else@8: + dig 2 + bury 2 + +main_after_if_else@9: + dup + int 1 + + + bury 1 + b main_for_header@1 + +main_after_for@11: + dig 1 + return + + +// test_cases.bug_load_store_load_store.contract.get_bool() -> uint64: +get_bool: + proto 0 1 + int 1 + retsub diff --git a/test_cases/bug_load_store_load_store/out_O2/MyContract.clear.teal b/test_cases/bug_load_store_load_store/out_O2/MyContract.clear.teal new file mode 100644 index 0000000000..bf7d887bc5 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out_O2/MyContract.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program: + int 1 + return diff --git a/test_cases/bug_load_store_load_store/out_O2/MyContract.destructured.ir b/test_cases/bug_load_store_load_store/out_O2/MyContract.destructured.ir new file mode 100644 index 0000000000..333ae2a710 --- /dev/null +++ b/test_cases/bug_load_store_load_store/out_O2/MyContract.destructured.ir @@ -0,0 +1,46 @@ +contract test_cases.bug_load_store_load_store.contract.MyContract: + program approval: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.approval_program() -> uint64: + block@0: // L10 + let val#0: uint64 = 0u + let _idx#0: uint64 = 0u + goto block@1 + block@1: // for_header_L12 + let continue_looping%0#0: bool = (< _idx#0 2u) + goto continue_looping%0#0 ? block@2 : block@11 + block@2: // for_body_L13 + let tmp%0#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%0#0 ? block@9 : block@4 + block@4: // else_body_L15 + let tmp%1#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + let val#11: uint64 = val#0 + goto tmp%1#0 ? block@5 : block@8 + block@5: // if_body_L16 + let tmp%2#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + let val#11: uint64 = val#0 + goto tmp%2#0 ? block@7 : block@6 + block@6: // if_body_L17 + let val#0: uint64 = (+ val#0 123u) + let val#11: uint64 = val#0 + goto block@7 + block@7: // after_if_else_L16 + let val#0: uint64 = val#11 + let val#11: uint64 = val#0 + goto block@8 + block@8: // after_if_else_L15 + let val#0: uint64 = val#11 + goto block@9 + block@9: // after_if_else_L13 + let _idx#0: uint64 = (+ _idx#0 1u) + goto block@1 + block@11: // after_for_L12 + return val#0 + + subroutine test_cases.bug_load_store_load_store.contract.get_bool() -> bool: + block@0: // L4 + return 1u + + program clear-state: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program() -> bool: + block@0: // L20 + return 1u \ No newline at end of file diff --git a/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.approval.teal b/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.approval.teal new file mode 100644 index 0000000000..2e4f55b52e --- /dev/null +++ b/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.approval.teal @@ -0,0 +1,78 @@ +#pragma version 10 + +test_cases.bug_load_store_load_store.contract.MyContract.approval_program: + byte "" + // bug_load_store_load_store/contract.py:11 + // val = UInt64(0) + int 0 + // bug_load_store_load_store/contract.py:12 + // for _idx in urange(2): + int 1 + assert // Step cannot be zero + int 0 + +main_for_header@1: + // bug_load_store_load_store/contract.py:12 + // for _idx in urange(2): + dup + int 2 + < + bz main_after_for@11 + // bug_load_store_load_store/contract.py:13 + // if get_bool(): + callsub get_bool + bz main_else_body@4 + b main_after_if_else@9 + +main_else_body@4: + // bug_load_store_load_store/contract.py:15 + // elif get_bool(): # noqa: SIM102 + callsub get_bool + dig 2 + bury 4 + bz main_after_if_else@8 + // bug_load_store_load_store/contract.py:16 + // if not get_bool(): + callsub get_bool + dig 2 + bury 4 + bnz main_after_if_else@7 + // bug_load_store_load_store/contract.py:17 + // val += UInt64(123) + dig 1 + int 123 + + + bury 3 + +main_after_if_else@7: + +main_after_if_else@8: + dig 2 + bury 2 + +main_after_if_else@9: + // bug_load_store_load_store/contract.py:12 + // for _idx in urange(2): + dup + int 1 + + + bury 1 + b main_for_header@1 + +main_after_for@11: + // bug_load_store_load_store/contract.py:18 + // return val + dig 1 + return + + +// test_cases.bug_load_store_load_store.contract.get_bool() -> uint64: +get_bool: + // bug_load_store_load_store/contract.py:4-5 + // @subroutine + // def get_bool() -> bool: + proto 0 1 + // bug_load_store_load_store/contract.py:6 + // return True + int 1 + retsub diff --git a/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.clear.teal b/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.clear.teal new file mode 100644 index 0000000000..42655fbf1f --- /dev/null +++ b/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program: + // bug_load_store_load_store/contract.py:21 + // return True + int 1 + return diff --git a/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.destructured.ir b/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.destructured.ir new file mode 100644 index 0000000000..b4a1c9a2bc --- /dev/null +++ b/test_cases/bug_load_store_load_store/out_unoptimized/MyContract.destructured.ir @@ -0,0 +1,51 @@ +contract test_cases.bug_load_store_load_store.contract.MyContract: + program approval: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.approval_program() -> uint64: + block@0: // L10 + let val#0: uint64 = 0u + (assert 1u) // Step cannot be zero + let _idx#0: uint64 = 0u + goto block@1 + block@1: // for_header_L12 + let continue_looping%0#0: bool = (< _idx#0 2u) + goto continue_looping%0#0 ? block@2 : block@11 + block@2: // for_body_L13 + let tmp%0#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + goto tmp%0#0 ? block@3 : block@4 + block@3: // if_body_L14 + goto block@9 + block@4: // else_body_L15 + let tmp%1#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + let val#11: uint64 = val#0 + goto tmp%1#0 ? block@5 : block@8 + block@5: // if_body_L16 + let tmp%2#0: bool = test_cases.bug_load_store_load_store.contract.get_bool() + let val#11: uint64 = val#0 + goto tmp%2#0 ? block@7 : block@6 + block@6: // if_body_L17 + let val#0: uint64 = (+ val#0 123u) + let val#11: uint64 = val#0 + goto block@7 + block@7: // after_if_else_L16 + let val#0: uint64 = val#11 + let val#11: uint64 = val#0 + goto block@8 + block@8: // after_if_else_L15 + let val#0: uint64 = val#11 + goto block@9 + block@9: // after_if_else_L13 + goto block@10 + block@10: // for_footer_L12 + let _idx#0: uint64 = (+ _idx#0 1u) + goto block@1 + block@11: // after_for_L12 + return val#0 + + subroutine test_cases.bug_load_store_load_store.contract.get_bool() -> bool: + block@0: // L4 + return 1u + + program clear-state: + subroutine test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program() -> bool: + block@0: // L20 + return 1u \ No newline at end of file diff --git a/test_cases/bug_load_store_load_store/puya.log b/test_cases/bug_load_store_load_store/puya.log new file mode 100644 index 0000000000..73cb65f386 --- /dev/null +++ b/test_cases/bug_load_store_load_store/puya.log @@ -0,0 +1,551 @@ +debug: PuyaPyOptions(output_teal=True, output_arc32=True, output_ssa_ir=True, output_optimization_ir=True, output_destructured_ir=True, output_memory_ir=True, output_bytecode=True, match_algod_bytecode=False, debug_level=1, optimization_level=1, target_avm_version=10, cli_template_definitions={}, template_vars_prefix='TMPL_', locals_coalescing_strategy=, paths=['bug_load_store_load_store'], output_awst=True, output_awst_json=False, output_client=True, log_level=) +info: Found python prefix: /.venv +info: writing bug_load_store_load_store/out/module.awst +debug: Sealing block@0: // L12 +debug: Terminated block@0: // L12 +debug: Looking for 'required_budget_with_buffer' in an unsealed block creating an incomplete Phi: block@1: // while_top_L20 +debug: Created Phi assignment: let required_budget_with_buffer#1: uint64 = undefined while trying to resolve 'required_budget_with_buffer' in block@1: // while_top_L20 +debug: Terminated block@1: // while_top_L20 +debug: Sealing block@2: // while_body_L21 +debug: Looking for 'fee_source' in an unsealed block creating an incomplete Phi: block@1: // while_top_L20 +debug: Created Phi assignment: let fee_source#1: uint64 = undefined while trying to resolve 'fee_source' in block@1: // while_top_L20 +debug: Terminated block@2: // while_body_L21 +debug: Sealing block@3: // switch_case_0_L28 +debug: Terminated block@3: // switch_case_0_L28 +debug: Sealing block@4: // switch_case_1_L30 +debug: Terminated block@4: // switch_case_1_L30 +debug: Sealing block@5: // switch_case_default_L26 +debug: Terminated block@5: // switch_case_default_L26 +debug: Sealing block@6: // switch_case_next_L26 +debug: Terminated block@6: // switch_case_next_L26 +debug: Sealing block@1: // while_top_L20 +debug: Added required_budget_with_buffer#0 to Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0) in block@0: // L12 +debug: Created Phi assignment: let required_budget_with_buffer#2: uint64 = undefined while trying to resolve 'required_budget_with_buffer' in block@6: // switch_case_next_L26 +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3) in block@3: // switch_case_0_L28 +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4) in block@4: // switch_case_1_L30 +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) in block@5: // switch_case_default_L26 +debug: Replacing trivial Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) (required_budget_with_buffer#2) with required_budget_with_buffer#1 +debug: Deleting Phi assignment: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) +debug: Replaced trivial Phi node: let required_budget_with_buffer#2: uint64 = φ(required_budget_with_buffer#1 <- block@3, required_budget_with_buffer#1 <- block@4, required_budget_with_buffer#1 <- block@5) (required_budget_with_buffer#2) with required_budget_with_buffer#1 in current definition for 1 blocks +debug: Added required_budget_with_buffer#1 to Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) in block@6: // switch_case_next_L26 +debug: Replacing trivial Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) (required_budget_with_buffer#1) with required_budget_with_buffer#0 +debug: Deleting Phi assignment: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) +debug: Replaced trivial Phi node: let required_budget_with_buffer#1: uint64 = φ(required_budget_with_buffer#0 <- block@0, required_budget_with_buffer#1 <- block@6) (required_budget_with_buffer#1) with required_budget_with_buffer#0 in current definition for 6 blocks +debug: Added fee_source#0 to Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0) in block@0: // L12 +debug: Created Phi assignment: let fee_source#2: uint64 = undefined while trying to resolve 'fee_source' in block@6: // switch_case_next_L26 +debug: Added fee_source#1 to Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3) in block@3: // switch_case_0_L28 +debug: Added fee_source#1 to Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4) in block@4: // switch_case_1_L30 +debug: Added fee_source#1 to Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) in block@5: // switch_case_default_L26 +debug: Replacing trivial Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) (fee_source#2) with fee_source#1 +debug: Deleting Phi assignment: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) +debug: Replaced trivial Phi node: let fee_source#2: uint64 = φ(fee_source#1 <- block@3, fee_source#1 <- block@4, fee_source#1 <- block@5) (fee_source#2) with fee_source#1 in current definition for 1 blocks +debug: Added fee_source#1 to Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) in block@6: // switch_case_next_L26 +debug: Replacing trivial Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) (fee_source#1) with fee_source#0 +debug: Deleting Phi assignment: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) +debug: Replaced trivial Phi node: let fee_source#1: uint64 = φ(fee_source#0 <- block@0, fee_source#1 <- block@6) (fee_source#1) with fee_source#0 in current definition for 6 blocks +debug: Sealing block@7: // after_while_L20 +debug: Terminated block@7: // after_while_L20 +debug: Sealing block@0: // L4 +debug: Terminated block@0: // L4 +debug: Looking for 'start' in an unsealed block creating an incomplete Phi: block@1: // while_top_L11 +debug: Created Phi assignment: let start#1: uint64 = undefined while trying to resolve 'start' in block@1: // while_top_L11 +debug: Looking for 'item' in an unsealed block creating an incomplete Phi: block@1: // while_top_L11 +debug: Created Phi assignment: let item#1: bytes = undefined while trying to resolve 'item' in block@1: // while_top_L11 +debug: Looking for 'sequence' in an unsealed block creating an incomplete Phi: block@1: // while_top_L11 +debug: Created Phi assignment: let sequence#1: bytes = undefined while trying to resolve 'sequence' in block@1: // while_top_L11 +debug: Terminated block@1: // while_top_L11 +debug: Sealing block@2: // while_body_L12 +debug: Terminated block@2: // while_body_L12 +debug: Sealing block@3: // if_body_L13 +debug: Terminated block@3: // if_body_L13 +debug: Sealing block@4: // after_if_else_L12 +debug: Terminated block@4: // after_if_else_L12 +debug: Sealing block@1: // while_top_L11 +debug: Added start#0 to Phi node: let start#1: uint64 = φ(start#0 <- block@0) in block@0: // L4 +debug: Added start#2 to Phi node: let start#1: uint64 = φ(start#0 <- block@0, start#2 <- block@4) in block@4: // after_if_else_L12 +debug: Added item#0 to Phi node: let item#1: bytes = φ(item#0 <- block@0) in block@0: // L4 +debug: Added item#1 to Phi node: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) in block@4: // after_if_else_L12 +debug: Replacing trivial Phi node: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) (item#1) with item#0 +debug: Deleting Phi assignment: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) +debug: Replaced trivial Phi node: let item#1: bytes = φ(item#0 <- block@0, item#1 <- block@4) (item#1) with item#0 in current definition for 3 blocks +debug: Added sequence#0 to Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0) in block@0: // L4 +debug: Added sequence#1 to Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) in block@4: // after_if_else_L12 +debug: Replacing trivial Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) (sequence#1) with sequence#0 +debug: Deleting Phi assignment: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) +debug: Replaced trivial Phi node: let sequence#1: bytes = φ(sequence#0 <- block@0, sequence#1 <- block@4) (sequence#1) with sequence#0 in current definition for 3 blocks +debug: Sealing block@5: // after_while_L11 +debug: Terminated block@5: // after_while_L11 +debug: Sealing block@0: // L25 +debug: Terminated block@0: // L25 +debug: Sealing block@0: // L44 +debug: Terminated block@0: // L44 +debug: Sealing block@0: // L62 +debug: Terminated block@0: // L62 +debug: Sealing block@0: // L92 +debug: Terminated block@0: // L92 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L110 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L110 +debug: Terminated block@1: // for_header_L110 +debug: Sealing block@2: // for_body_L111 +debug: Looking for 'head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L110 +debug: Created Phi assignment: let head_and_tail#1: bytes = undefined while trying to resolve 'head_and_tail' in block@1: // for_header_L110 +debug: Looking for 'new_head' in an unsealed block creating an incomplete Phi: block@1: // for_header_L110 +debug: Created Phi assignment: let new_head#1: bytes = undefined while trying to resolve 'new_head' in block@1: // for_header_L110 +debug: Terminated block@2: // for_body_L111 +debug: Sealing block@3: // for_footer_L110 +debug: Terminated block@3: // for_footer_L110 +debug: Sealing block@1: // for_header_L110 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L92 +debug: Added head_offset#2 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#2 <- block@3) in block@3: // for_footer_L110 +debug: Added head_and_tail#0 to Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0) in block@0: // L92 +debug: Added head_and_tail#1 to Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) (head_and_tail#1) with head_and_tail#0 +debug: Deleting Phi assignment: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) +debug: Replaced trivial Phi node: let head_and_tail#1: bytes = φ(head_and_tail#0 <- block@0, head_and_tail#1 <- block@3) (head_and_tail#1) with head_and_tail#0 in current definition for 3 blocks +debug: Added new_head#0 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0) in block@0: // L92 +debug: Added new_head#2 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0, new_head#2 <- block@3) in block@3: // for_footer_L110 +debug: Sealing block@4: // after_for_L110 +debug: Created Phi assignment: let length_minus_1#1: uint64 = undefined while trying to resolve 'length_minus_1' in block@1: // for_header_L110 +debug: Added length_minus_1#0 to Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0) in block@0: // L92 +debug: Added length_minus_1#1 to Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) (length_minus_1#1) with length_minus_1#0 +debug: Deleting Phi assignment: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) +debug: Replaced trivial Phi node: let length_minus_1#1: uint64 = φ(length_minus_1#0 <- block@0, length_minus_1#1 <- block@3) (length_minus_1#1) with length_minus_1#0 in current definition for 3 blocks +debug: Created Phi assignment: let popped_header_offset#1: uint64 = undefined while trying to resolve 'popped_header_offset' in block@1: // for_header_L110 +debug: Added popped_header_offset#0 to Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0) in block@0: // L92 +debug: Added popped_header_offset#1 to Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) (popped_header_offset#1) with popped_header_offset#0 +debug: Deleting Phi assignment: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) +debug: Replaced trivial Phi node: let popped_header_offset#1: uint64 = φ(popped_header_offset#0 <- block@0, popped_header_offset#1 <- block@3) (popped_header_offset#1) with popped_header_offset#0 in current definition for 3 blocks +debug: Created Phi assignment: let popped_offset#1: uint64 = undefined while trying to resolve 'popped_offset' in block@1: // for_header_L110 +debug: Added popped_offset#0 to Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0) in block@0: // L92 +debug: Added popped_offset#1 to Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) (popped_offset#1) with popped_offset#0 +debug: Deleting Phi assignment: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) +debug: Replaced trivial Phi node: let popped_offset#1: uint64 = φ(popped_offset#0 <- block@0, popped_offset#1 <- block@3) (popped_offset#1) with popped_offset#0 in current definition for 3 blocks +debug: Created Phi assignment: let popped#1: bytes = undefined while trying to resolve 'popped' in block@1: // for_header_L110 +debug: Added popped#0 to Phi node: let popped#1: bytes = φ(popped#0 <- block@0) in block@0: // L92 +debug: Added popped#1 to Phi node: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) in block@3: // for_footer_L110 +debug: Replacing trivial Phi node: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) (popped#1) with popped#0 +debug: Deleting Phi assignment: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) +debug: Replaced trivial Phi node: let popped#1: bytes = φ(popped#0 <- block@0, popped#1 <- block@3) (popped#1) with popped#0 in current definition for 3 blocks +debug: Terminated block@4: // after_for_L110 +debug: Sealing block@0: // L124 +debug: Terminated block@0: // L124 +debug: Sealing block@1: // if_body_L147 +debug: Terminated block@1: // if_body_L147 +debug: Sealing block@2: // after_if_else_L146 +debug: Created Phi assignment: let array_length#1: uint64 = undefined while trying to resolve 'array_length' in block@2: // after_if_else_L146 +debug: Added array_length#0 to Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0) in block@0: // L124 +debug: Added array_length#0 to Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) (array_length#1) with array_length#0 +debug: Deleting Phi assignment: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) +debug: Replaced trivial Phi node: let array_length#1: uint64 = φ(array_length#0 <- block@0, array_length#0 <- block@1) (array_length#1) with array_length#0 in current definition for 1 blocks +debug: Created Phi assignment: let is_packed#1: bool = undefined while trying to resolve 'is_packed' in block@2: // after_if_else_L146 +debug: Added is_packed#0 to Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0) in block@0: // L124 +debug: Added is_packed#0 to Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) (is_packed#1) with is_packed#0 +debug: Deleting Phi assignment: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) +debug: Replaced trivial Phi node: let is_packed#1: bool = φ(is_packed#0 <- block@0, is_packed#0 <- block@1) (is_packed#1) with is_packed#0 in current definition for 1 blocks +debug: Created Phi assignment: let new_items_count#1: uint64 = undefined while trying to resolve 'new_items_count' in block@2: // after_if_else_L146 +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0) in block@0: // L124 +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) (new_items_count#1) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) +debug: Replaced trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#0 <- block@1) (new_items_count#1) with new_items_count#0 in current definition for 1 blocks +debug: Terminated block@2: // after_if_else_L146 +debug: Looking for 'i' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let i#1: uint64 = undefined while trying to resolve 'i' in block@3: // for_header_L150 +debug: Terminated block@3: // for_header_L150 +debug: Sealing block@4: // for_body_L151 +debug: Looking for 'result' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let result#2: bytes = undefined while trying to resolve 'result' in block@3: // for_header_L150 +debug: Looking for 'write_offset' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let write_offset#1: uint64 = undefined while trying to resolve 'write_offset' in block@3: // for_header_L150 +debug: Looking for 'new_items_bytes' in an unsealed block creating an incomplete Phi: block@3: // for_header_L150 +debug: Created Phi assignment: let new_items_bytes#1: bytes = undefined while trying to resolve 'new_items_bytes' in block@3: // for_header_L150 +debug: Terminated block@4: // for_body_L151 +debug: Sealing block@5: // for_footer_L150 +debug: Terminated block@5: // for_footer_L150 +debug: Sealing block@3: // for_header_L150 +debug: Added i#0 to Phi node: let i#1: uint64 = φ(i#0 <- block@2) in block@2: // after_if_else_L146 +debug: Added i#2 to Phi node: let i#1: uint64 = φ(i#0 <- block@2, i#2 <- block@5) in block@5: // for_footer_L150 +debug: Created Phi assignment: let result#4: bytes = undefined while trying to resolve 'result' in block@2: // after_if_else_L146 +debug: Added result#0 to Phi node: let result#4: bytes = φ(result#0 <- block@0) in block@0: // L124 +debug: Added result#1 to Phi node: let result#4: bytes = φ(result#0 <- block@0, result#1 <- block@1) in block@1: // if_body_L147 +debug: Added result#4 to Phi node: let result#2: bytes = φ(result#4 <- block@2) in block@2: // after_if_else_L146 +debug: Added result#3 to Phi node: let result#2: bytes = φ(result#4 <- block@2, result#3 <- block@5) in block@5: // for_footer_L150 +debug: Added write_offset#0 to Phi node: let write_offset#1: uint64 = φ(write_offset#0 <- block@2) in block@2: // after_if_else_L146 +debug: Added write_offset#2 to Phi node: let write_offset#1: uint64 = φ(write_offset#0 <- block@2, write_offset#2 <- block@5) in block@5: // for_footer_L150 +debug: Created Phi assignment: let new_items_bytes#2: bytes = undefined while trying to resolve 'new_items_bytes' in block@2: // after_if_else_L146 +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0) in block@0: // L124 +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) in block@1: // if_body_L147 +debug: Replacing trivial Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) (new_items_bytes#2) with new_items_bytes#0 +debug: Deleting Phi assignment: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) +debug: Replaced trivial Phi node: let new_items_bytes#2: bytes = φ(new_items_bytes#0 <- block@0, new_items_bytes#0 <- block@1) (new_items_bytes#2) with new_items_bytes#0 in current definition for 1 blocks +debug: Added new_items_bytes#0 to Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2) in block@2: // after_if_else_L146 +debug: Added new_items_bytes#1 to Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) in block@5: // for_footer_L150 +debug: Replacing trivial Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) (new_items_bytes#1) with new_items_bytes#0 +debug: Deleting Phi assignment: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) +debug: Replaced trivial Phi node: let new_items_bytes#1: bytes = φ(new_items_bytes#0 <- block@2, new_items_bytes#1 <- block@5) (new_items_bytes#1) with new_items_bytes#0 in current definition for 3 blocks +debug: Sealing block@6: // after_for_L150 +debug: Terminated block@6: // after_for_L150 +debug: Sealing block@0: // L157 +debug: Terminated block@0: // L157 +debug: Sealing block@0: // L189 +debug: Terminated block@0: // L189 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L199 +debug: Terminated block@1: // for_header_L199 +debug: Sealing block@2: // for_body_L200 +debug: Looking for 'array_head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let array_head_and_tail#1: bytes = undefined while trying to resolve 'array_head_and_tail' in block@1: // for_header_L199 +debug: Looking for 'new_head' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let new_head#1: bytes = undefined while trying to resolve 'new_head' in block@1: // for_header_L199 +debug: Looking for 'item_offset_adjustment' in an unsealed block creating an incomplete Phi: block@1: // for_header_L199 +debug: Created Phi assignment: let item_offset_adjustment#1: uint64 = undefined while trying to resolve 'item_offset_adjustment' in block@1: // for_header_L199 +debug: Terminated block@2: // for_body_L200 +debug: Sealing block@3: // for_footer_L199 +debug: Terminated block@3: // for_footer_L199 +debug: Sealing block@1: // for_header_L199 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L189 +debug: Added head_offset#2 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#2 <- block@3) in block@3: // for_footer_L199 +debug: Added array_head_and_tail#0 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0) in block@0: // L189 +debug: Added array_head_and_tail#1 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) (array_head_and_tail#1) with array_head_and_tail#0 +debug: Deleting Phi assignment: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) +debug: Replaced trivial Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#1 <- block@3) (array_head_and_tail#1) with array_head_and_tail#0 in current definition for 3 blocks +debug: Added new_head#0 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0) in block@0: // L189 +debug: Added new_head#2 to Phi node: let new_head#1: bytes = φ(new_head#0 <- block@0, new_head#2 <- block@3) in block@3: // for_footer_L199 +debug: Added item_offset_adjustment#0 to Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0) in block@0: // L189 +debug: Added item_offset_adjustment#1 to Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) (item_offset_adjustment#1) with item_offset_adjustment#0 +debug: Deleting Phi assignment: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) +debug: Replaced trivial Phi node: let item_offset_adjustment#1: uint64 = φ(item_offset_adjustment#0 <- block@0, item_offset_adjustment#1 <- block@3) (item_offset_adjustment#1) with item_offset_adjustment#0 in current definition for 3 blocks +debug: Sealing block@4: // after_for_L199 +debug: Created Phi assignment: let new_items_count#1: uint64 = undefined while trying to resolve 'new_items_count' in block@1: // for_header_L199 +debug: Added new_items_count#0 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0) in block@0: // L189 +debug: Added new_items_count#1 to Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) (new_items_count#1) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) +debug: Replaced trivial Phi node: let new_items_count#1: uint64 = φ(new_items_count#0 <- block@0, new_items_count#1 <- block@3) (new_items_count#1) with new_items_count#0 in current definition for 3 blocks +debug: Terminated block@4: // after_for_L199 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let head_offset#4: uint64 = undefined while trying to resolve 'head_offset' in block@5: // for_header_L204 +debug: Terminated block@5: // for_header_L204 +debug: Sealing block@6: // for_body_L205 +debug: Looking for 'new_head_and_tail' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let new_head_and_tail#1: bytes = undefined while trying to resolve 'new_head_and_tail' in block@5: // for_header_L204 +debug: Looking for 'new_head' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let new_head#3: bytes = undefined while trying to resolve 'new_head' in block@5: // for_header_L204 +debug: Looking for 'item_offset_adjustment' in an unsealed block creating an incomplete Phi: block@5: // for_header_L204 +debug: Created Phi assignment: let item_offset_adjustment#3: uint64 = undefined while trying to resolve 'item_offset_adjustment' in block@5: // for_header_L204 +debug: Terminated block@6: // for_body_L205 +debug: Sealing block@7: // for_footer_L204 +debug: Terminated block@7: // for_footer_L204 +debug: Sealing block@5: // for_header_L204 +debug: Added head_offset#3 to Phi node: let head_offset#4: uint64 = φ(head_offset#3 <- block@4) in block@4: // after_for_L199 +debug: Added head_offset#5 to Phi node: let head_offset#4: uint64 = φ(head_offset#3 <- block@4, head_offset#5 <- block@7) in block@7: // for_footer_L204 +debug: Created Phi assignment: let new_head_and_tail#2: bytes = undefined while trying to resolve 'new_head_and_tail' in block@1: // for_header_L199 +debug: Added new_head_and_tail#0 to Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0) in block@0: // L189 +debug: Added new_head_and_tail#2 to Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) (new_head_and_tail#2) with new_head_and_tail#0 +debug: Deleting Phi assignment: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) +debug: Replaced trivial Phi node: let new_head_and_tail#2: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) (new_head_and_tail#2) with new_head_and_tail#0 in current definition for 3 blocks +debug: Added new_head_and_tail#0 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4) in block@4: // after_for_L199 +debug: Added new_head_and_tail#1 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) (new_head_and_tail#1) with new_head_and_tail#0 +debug: Deleting Phi assignment: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) +debug: Replaced trivial Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@4, new_head_and_tail#1 <- block@7) (new_head_and_tail#1) with new_head_and_tail#0 in current definition for 3 blocks +debug: Added new_head#1 to Phi node: let new_head#3: bytes = φ(new_head#1 <- block@4) in block@4: // after_for_L199 +debug: Added new_head#4 to Phi node: let new_head#3: bytes = φ(new_head#1 <- block@4, new_head#4 <- block@7) in block@7: // for_footer_L204 +debug: Added item_offset_adjustment#2 to Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4) in block@4: // after_for_L199 +debug: Added item_offset_adjustment#3 to Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) (item_offset_adjustment#3) with item_offset_adjustment#2 +debug: Deleting Phi assignment: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) +debug: Replaced trivial Phi node: let item_offset_adjustment#3: uint64 = φ(item_offset_adjustment#2 <- block@4, item_offset_adjustment#3 <- block@7) (item_offset_adjustment#3) with item_offset_adjustment#2 in current definition for 3 blocks +debug: Sealing block@8: // after_for_L204 +debug: Created Phi assignment: let array_items_count#1: uint64 = undefined while trying to resolve 'array_items_count' in block@5: // for_header_L204 +debug: Created Phi assignment: let array_items_count#2: uint64 = undefined while trying to resolve 'array_items_count' in block@1: // for_header_L199 +debug: Added array_items_count#0 to Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0) in block@0: // L189 +debug: Added array_items_count#2 to Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) in block@3: // for_footer_L199 +debug: Replacing trivial Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) (array_items_count#2) with array_items_count#0 +debug: Deleting Phi assignment: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) +debug: Replaced trivial Phi node: let array_items_count#2: uint64 = φ(array_items_count#0 <- block@0, array_items_count#2 <- block@3) (array_items_count#2) with array_items_count#0 in current definition for 3 blocks +debug: Added array_items_count#0 to Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4) in block@4: // after_for_L199 +debug: Added array_items_count#1 to Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) (array_items_count#1) with array_items_count#0 +debug: Deleting Phi assignment: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) +debug: Replaced trivial Phi node: let array_items_count#1: uint64 = φ(array_items_count#0 <- block@4, array_items_count#1 <- block@7) (array_items_count#1) with array_items_count#0 in current definition for 3 blocks +debug: Created Phi assignment: let new_items_count#2: uint64 = undefined while trying to resolve 'new_items_count' in block@5: // for_header_L204 +debug: Added new_items_count#0 to Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4) in block@4: // after_for_L199 +debug: Added new_items_count#2 to Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) (new_items_count#2) with new_items_count#0 +debug: Deleting Phi assignment: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) +debug: Replaced trivial Phi node: let new_items_count#2: uint64 = φ(new_items_count#0 <- block@4, new_items_count#2 <- block@7) (new_items_count#2) with new_items_count#0 in current definition for 3 blocks +debug: Created Phi assignment: let array_head_and_tail#2: bytes = undefined while trying to resolve 'array_head_and_tail' in block@5: // for_header_L204 +debug: Added array_head_and_tail#0 to Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4) in block@4: // after_for_L199 +debug: Added array_head_and_tail#2 to Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) in block@7: // for_footer_L204 +debug: Replacing trivial Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) (array_head_and_tail#2) with array_head_and_tail#0 +debug: Deleting Phi assignment: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) +debug: Replaced trivial Phi node: let array_head_and_tail#2: bytes = φ(array_head_and_tail#0 <- block@4, array_head_and_tail#2 <- block@7) (array_head_and_tail#2) with array_head_and_tail#0 in current definition for 3 blocks +debug: Terminated block@8: // after_for_L204 +debug: Sealing block@0: // L217 +debug: Terminated block@0: // L217 +debug: Sealing block@0: // L240 +debug: Terminated block@0: // L240 +debug: Sealing block@0: // L252 +debug: Terminated block@0: // L252 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L269 +debug: Terminated block@1: // for_header_L269 +debug: Sealing block@2: // for_body_L270 +debug: Looking for 'new_head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let new_head_and_tail#1: bytes = undefined while trying to resolve 'new_head_and_tail' in block@1: // for_header_L269 +debug: Looking for 'new_item_length' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let new_item_length#1: uint64 = undefined while trying to resolve 'new_item_length' in block@1: // for_header_L269 +debug: Looking for 'original_item_length' in an unsealed block creating an incomplete Phi: block@1: // for_header_L269 +debug: Created Phi assignment: let original_item_length#1: uint64 = undefined while trying to resolve 'original_item_length' in block@1: // for_header_L269 +debug: Terminated block@2: // for_body_L270 +debug: Sealing block@3: // for_footer_L269 +debug: Terminated block@3: // for_footer_L269 +debug: Sealing block@1: // for_header_L269 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L252 +debug: Added head_offset#2 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#2 <- block@3) in block@3: // for_footer_L269 +debug: Added new_head_and_tail#0 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@0) in block@0: // L252 +debug: Added new_head_and_tail#2 to Phi node: let new_head_and_tail#1: bytes = φ(new_head_and_tail#0 <- block@0, new_head_and_tail#2 <- block@3) in block@3: // for_footer_L269 +debug: Added new_item_length#0 to Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0) in block@0: // L252 +debug: Added new_item_length#1 to Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) in block@3: // for_footer_L269 +debug: Replacing trivial Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) (new_item_length#1) with new_item_length#0 +debug: Deleting Phi assignment: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) +debug: Replaced trivial Phi node: let new_item_length#1: uint64 = φ(new_item_length#0 <- block@0, new_item_length#1 <- block@3) (new_item_length#1) with new_item_length#0 in current definition for 3 blocks +debug: Added original_item_length#0 to Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0) in block@0: // L252 +debug: Added original_item_length#1 to Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) in block@3: // for_footer_L269 +debug: Replacing trivial Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) (original_item_length#1) with original_item_length#0 +debug: Deleting Phi assignment: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) +debug: Replaced trivial Phi node: let original_item_length#1: uint64 = φ(original_item_length#0 <- block@0, original_item_length#1 <- block@3) (original_item_length#1) with original_item_length#0 in current definition for 3 blocks +debug: Sealing block@4: // after_for_L269 +debug: Terminated block@4: // after_for_L269 +debug: Sealing block@0: // L278 +debug: Terminated block@0: // L278 +debug: Sealing block@0: // L306 +debug: Terminated block@0: // L306 +debug: Looking for 'head_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L327 +debug: Created Phi assignment: let head_offset#1: uint64 = undefined while trying to resolve 'head_offset' in block@1: // for_header_L327 +debug: Terminated block@1: // for_header_L327 +debug: Sealing block@2: // for_body_L328 +debug: Looking for 'tail_offset' in an unsealed block creating an incomplete Phi: block@1: // for_header_L327 +debug: Created Phi assignment: let tail_offset#1: uint64 = undefined while trying to resolve 'tail_offset' in block@1: // for_header_L327 +debug: Looking for 'array_head_and_tail' in an unsealed block creating an incomplete Phi: block@1: // for_header_L327 +debug: Created Phi assignment: let array_head_and_tail#1: bytes = undefined while trying to resolve 'array_head_and_tail' in block@1: // for_header_L327 +debug: Terminated block@2: // for_body_L328 +debug: Sealing block@3: // for_footer_L327 +debug: Terminated block@3: // for_footer_L327 +debug: Sealing block@1: // for_header_L327 +debug: Added head_offset#0 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0) in block@0: // L306 +debug: Added head_offset#3 to Phi node: let head_offset#1: uint64 = φ(head_offset#0 <- block@0, head_offset#3 <- block@3) in block@3: // for_footer_L327 +debug: Added tail_offset#0 to Phi node: let tail_offset#1: uint64 = φ(tail_offset#0 <- block@0) in block@0: // L306 +debug: Added tail_offset#2 to Phi node: let tail_offset#1: uint64 = φ(tail_offset#0 <- block@0, tail_offset#2 <- block@3) in block@3: // for_footer_L327 +debug: Added array_head_and_tail#0 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0) in block@0: // L306 +debug: Added array_head_and_tail#2 to Phi node: let array_head_and_tail#1: bytes = φ(array_head_and_tail#0 <- block@0, array_head_and_tail#2 <- block@3) in block@3: // for_footer_L327 +debug: Sealing block@4: // after_for_L327 +debug: Terminated block@4: // after_for_L327 +debug: Sealing block@0: // L9 +debug: Terminated block@0: // L9 +debug: Sealing block@1: // abi_routing_L9 +debug: Terminated block@1: // abi_routing_L9 +debug: Sealing block@2: // bare_routing_L9 +debug: Terminated block@2: // bare_routing_L9 +debug: Sealing block@3: // after_if_else_L9 +debug: Terminated block@3: // after_if_else_L9 +debug: Sealing block@0: // L4 +debug: Terminated block@0: // L4 +debug: Sealing block@0: // L10 +debug: Terminated block@0: // L10 +debug: Looking for '_idx' in an unsealed block creating an incomplete Phi: block@1: // for_header_L12 +debug: Created Phi assignment: let _idx#1: uint64 = undefined while trying to resolve '_idx' in block@1: // for_header_L12 +debug: Terminated block@1: // for_header_L12 +debug: Sealing block@2: // for_body_L13 +debug: Terminated block@2: // for_body_L13 +debug: Sealing block@3: // if_body_L14 +debug: Terminated block@3: // if_body_L14 +debug: Sealing block@4: // else_body_L15 +debug: Terminated block@4: // else_body_L15 +debug: Sealing block@5: // if_body_L16 +debug: Terminated block@5: // if_body_L16 +debug: Sealing block@6: // if_body_L17 +debug: Looking for 'val' in an unsealed block creating an incomplete Phi: block@1: // for_header_L12 +debug: Created Phi assignment: let val#1: uint64 = undefined while trying to resolve 'val' in block@1: // for_header_L12 +debug: Terminated block@6: // if_body_L17 +debug: Sealing block@7: // after_if_else_L16 +debug: Terminated block@7: // after_if_else_L16 +debug: Sealing block@8: // after_if_else_L15 +debug: Terminated block@8: // after_if_else_L15 +debug: Sealing block@9: // after_if_else_L13 +debug: Terminated block@9: // after_if_else_L13 +debug: Sealing block@10: // for_footer_L12 +debug: Terminated block@10: // for_footer_L12 +debug: Sealing block@1: // for_header_L12 +debug: Added _idx#0 to Phi node: let _idx#1: uint64 = φ(_idx#0 <- block@0) in block@0: // L10 +debug: Added _idx#2 to Phi node: let _idx#1: uint64 = φ(_idx#0 <- block@0, _idx#2 <- block@10) in block@10: // for_footer_L12 +debug: Added val#0 to Phi node: let val#1: uint64 = φ(val#0 <- block@0) in block@0: // L10 +debug: Created Phi assignment: let val#3: uint64 = undefined while trying to resolve 'val' in block@9: // after_if_else_L13 +debug: Added val#1 to Phi node: let val#3: uint64 = φ(val#1 <- block@3) in block@3: // if_body_L14 +debug: Created Phi assignment: let val#4: uint64 = undefined while trying to resolve 'val' in block@8: // after_if_else_L15 +debug: Added val#1 to Phi node: let val#4: uint64 = φ(val#1 <- block@4) in block@4: // else_body_L15 +debug: Created Phi assignment: let val#5: uint64 = undefined while trying to resolve 'val' in block@7: // after_if_else_L16 +debug: Added val#1 to Phi node: let val#5: uint64 = φ(val#1 <- block@5) in block@5: // if_body_L16 +debug: Added val#2 to Phi node: let val#5: uint64 = φ(val#1 <- block@5, val#2 <- block@6) in block@6: // if_body_L17 +debug: Added val#5 to Phi node: let val#4: uint64 = φ(val#1 <- block@4, val#5 <- block@7) in block@7: // after_if_else_L16 +debug: Added val#4 to Phi node: let val#3: uint64 = φ(val#1 <- block@3, val#4 <- block@8) in block@8: // after_if_else_L15 +debug: Added val#3 to Phi node: let val#1: uint64 = φ(val#0 <- block@0, val#3 <- block@10) in block@10: // for_footer_L12 +debug: Sealing block@11: // after_for_L12 +debug: Terminated block@11: // after_for_L12 +debug: Sealing block@0: // L20 +debug: Terminated block@0: // L20 +debug: Output IR to bug_load_store_load_store/out/MyContract.ssa.ir +info: optimizing test_cases.bug_load_store_load_store.contract.MyContract at level 1 +debug: Begin optimization pass 1/100 +debug: Optimizing subroutine test_cases.bug_load_store_load_store.contract.MyContract.approval_program +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Replaced predecessor block@10: // for_footer_L12 with block@9: // after_if_else_L13 in block@1: // for_header_L12 +debug: Merged linear block@10: // for_footer_L12 into block@9: // after_if_else_L13 +debug: Optimizer: Remove Empty Blocks +debug: Not removing empty block block@3: // if_body_L14 because it's used by phi nodes +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.bug_load_store_load_store.contract.get_bool +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program +debug: Splitting parallel copies prior to optimization +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Output IR to bug_load_store_load_store/out/MyContract.ssa.opt_pass_1.ir +debug: Begin optimization pass 2/100 +debug: Optimizing subroutine test_cases.bug_load_store_load_store.contract.MyContract.approval_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Not removing empty block block@3: // if_body_L14 because it's used by phi nodes +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.bug_load_store_load_store.contract.get_bool +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: Optimizing subroutine test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program +debug: Optimizer: Constant Replacer +debug: Optimizer: Copy Propagation +debug: Optimizer: Intrinsic Simplifier +debug: Optimizer: Remove Unused Variables +debug: Optimizer: Inner Txn Field Replacer +debug: Optimizer: Replace Compiled References +debug: Optimizer: Simplify Control Ops +debug: Optimizer: Remove Linear Jump +debug: Optimizer: Remove Empty Blocks +debug: Optimizer: Remove Unreachable Blocks +debug: Optimizer: Repeated Expression Elimination +debug: Optimizer: Remove Calls To No Op Subroutines +debug: No optimizations performed in pass 2, ending loop +debug: Removing Phis from test_cases.bug_load_store_load_store.contract.MyContract.approval_program +debug: Removing Phis from test_cases.bug_load_store_load_store.contract.get_bool +debug: Removing Phis from test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program +debug: Coalescing local variables in test_cases.bug_load_store_load_store.contract.MyContract.approval_program using strategy RootOperandGrouping +debug: Coalescing val#0 with [val#8, val#1, val#17, val#2, val#5, val#4, val#3] +debug: Coalescing val#11 with [val#14] +debug: Coalescing _idx#0 with [_idx#5, _idx#1, _idx#2] +debug: Coalescing resulted in 31 replacement/s +debug: Coalescing local variables in test_cases.bug_load_store_load_store.contract.get_bool using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Coalescing local variables in test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program using strategy RootOperandGrouping +debug: Coalescing resulted in 0 replacement/s +debug: Sequentializing parallel copies in test_cases.bug_load_store_load_store.contract.MyContract.approval_program +debug: loc: {_idx#0=_idx#0, val#0=val#0} +debug: pred: {_idx#0=_idx#0, val#0=val#0} +debug: ready: +debug: to_do: _idx#0, val#0 +debug: * to_do val#0 +debug: * to_do _idx#0 +debug: loc: {_idx#0=_idx#0, val#0=val#0} +debug: pred: {_idx#0=_idx#0, val#0=val#0} +debug: ready: +debug: to_do: _idx#0, val#0 +debug: * to_do val#0 +debug: * to_do _idx#0 +debug: loc: {_idx#0=_idx#0, val#0=val#0} +debug: pred: {_idx#0=_idx#0, val#0=val#0} +debug: ready: +debug: to_do: _idx#0, val#0 +debug: * to_do val#0 +debug: * to_do _idx#0 +debug: Sequentializing parallel copies in test_cases.bug_load_store_load_store.contract.get_bool +debug: Sequentializing parallel copies in test_cases.bug_load_store_load_store.contract.MyContract.clear_state_program +debug: Performing post-SSA optimizations +debug: Removing jump block block@3: // if_body_L14 and replacing references with block@9: // after_if_else_L13 +debug: Output IR to bug_load_store_load_store/out/MyContract.destructured.ir +debug: Inserted main_for_header@1.ops[3]: 'store continue_looping%0#0 to l-stack (copy)' +debug: Replaced main_for_header@1.ops[5]: 'load continue_looping%0#0' with 'load continue_looping%0#0 from l-stack (no copy)' +debug: Inserted main_for_body@2.ops[1]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced main_for_body@2.ops[3]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' +debug: Inserted main_else_body@4.ops[1]: 'store tmp%1#0 to l-stack (copy)' +debug: Replaced main_else_body@4.ops[5]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' +debug: Inserted main_if_body@5.ops[1]: 'store tmp%2#0 to l-stack (copy)' +debug: Replaced main_if_body@5.ops[5]: 'load tmp%2#0' with 'load tmp%2#0 from l-stack (no copy)' +debug: Inserted main_if_body@6.ops[3]: 'store val#0 to l-stack (copy)' +debug: Replaced main_if_body@6.ops[5]: 'load val#0' with 'load val#0 from l-stack (no copy)' +debug: Inserted main_after_if_else@7.ops[1]: 'store val#0 to l-stack (copy)' +debug: Replaced main_after_if_else@7.ops[3]: 'load val#0' with 'load val#0 from l-stack (no copy)' +debug: Found 5 edge set/s for test_cases.bug_load_store_load_store.contract.MyContract.approval_program +debug: test_cases.bug_load_store_load_store.contract.MyContract.approval_program f-stack entry: ['val#11'] +debug: test_cases.bug_load_store_load_store.contract.MyContract.approval_program f-stack on first store: ['val#0', '_idx#0'] +info: Writing bug_load_store_load_store/out/MyContract.approval.teal +info: Writing bug_load_store_load_store/out/MyContract.clear.teal +info: Writing bug_load_store_load_store/out/MyContract.approval.bin +info: Writing bug_load_store_load_store/out/MyContract.clear.bin \ No newline at end of file