From 3197688b06fca6a37dde0f562c69a6f54dc505b6 Mon Sep 17 00:00:00 2001 From: xunilrj Date: Thu, 13 Nov 2025 05:34:59 -0300 Subject: [PATCH 1/4] memcpyopt ignoring types so it works with cast_ptr --- sway-ir/src/optimize/memcpyopt.rs | 61 ++++++++++++++----- .../main_args/main_args_empty/src/main.sw | 14 +++++ 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/sway-ir/src/optimize/memcpyopt.rs b/sway-ir/src/optimize/memcpyopt.rs index 90b1f327e1e..408ee3c7c78 100644 --- a/sway-ir/src/optimize/memcpyopt.rs +++ b/sway-ir/src/optimize/memcpyopt.rs @@ -7,11 +7,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use sway_types::{FxIndexMap, FxIndexSet}; use crate::{ - get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, - get_stored_symbols, memory_utils, AnalysisResults, Block, Context, EscapedSymbols, - FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, - PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueDatum, - ESCAPED_SYMBOLS_NAME, + AnalysisResults, Block, Context, DebugWithContext, ESCAPED_SYMBOLS_NAME, EscapedSymbols, FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueContent, ValueDatum, get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, get_stored_symbols, memory_utils }; pub const MEMCPYOPT_NAME: &str = "memcpyopt"; @@ -1121,9 +1117,11 @@ fn copy_prop_reverse( _ => continue, }; - if dst_sym.get_type(context) != src_sym.get_type(context) { - continue; - } + // if types are different, insert a cast_ptr + // if dst_sym.get_type(context) != src_sym.get_type(context) { + // eprintln!("MEMCPY: {:?} <- {:?}", dst_sym.get_type(context).with_context(context), src_sym.get_type(context).with_context(context)); + // continue; + // } // We don't deal with partial memcpys if dst_sym @@ -1230,16 +1228,36 @@ fn copy_prop_reverse( } } - // Gather the get_local instructions that need to be replaced. let mut repl_locals = vec![]; + let mut value_replacements = FxHashMap::default(); + + // Gather the get_local instructions that need to be replaced. for (_block, inst) in function.instruction_iter(context) { - match inst.get_instruction(context).unwrap() { + match inst.get_instruction(context).cloned().unwrap() { Instruction { op: InstOp::GetLocal(sym), + parent, .. } => { - if let Some(dst) = src_to_dst.get(&Symbol::Local(*sym)) { - repl_locals.push((inst, *dst)); + if let Some(dst) = src_to_dst.get(&Symbol::Local(sym)) { + let sym_type = sym.get_type(context); + let dst_type = dst.get_type(context); + + if sym_type.eq(context, &dst_type) { + repl_locals.push((inst, *dst)); + } else { + eprintln!("MEMCPY: {:?} <- {:?}", dst_type.with_context(context), sym_type.with_context(context)); + + let original_ptr = match dst { + Symbol::Local(..) => todo!(), + Symbol::Arg(block_argument) => { + block_argument.as_value(context) + }, + }; + + let cast_ptr = InstOp::CastPtr(original_ptr, sym_type); + value_replacements.insert(inst, (parent, cast_ptr)); + } } } _ => { @@ -1249,12 +1267,27 @@ fn copy_prop_reverse( } } - if repl_locals.is_empty() { + if repl_locals.is_empty() && value_replacements.is_empty() { return Ok(modified); } + modified = true; - let mut value_replacements = FxHashMap::default(); + let mut value_replacements = value_replacements.into_iter() + .map(|(old, (block, instruction))| { + let v = Value::new_instruction(context, block, instruction); + + let mut inserter = InstructionInserter::new( + context, + block, + crate::InsertionPosition::Before(old), + ); + inserter.insert(v); + + (old, v) + }) + .collect::>(); + for (to_repl, repl_with) in repl_locals { let Instruction { op: InstOp::GetLocal(sym), diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw index 2cbd1392211..bb2f0cd2878 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw @@ -1,5 +1,19 @@ script; +<<<<<<< Updated upstream fn main() -> u64 { 1337 +======= +#[inline(never)] +fn f3() -> raw_slice { + let ptr = asm(size: 0) { + aloc size; + hp: raw_ptr + }; + __transmute::<(raw_ptr, u64), raw_slice>((ptr, 0)) +} + +fn main() { + f3(); +>>>>>>> Stashed changes } From 19e320b08e0a84eb790ec38930e61bf91c9a5d03 Mon Sep 17 00:00:00 2001 From: xunilrj Date: Thu, 13 Nov 2025 05:48:16 -0300 Subject: [PATCH 2/4] snapshot tests --- sway-ir/src/optimize/memcpyopt.rs | 32 ++-- .../intrinsics/dbg_release/stdout.snap | 20 --- .../main_args/main_args_empty/snapshot.toml | 3 + .../main_args/main_args_empty/src/main.sw | 5 - .../main_args/main_args_empty/stdout.snap | 158 ++++++++++++++++++ .../panicking_lib/stdout.snap | 145 +--------------- 6 files changed, 177 insertions(+), 186 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap diff --git a/sway-ir/src/optimize/memcpyopt.rs b/sway-ir/src/optimize/memcpyopt.rs index 408ee3c7c78..c3304d31d88 100644 --- a/sway-ir/src/optimize/memcpyopt.rs +++ b/sway-ir/src/optimize/memcpyopt.rs @@ -7,7 +7,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; use sway_types::{FxIndexMap, FxIndexSet}; use crate::{ - AnalysisResults, Block, Context, DebugWithContext, ESCAPED_SYMBOLS_NAME, EscapedSymbols, FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueContent, ValueDatum, get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, get_stored_symbols, memory_utils + get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, + get_stored_symbols, memory_utils, AnalysisResults, Block, Context, EscapedSymbols, + FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, + PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueDatum, + ESCAPED_SYMBOLS_NAME, }; pub const MEMCPYOPT_NAME: &str = "memcpyopt"; @@ -1117,12 +1121,6 @@ fn copy_prop_reverse( _ => continue, }; - // if types are different, insert a cast_ptr - // if dst_sym.get_type(context) != src_sym.get_type(context) { - // eprintln!("MEMCPY: {:?} <- {:?}", dst_sym.get_type(context).with_context(context), src_sym.get_type(context).with_context(context)); - // continue; - // } - // We don't deal with partial memcpys if dst_sym .get_type(context) @@ -1246,13 +1244,9 @@ fn copy_prop_reverse( if sym_type.eq(context, &dst_type) { repl_locals.push((inst, *dst)); } else { - eprintln!("MEMCPY: {:?} <- {:?}", dst_type.with_context(context), sym_type.with_context(context)); - let original_ptr = match dst { Symbol::Local(..) => todo!(), - Symbol::Arg(block_argument) => { - block_argument.as_value(context) - }, + Symbol::Arg(block_argument) => block_argument.as_value(context), }; let cast_ptr = InstOp::CastPtr(original_ptr, sym_type); @@ -1273,17 +1267,15 @@ fn copy_prop_reverse( modified = true; - let mut value_replacements = value_replacements.into_iter() + let mut value_replacements = value_replacements + .into_iter() .map(|(old, (block, instruction))| { let v = Value::new_instruction(context, block, instruction); - - let mut inserter = InstructionInserter::new( - context, - block, - crate::InsertionPosition::Before(old), - ); + + let mut inserter = + InstructionInserter::new(context, block, crate::InsertionPosition::Before(old)); inserter.insert(v); - + (old, v) }) .collect::>(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap index c25729eaec8..b5359d673ac 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap @@ -1,6 +1,5 @@ --- source: test/src/snapshot/mod.rs -assertion_line: 162 --- > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release --asm final | sub ecal ecal $r1 $r0 $zero $zero ; ecal id fd zero zero @@ -19,22 +18,3 @@ ecal $r1 $r0 $zero $zero ; ecal id fd zero zero ecal $r4 $r0 $r1 $r3 ; ecal id fd buf count > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release --release --asm final | sub ecal -ecal $r2 $r3 $r0 $r1 ; ecal id fd buf count -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r2 $r3 $r0 $r1 ; ecal id fd buf count -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r0 $r3 $r2 $$retv ; ecal id fd buf count -ecal $r3 $r4 $r1 $r2 ; ecal id fd buf count -ecal $r3 $r4 $$locbase $one ; ecal id fd buf count -ecal $r1 $r3 $r0 $one ; ecal id fd buf count diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml new file mode 100644 index 00000000000..24421d62304 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml @@ -0,0 +1,3 @@ +cmds = [ + "forc build --path {root} --release --ir final --asm final" +] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw index bb2f0cd2878..11e356f823d 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw @@ -1,9 +1,5 @@ script; -<<<<<<< Updated upstream -fn main() -> u64 { - 1337 -======= #[inline(never)] fn f3() -> raw_slice { let ptr = asm(size: 0) { @@ -15,5 +11,4 @@ fn f3() -> raw_slice { fn main() { f3(); ->>>>>>> Stashed changes } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap new file mode 100644 index 00000000000..bb53d24900f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap @@ -0,0 +1,158 @@ +--- +source: test/src/snapshot/mod.rs +--- +> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty --release --ir final --asm final +exit status: 0 +output: + Building test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty + Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) +// IR: Final +library { +} + + Compiling script main_args_empty (test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty) +// IR: Final +script { + pub entry fn __entry() -> __ptr slice, !3 { + local mut slice __aggr_memcpy_0 + local { u64, u64 } __anon_0 + local slice __ret_value + + entry(): + v0 = get_local __ptr slice, __ret_value + v1 = call main_0(), !6 + v2 = get_local __ptr { u64, u64 }, __anon_0, !7 + v3 = const u64 0 + v4 = get_elem_ptr v2, __ptr u64, v3, !7 + v5 = const u64 0, !8 + store v5 to v4, !7 + v6 = const u64 1 + v7 = get_elem_ptr v2, __ptr u64, v6, !7 + v8 = const u64 0, !9 + store v8 to v7, !7 + v9 = asm(s: v2) -> __ptr slice s { + } + v10 = get_local __ptr slice, __aggr_memcpy_0 + mem_copy_val v10, v9 + mem_copy_val v0, v10 + ret __ptr slice v0 + } + + entry_orig fn main_0() -> (), !13 { + local slice __ret_val + + entry(): + v0 = get_local __ptr slice, __ret_val + v1 = call f3_1(v0) + v2 = const unit () + ret () v2 + } + + fn f3_1(__ret_value: __ptr slice) -> (), !17 { + entry(__ret_value: __ptr slice): + v0 = const u64 0, !18 + v1 = asm(size: v0) -> ptr hp, !19 { + aloc size, !20 + } + v2 = cast_ptr __ret_value to __ptr { ptr, u64 } + v3 = const u64 0 + v4 = get_elem_ptr v2, __ptr ptr, v3, !21 + store v1 to v4, !21 + v5 = const u64 1 + v6 = get_elem_ptr v2, __ptr u64, v5, !21 + v7 = const u64 0, !22 + store v7 to v6, !21 + v8 = const unit () + ret () v8 + } +} + +!0 = "test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main..sw" +!1 = span !0 0 135 +!2 = fn_name_span !0 7 14 +!3 = (!1 !2) +!4 = span !0 66 72 +!5 = fn_call_path_span !0 66 70 +!6 = (!4 !5) +!7 = span !0 97 103 +!8 = span !0 98 99 +!9 = span !0 101 102 +!10 = "test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw" +!11 = span !10 182 205 +!12 = fn_name_span !10 185 189 +!13 = (!11 !12) +!14 = span !10 26 180 +!15 = fn_name_span !10 29 31 +!16 = inline "never" +!17 = (!14 !15 !16) +!18 = span !10 73 74 +!19 = span !10 63 122 +!20 = span !10 86 95 +!21 = span !10 169 177 +!22 = span !10 175 176 + +;; ASM: Final program +;; Program kind: Script +.program: +move $$tmp $pc +jmpf $zero i4 +DATA_SECTION_OFFSET[0..32] +DATA_SECTION_OFFSET[32..64] +CONFIGURABLES_OFFSET[0..32] +CONFIGURABLES_OFFSET[32..64] +lw $$ds $$tmp i1 +add $$ds $$ds $$tmp +cfei i0 ; allocate stack space for globals +move $$locbase $sp ; save locals base register for function __entry +cfei i48 ; allocate 48 bytes for locals and 0 slots for call arguments +addi $r0 $$locbase i32 ; get offset to local __ptr slice +jal $$reta $pc i9 ; [call]: call main_0 +addi $r1 $$locbase i16 ; get offset to local __ptr { u64, u64 } +sw $$locbase $zero i2 ; store word +sw $$locbase $zero i3 ; store word +mcpi $$locbase $r1 i16 ; copy memory +mcpi $r0 $$locbase i16 ; copy memory +lw $r1 $r0 i1 ; load size of returned slice +lw $r0 $r0 i0 ; load pointer to returned slice +retd $r0 $r1 +pshl i1 ; save registers 16..40 +pshh i524288 ; save registers 40..64 +move $$locbase $sp ; save locals base register for function main_0 +cfei i16 ; allocate 16 bytes for locals and 0 slots for call arguments +move $r0 $$reta ; save return address +move $$arg0 $$locbase ; [call]: pass argument 0 +jal $$reta $pc i6 ; [call]: call f3_1 +cfsi i16 ; free 16 bytes for locals and 0 slots for extra call arguments +move $$reta $r0 ; restore return address +poph i524288 ; restore registers 40..64 +popl i1 ; restore registers 16..40 +jal $zero $$reta i0 ; return from call +pshl i3 ; save registers 16..40 +pshh i524288 ; save registers 40..64 +move $$locbase $sp ; save locals base register for function f3_1 +move $r0 $$arg0 ; save argument 0 (__ret_value) +move $r1 $$reta ; save return address +aloc $zero ; aloc size +sw $r0 $hp i0 ; store word +sw $r0 $zero i1 ; store word +move $$reta $r1 ; restore return address +poph i524288 ; restore registers 40..64 +popl i3 ; restore registers 16..40 +jal $zero $$reta i0 ; return from call +.data: + + +warning: Returned value is ignored + --> test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw:13:5 + | +... +13 | f3(); + | ---- This returns a value which is not assigned to anything and is ignored. + | ---- help: The returned value has type "raw_slice". + | + = help: If you want to intentionally ignore the returned value, use `let _ = ...`: + = help: let _ = f3(); +____ + + Compiled script "main_args_empty" with 1 warning. + Finished release [optimized + fuel] target(s) [176 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap index 29c31e2d26a..61955457ac9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap @@ -1,6 +1,5 @@ --- source: test/src/snapshot/mod.rs -assertion_line: 101 --- > forc test --path test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib --test-threads 1 --logs --reverts exit status: 0 @@ -178,148 +177,12 @@ test result: OK. 18 passed; 0 failed; finished in ??? Finished in ??? > forc test --path test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib --release --test-threads 1 --logs --reverts -exit status: 0 +exit status: 101 output: Building test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) - Finished release [optimized + fuel] target(s) [4.56 KB] in ??? - Running 18 tests, filtered 0 tests - -tested -- panicking_lib - - test test_nested_panic_inlined ... ok (???, 1679 gas) - revert code: 8000000000000000 - ├─ panic message: Error E. - ├─ panic value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]) - └─ panicked: in panicking_lib::nested_panic_inlined - └─ at panicking_lib, src/lib.sw:35:5 - decoded log values: -E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 2721958641300806892 - test test_nested_panic_inlined_same_revert_code ... ok (???, 1679 gas) - revert code: 8000000000000000 - ├─ panic message: Error E. - ├─ panic value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]) - └─ panicked: in panicking_lib::nested_panic_inlined - └─ at panicking_lib, src/lib.sw:35:5 - decoded log values: -E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 2721958641300806892 - test test_nested_panic_non_inlined ... ok (???, 1717 gas) - revert code: 8080000000000000 - ├─ panic message: Error E. - ├─ panic value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]) - └─ panicked: in panicking_lib::nested_panic_non_inlined - └─ at panicking_lib, src/lib.sw:41:9 - decoded log values: -E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 2721958641300806892 - test test_nested_panic_non_inlined_same_revert_code ... ok (???, 1717 gas) - revert code: 8080000000000000 - ├─ panic message: Error E. - ├─ panic value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]) - └─ panicked: in panicking_lib::nested_panic_non_inlined - └─ at panicking_lib, src/lib.sw:41:9 - decoded log values: -E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 2721958641300806892 - test test_generic_panic_with_unit ... ok (???, 660 gas) - revert code: 8100000000000000 - ├─ panic value: () - └─ panicked: in panicking_lib::generic_panic - └─ at panicking_lib, src/lib.sw:74:5 - decoded log values: -(), log rb: 3330666440490685604 - test test_generic_panic_with_unit_same_revert_code ... ok (???, 660 gas) - revert code: 8100000000000000 - ├─ panic value: () - └─ panicked: in panicking_lib::generic_panic - └─ at panicking_lib, src/lib.sw:74:5 - decoded log values: -(), log rb: 3330666440490685604 - test test_generic_panic_with_str ... ok (???, 874 gas) - revert code: 8180000000000000 - ├─ panic message: generic panic with string - └─ panicked: in panicking_lib::generic_panic - └─ at panicking_lib, src/lib.sw:74:5 - decoded log values: -AsciiString { data: "generic panic with string" }, log rb: 10098701174489624218 - test test_generic_panic_with_different_str_same_revert_code ... ok (???, 875 gas) - revert code: 8180000000000000 - ├─ panic message: generic panic different string - └─ panicked: in panicking_lib::generic_panic - └─ at panicking_lib, src/lib.sw:74:5 - decoded log values: -AsciiString { data: "generic panic different string" }, log rb: 10098701174489624218 - test test_generic_panic_with_error_type_enum_variant ... ok (???, 893 gas) - revert code: 8200000000000000 - ├─ panic message: Error A. - ├─ panic value: A - └─ panicked: in panicking_lib::generic_panic - └─ at panicking_lib, src/lib.sw:74:5 - decoded log values: -A, log rb: 2721958641300806892 - test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 893 gas) - revert code: 8200000000000000 - ├─ panic message: Error A. - ├─ panic value: A - └─ panicked: in panicking_lib::generic_panic - └─ at panicking_lib, src/lib.sw:74:5 - decoded log values: -A, log rb: 2721958641300806892 - test test_panic_without_arg ... ok (???, 660 gas) - revert code: 8280000000000000 - ├─ panic value: () - └─ panicked: in panicking_lib::test_panic_without_arg - └─ at panicking_lib, src/lib.sw:113:5 - decoded log values: -(), log rb: 3330666440490685604 - test test_panic_with_unit ... ok (???, 660 gas) - revert code: 8300000000000000 - ├─ panic value: () - └─ panicked: in panicking_lib::test_panic_with_unit - └─ at panicking_lib, src/lib.sw:118:5 - decoded log values: -(), log rb: 3330666440490685604 - test test_panic_with_str ... ok (???, 79 gas) - revert code: 8380000000000000 - ├─ panic message: panic with string - └─ panicked: in panicking_lib::test_panic_with_str - └─ at panicking_lib, src/lib.sw:123:5 - test test_panic_with_error_type_enum ... ok (???, 1028 gas) - revert code: 8400000000000000 - ├─ panic message: Error C. - ├─ panic value: C(true) - └─ panicked: in panicking_lib::test_panic_with_error_type_enum - └─ at panicking_lib, src/lib.sw:128:5 - decoded log values: -C(true), log rb: 2721958641300806892 - test test_panic_with_generic_error_type_enum ... ok (???, 940 gas) - revert code: 8480000000000000 - ├─ panic value: A(42) - └─ panicked: in panicking_lib::test_panic_with_generic_error_type_enum - └─ at panicking_lib, src/lib.sw:133:5 - decoded log values: -A(42), log rb: 12408470889216862137 - test test_panic_with_nested_generic_error_type ... ok (???, 1354 gas) - revert code: 8500000000000000 - ├─ panic value: B(B(C(true))) - └─ panicked: in panicking_lib::test_panic_with_nested_generic_error_type - └─ at panicking_lib, src/lib.sw:138:5 - decoded log values: -B(B(C(true))), log rb: 14988555917426256081 - test test_panic_with_generic_error_type_enum_with_abi_encode ... ok (???, 940 gas) - revert code: 8580000000000000 - ├─ panic value: A(42) - └─ panicked: in panicking_lib::test_panic_with_generic_error_type_enum_with_abi_encode - └─ at panicking_lib, src/lib.sw:143:5 - decoded log values: -A(42), log rb: 17388243649088655852 - test test_panic_with_nested_generic_error_type_enum_with_abi_encode ... ok (???, 1354 gas) - revert code: 8600000000000000 - ├─ panic value: B(B(C(true))) - └─ panicked: in panicking_lib::test_panic_with_nested_generic_error_type_enum_with_abi_encode - └─ at panicking_lib, src/lib.sw:148:5 - decoded log values: -B(B(C(true))), log rb: 3755100321495500961 -test result: OK. 18 passed; 0 failed; finished in ??? - - Finished in ??? +thread 'main' panicked at sway-ir/src/optimize/memcpyopt.rs:1248:50: +not yet implemented +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace From f2273a00545d44815b49d71228d849ba16ed1dbe Mon Sep 17 00:00:00 2001 From: xunilrj Date: Tue, 18 Nov 2025 20:24:28 -0300 Subject: [PATCH 3/4] making all tests pass --- sway-ir/src/optimize/memcpyopt.rs | 24 +-- .../intrinsics/dbg_release/stdout.snap | 19 +++ .../intrinsics/transmute/snapshot.toml | 2 +- .../language/intrinsics/transmute/src/main.sw | 12 ++ .../language/intrinsics/transmute/stdout.snap | 66 ++++---- .../main_args/main_args_empty/snapshot.toml | 3 - .../main_args/main_args_empty/src/main.sw | 13 +- .../main_args/main_args_empty/stdout.snap | 158 ------------------ .../panicking_lib/stdout.snap | 144 +++++++++++++++- 9 files changed, 225 insertions(+), 216 deletions(-) delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml delete mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap diff --git a/sway-ir/src/optimize/memcpyopt.rs b/sway-ir/src/optimize/memcpyopt.rs index c3304d31d88..93201f8da6a 100644 --- a/sway-ir/src/optimize/memcpyopt.rs +++ b/sway-ir/src/optimize/memcpyopt.rs @@ -7,11 +7,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use sway_types::{FxIndexMap, FxIndexSet}; use crate::{ - get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, - get_stored_symbols, memory_utils, AnalysisResults, Block, Context, EscapedSymbols, - FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, - PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueDatum, - ESCAPED_SYMBOLS_NAME, + AnalysisResults, Block, Context, ESCAPED_SYMBOLS_NAME, EscapedSymbols, FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueDatum, get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, get_stored_symbols, memory_utils }; pub const MEMCPYOPT_NAME: &str = "memcpyopt"; @@ -1121,6 +1117,7 @@ fn copy_prop_reverse( _ => continue, }; + // We don't deal with partial memcpys if dst_sym .get_type(context) @@ -1196,8 +1193,7 @@ fn copy_prop_reverse( continue; } } - } - to_delete.insert(inst); + } } } } @@ -1226,11 +1222,11 @@ fn copy_prop_reverse( } } - let mut repl_locals = vec![]; + let mut repl_locals: Vec<(Value, Symbol)> = vec![]; let mut value_replacements = FxHashMap::default(); // Gather the get_local instructions that need to be replaced. - for (_block, inst) in function.instruction_iter(context) { + for (block, inst) in function.instruction_iter(context).collect::>() { match inst.get_instruction(context).cloned().unwrap() { Instruction { op: InstOp::GetLocal(sym), @@ -1241,11 +1237,17 @@ fn copy_prop_reverse( let sym_type = sym.get_type(context); let dst_type = dst.get_type(context); - if sym_type.eq(context, &dst_type) { + // TODO we are comparings strings here + let sym_type_str = sym_type.as_string(context); + let dst_type_str = dst_type.as_string(context); + if sym_type_str == dst_type_str { repl_locals.push((inst, *dst)); + //to_delete.insert(inst); // TODO what to do with this? } else { let original_ptr = match dst { - Symbol::Local(..) => todo!(), + Symbol::Local(_) => { + continue; + }, Symbol::Arg(block_argument) => block_argument.as_value(context), }; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap index b5359d673ac..72a814f3b60 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap @@ -18,3 +18,22 @@ ecal $r1 $r0 $zero $zero ; ecal id fd zero zero ecal $r4 $r0 $r1 $r3 ; ecal id fd buf count > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release --release --asm final | sub ecal +ecal $r2 $r3 $r0 $r1 ; ecal id fd buf count +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r2 $r3 $r0 $r1 ; ecal id fd buf count +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r1 $zero $zero ; ecal id fd zero zero +ecal $r0 $r3 $r2 $$retv ; ecal id fd buf count +ecal $r3 $r4 $r1 $r2 ; ecal id fd buf count +ecal $r3 $r4 $$locbase $one ; ecal id fd buf count +ecal $r1 $r3 $r0 $one ; ecal id fd buf count diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/snapshot.toml index c613fa3ab43..d291408834d 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/snapshot.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/snapshot.toml @@ -1,3 +1,3 @@ cmds = [ - "forc build --path {root} --ir final --asm final | filter-fn {name} transmute_by_reference_7", + "forc build --path {root} --ir final --asm final --release | filter-fn {name} transmute_by_reference_7,transmute_optimisation_13", ] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/src/main.sw index 8ac4aeaaddf..f580bd9dc60 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/src/main.sw @@ -49,6 +49,16 @@ fn const_transmute() { let _ = transmute_by_reference(); } + +#[inline(never)] +fn transmute_optimisation() -> raw_slice { + let ptr = asm(size: 0) { + aloc size; + hp: raw_ptr + }; + __transmute::<(raw_ptr, u64), raw_slice>((ptr, 0)) +} + fn main() { const_transmute(); @@ -129,4 +139,6 @@ fn main() { let some_struct = __transmute::(some_enum); assert(some_struct.tag == 1); assert(some_struct.value == 1); + + let _ = transmute_optimisation(); } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/stdout.snap index 243a5b271bb..5e9105f8bd4 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute/stdout.snap @@ -1,45 +1,55 @@ --- source: test/src/snapshot/mod.rs --- -> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute --ir final --asm final | filter-fn transmute transmute_by_reference_7 +> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/transmute --ir final --asm final --release | filter-fn transmute transmute_by_reference_7,transmute_optimisation_13 fn transmute_by_reference_7(__ret_value: __ptr u256) -> () { - local [u8; 32] __anon_0 - local mut [u8; 32] bytes - local __ptr u256 v - entry(__ret_value: __ptr u256): - v0 = get_local __ptr [u8; 32], __anon_0 + v0 = cast_ptr __ret_value to __ptr [u8; 32] mem_clear_val v0 - v1 = get_local __ptr [u8; 32], bytes - mem_copy_val v1, v0 - v2 = get_local __ptr [u8; 32], bytes - v3 = cast_ptr v2 to __ptr u256 - v4 = get_local __ptr __ptr u256, v - store v3 to v4 - v5 = get_local __ptr __ptr u256, v - v6 = load v5 - mem_copy_val __ret_value, v6 - v7 = const unit () - ret () v7 + v1 = const unit () + ret () v1 +} + + +fn transmute_optimisation_13(__ret_value: __ptr slice) -> () { + entry(__ret_value: __ptr slice): + v0 = const u64 0 + v1 = asm(size: v0) -> ptr hp { + aloc size + } + v2 = cast_ptr __ret_value to __ptr { ptr, u64 } + v3 = const u64 0 + v4 = get_elem_ptr v2, __ptr ptr, v3 + store v1 to v4 + v5 = const u64 1 + v6 = get_elem_ptr v2, __ptr u64, v5 + v7 = const u64 0 + store v7 to v6 + v8 = const unit () + ret () v8 } -pshl i7 ; save registers 16..40 +pshl i1 ; save registers 16..40 pshh i524288 ; save registers 40..64 move $$locbase $sp ; save locals base register for function transmute_by_reference_7 -cfei i72 ; allocate 72 bytes for locals and 0 slots for call arguments +move $r0 $$reta ; save return address +mcli $$arg0 i32 ; clear memory [u8; 32], 32 bytes +move $$reta $r0 ; restore return address +poph i524288 ; restore registers 40..64 +popl i1 ; restore registers 16..40 +jal $zero $$reta i0 ; return from call + +pshl i3 ; save registers 16..40 +pshh i524288 ; save registers 40..64 +move $$locbase $sp ; save locals base register for function transmute_optimisation_13 move $r0 $$arg0 ; save argument 0 (__ret_value) move $r1 $$reta ; save return address -mcli $$locbase i32 ; clear memory [u8; 32], 32 bytes -addi $r2 $$locbase i32 ; get offset to local __ptr [u8; 32] -mcpi $r2 $$locbase i32 ; copy memory -addi $r2 $$locbase i32 ; get offset to local __ptr [u8; 32] -sw $$locbase $r2 i8 ; store word -lw $r2 $$locbase i8 ; load word -mcpi $r0 $r2 i32 ; copy memory -cfsi i72 ; free 72 bytes for locals and 0 slots for extra call arguments +aloc $zero ; aloc size +sw $r0 $hp i0 ; store word +sw $r0 $zero i1 ; store word move $$reta $r1 ; restore return address poph i524288 ; restore registers 40..64 -popl i7 ; restore registers 16..40 +popl i3 ; restore registers 16..40 jal $zero $$reta i0 ; return from call diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml deleted file mode 100644 index 24421d62304..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/snapshot.toml +++ /dev/null @@ -1,3 +0,0 @@ -cmds = [ - "forc build --path {root} --release --ir final --asm final" -] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw index 11e356f823d..2cbd1392211 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw @@ -1,14 +1,5 @@ script; -#[inline(never)] -fn f3() -> raw_slice { - let ptr = asm(size: 0) { - aloc size; - hp: raw_ptr - }; - __transmute::<(raw_ptr, u64), raw_slice>((ptr, 0)) -} - -fn main() { - f3(); +fn main() -> u64 { + 1337 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap deleted file mode 100644 index bb53d24900f..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/stdout.snap +++ /dev/null @@ -1,158 +0,0 @@ ---- -source: test/src/snapshot/mod.rs ---- -> forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty --release --ir final --asm final -exit status: 0 -output: - Building test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty - Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) -// IR: Final -library { -} - - Compiling script main_args_empty (test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty) -// IR: Final -script { - pub entry fn __entry() -> __ptr slice, !3 { - local mut slice __aggr_memcpy_0 - local { u64, u64 } __anon_0 - local slice __ret_value - - entry(): - v0 = get_local __ptr slice, __ret_value - v1 = call main_0(), !6 - v2 = get_local __ptr { u64, u64 }, __anon_0, !7 - v3 = const u64 0 - v4 = get_elem_ptr v2, __ptr u64, v3, !7 - v5 = const u64 0, !8 - store v5 to v4, !7 - v6 = const u64 1 - v7 = get_elem_ptr v2, __ptr u64, v6, !7 - v8 = const u64 0, !9 - store v8 to v7, !7 - v9 = asm(s: v2) -> __ptr slice s { - } - v10 = get_local __ptr slice, __aggr_memcpy_0 - mem_copy_val v10, v9 - mem_copy_val v0, v10 - ret __ptr slice v0 - } - - entry_orig fn main_0() -> (), !13 { - local slice __ret_val - - entry(): - v0 = get_local __ptr slice, __ret_val - v1 = call f3_1(v0) - v2 = const unit () - ret () v2 - } - - fn f3_1(__ret_value: __ptr slice) -> (), !17 { - entry(__ret_value: __ptr slice): - v0 = const u64 0, !18 - v1 = asm(size: v0) -> ptr hp, !19 { - aloc size, !20 - } - v2 = cast_ptr __ret_value to __ptr { ptr, u64 } - v3 = const u64 0 - v4 = get_elem_ptr v2, __ptr ptr, v3, !21 - store v1 to v4, !21 - v5 = const u64 1 - v6 = get_elem_ptr v2, __ptr u64, v5, !21 - v7 = const u64 0, !22 - store v7 to v6, !21 - v8 = const unit () - ret () v8 - } -} - -!0 = "test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main..sw" -!1 = span !0 0 135 -!2 = fn_name_span !0 7 14 -!3 = (!1 !2) -!4 = span !0 66 72 -!5 = fn_call_path_span !0 66 70 -!6 = (!4 !5) -!7 = span !0 97 103 -!8 = span !0 98 99 -!9 = span !0 101 102 -!10 = "test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw" -!11 = span !10 182 205 -!12 = fn_name_span !10 185 189 -!13 = (!11 !12) -!14 = span !10 26 180 -!15 = fn_name_span !10 29 31 -!16 = inline "never" -!17 = (!14 !15 !16) -!18 = span !10 73 74 -!19 = span !10 63 122 -!20 = span !10 86 95 -!21 = span !10 169 177 -!22 = span !10 175 176 - -;; ASM: Final program -;; Program kind: Script -.program: -move $$tmp $pc -jmpf $zero i4 -DATA_SECTION_OFFSET[0..32] -DATA_SECTION_OFFSET[32..64] -CONFIGURABLES_OFFSET[0..32] -CONFIGURABLES_OFFSET[32..64] -lw $$ds $$tmp i1 -add $$ds $$ds $$tmp -cfei i0 ; allocate stack space for globals -move $$locbase $sp ; save locals base register for function __entry -cfei i48 ; allocate 48 bytes for locals and 0 slots for call arguments -addi $r0 $$locbase i32 ; get offset to local __ptr slice -jal $$reta $pc i9 ; [call]: call main_0 -addi $r1 $$locbase i16 ; get offset to local __ptr { u64, u64 } -sw $$locbase $zero i2 ; store word -sw $$locbase $zero i3 ; store word -mcpi $$locbase $r1 i16 ; copy memory -mcpi $r0 $$locbase i16 ; copy memory -lw $r1 $r0 i1 ; load size of returned slice -lw $r0 $r0 i0 ; load pointer to returned slice -retd $r0 $r1 -pshl i1 ; save registers 16..40 -pshh i524288 ; save registers 40..64 -move $$locbase $sp ; save locals base register for function main_0 -cfei i16 ; allocate 16 bytes for locals and 0 slots for call arguments -move $r0 $$reta ; save return address -move $$arg0 $$locbase ; [call]: pass argument 0 -jal $$reta $pc i6 ; [call]: call f3_1 -cfsi i16 ; free 16 bytes for locals and 0 slots for extra call arguments -move $$reta $r0 ; restore return address -poph i524288 ; restore registers 40..64 -popl i1 ; restore registers 16..40 -jal $zero $$reta i0 ; return from call -pshl i3 ; save registers 16..40 -pshh i524288 ; save registers 40..64 -move $$locbase $sp ; save locals base register for function f3_1 -move $r0 $$arg0 ; save argument 0 (__ret_value) -move $r1 $$reta ; save return address -aloc $zero ; aloc size -sw $r0 $hp i0 ; store word -sw $r0 $zero i1 ; store word -move $$reta $r1 ; restore return address -poph i524288 ; restore registers 40..64 -popl i3 ; restore registers 16..40 -jal $zero $$reta i0 ; return from call -.data: - - -warning: Returned value is ignored - --> test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src/main.sw:13:5 - | -... -13 | f3(); - | ---- This returns a value which is not assigned to anything and is ignored. - | ---- help: The returned value has type "raw_slice". - | - = help: If you want to intentionally ignore the returned value, use `let _ = ...`: - = help: let _ = f3(); -____ - - Compiled script "main_args_empty" with 1 warning. - Finished release [optimized + fuel] target(s) [176 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap index 61955457ac9..f2fb87bc7ec 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap @@ -177,12 +177,148 @@ test result: OK. 18 passed; 0 failed; finished in ??? Finished in ??? > forc test --path test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib --release --test-threads 1 --logs --reverts -exit status: 101 +exit status: 0 output: Building test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) + Finished release [optimized + fuel] target(s) [4.56 KB] in ??? + Running 18 tests, filtered 0 tests + +tested -- panicking_lib + + test test_nested_panic_inlined ... ok (???, 1679 gas) + revert code: 8000000000000000 + ├─ panic message: Error E. + ├─ panic value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]) + └─ panicked: in panicking_lib::nested_panic_inlined + └─ at panicking_lib, src/lib.sw:35:5 + decoded log values: +E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 2721958641300806892 + test test_nested_panic_inlined_same_revert_code ... ok (???, 1679 gas) + revert code: 8000000000000000 + ├─ panic message: Error E. + ├─ panic value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]) + └─ panicked: in panicking_lib::nested_panic_inlined + └─ at panicking_lib, src/lib.sw:35:5 + decoded log values: +E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 2721958641300806892 + test test_nested_panic_non_inlined ... ok (???, 1717 gas) + revert code: 8080000000000000 + ├─ panic message: Error E. + ├─ panic value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]) + └─ panicked: in panicking_lib::nested_panic_non_inlined + └─ at panicking_lib, src/lib.sw:41:9 + decoded log values: +E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 2721958641300806892 + test test_nested_panic_non_inlined_same_revert_code ... ok (???, 1717 gas) + revert code: 8080000000000000 + ├─ panic message: Error E. + ├─ panic value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]) + └─ panicked: in panicking_lib::nested_panic_non_inlined + └─ at panicking_lib, src/lib.sw:41:9 + decoded log values: +E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 2721958641300806892 + test test_generic_panic_with_unit ... ok (???, 660 gas) + revert code: 8100000000000000 + ├─ panic value: () + └─ panicked: in panicking_lib::generic_panic + └─ at panicking_lib, src/lib.sw:74:5 + decoded log values: +(), log rb: 3330666440490685604 + test test_generic_panic_with_unit_same_revert_code ... ok (???, 660 gas) + revert code: 8100000000000000 + ├─ panic value: () + └─ panicked: in panicking_lib::generic_panic + └─ at panicking_lib, src/lib.sw:74:5 + decoded log values: +(), log rb: 3330666440490685604 + test test_generic_panic_with_str ... ok (???, 874 gas) + revert code: 8180000000000000 + ├─ panic message: generic panic with string + └─ panicked: in panicking_lib::generic_panic + └─ at panicking_lib, src/lib.sw:74:5 + decoded log values: +AsciiString { data: "generic panic with string" }, log rb: 10098701174489624218 + test test_generic_panic_with_different_str_same_revert_code ... ok (???, 875 gas) + revert code: 8180000000000000 + ├─ panic message: generic panic different string + └─ panicked: in panicking_lib::generic_panic + └─ at panicking_lib, src/lib.sw:74:5 + decoded log values: +AsciiString { data: "generic panic different string" }, log rb: 10098701174489624218 + test test_generic_panic_with_error_type_enum_variant ... ok (???, 893 gas) + revert code: 8200000000000000 + ├─ panic message: Error A. + ├─ panic value: A + └─ panicked: in panicking_lib::generic_panic + └─ at panicking_lib, src/lib.sw:74:5 + decoded log values: +A, log rb: 2721958641300806892 + test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 893 gas) + revert code: 8200000000000000 + ├─ panic message: Error A. + ├─ panic value: A + └─ panicked: in panicking_lib::generic_panic + └─ at panicking_lib, src/lib.sw:74:5 + decoded log values: +A, log rb: 2721958641300806892 + test test_panic_without_arg ... ok (???, 660 gas) + revert code: 8280000000000000 + ├─ panic value: () + └─ panicked: in panicking_lib::test_panic_without_arg + └─ at panicking_lib, src/lib.sw:113:5 + decoded log values: +(), log rb: 3330666440490685604 + test test_panic_with_unit ... ok (???, 660 gas) + revert code: 8300000000000000 + ├─ panic value: () + └─ panicked: in panicking_lib::test_panic_with_unit + └─ at panicking_lib, src/lib.sw:118:5 + decoded log values: +(), log rb: 3330666440490685604 + test test_panic_with_str ... ok (???, 79 gas) + revert code: 8380000000000000 + ├─ panic message: panic with string + └─ panicked: in panicking_lib::test_panic_with_str + └─ at panicking_lib, src/lib.sw:123:5 + test test_panic_with_error_type_enum ... ok (???, 1028 gas) + revert code: 8400000000000000 + ├─ panic message: Error C. + ├─ panic value: C(true) + └─ panicked: in panicking_lib::test_panic_with_error_type_enum + └─ at panicking_lib, src/lib.sw:128:5 + decoded log values: +C(true), log rb: 2721958641300806892 + test test_panic_with_generic_error_type_enum ... ok (???, 940 gas) + revert code: 8480000000000000 + ├─ panic value: A(42) + └─ panicked: in panicking_lib::test_panic_with_generic_error_type_enum + └─ at panicking_lib, src/lib.sw:133:5 + decoded log values: +A(42), log rb: 12408470889216862137 + test test_panic_with_nested_generic_error_type ... ok (???, 1354 gas) + revert code: 8500000000000000 + ├─ panic value: B(B(C(true))) + └─ panicked: in panicking_lib::test_panic_with_nested_generic_error_type + └─ at panicking_lib, src/lib.sw:138:5 + decoded log values: +B(B(C(true))), log rb: 14988555917426256081 + test test_panic_with_generic_error_type_enum_with_abi_encode ... ok (???, 940 gas) + revert code: 8580000000000000 + ├─ panic value: A(42) + └─ panicked: in panicking_lib::test_panic_with_generic_error_type_enum_with_abi_encode + └─ at panicking_lib, src/lib.sw:143:5 + decoded log values: +A(42), log rb: 17388243649088655852 + test test_panic_with_nested_generic_error_type_enum_with_abi_encode ... ok (???, 1354 gas) + revert code: 8600000000000000 + ├─ panic value: B(B(C(true))) + └─ panicked: in panicking_lib::test_panic_with_nested_generic_error_type_enum_with_abi_encode + └─ at panicking_lib, src/lib.sw:148:5 + decoded log values: +B(B(C(true))), log rb: 3755100321495500961 -thread 'main' panicked at sway-ir/src/optimize/memcpyopt.rs:1248:50: -not yet implemented -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +test result: OK. 18 passed; 0 failed; finished in ??? + + Finished in ??? From 12fcdf4c6ade7a0ff588da608d61270c31f5c130 Mon Sep 17 00:00:00 2001 From: xunilrj Date: Tue, 18 Nov 2025 20:30:22 -0300 Subject: [PATCH 4/4] fmt and clippy issues --- sway-ir/src/optimize/memcpyopt.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sway-ir/src/optimize/memcpyopt.rs b/sway-ir/src/optimize/memcpyopt.rs index 93201f8da6a..446fe6f61af 100644 --- a/sway-ir/src/optimize/memcpyopt.rs +++ b/sway-ir/src/optimize/memcpyopt.rs @@ -7,7 +7,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; use sway_types::{FxIndexMap, FxIndexSet}; use crate::{ - AnalysisResults, Block, Context, ESCAPED_SYMBOLS_NAME, EscapedSymbols, FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueDatum, get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, get_stored_symbols, memory_utils + get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, + get_stored_symbols, memory_utils, AnalysisResults, Block, Context, EscapedSymbols, + FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, + PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueDatum, + ESCAPED_SYMBOLS_NAME, }; pub const MEMCPYOPT_NAME: &str = "memcpyopt"; @@ -1117,7 +1121,6 @@ fn copy_prop_reverse( _ => continue, }; - // We don't deal with partial memcpys if dst_sym .get_type(context) @@ -1165,7 +1168,7 @@ fn copy_prop_reverse( let mut to_delete: FxHashSet = FxHashSet::default(); let mut src_to_dst: FxHashMap = FxHashMap::default(); - for (inst, dst_sym, src_sym) in candidates { + for (_inst, dst_sym, src_sym) in candidates { match src_sym { Symbol::Arg(_) => { // Args are mostly copied to locals before actually being used. @@ -1193,7 +1196,7 @@ fn copy_prop_reverse( continue; } } - } + } } } } @@ -1226,7 +1229,7 @@ fn copy_prop_reverse( let mut value_replacements = FxHashMap::default(); // Gather the get_local instructions that need to be replaced. - for (block, inst) in function.instruction_iter(context).collect::>() { + for (_block, inst) in function.instruction_iter(context).collect::>() { match inst.get_instruction(context).cloned().unwrap() { Instruction { op: InstOp::GetLocal(sym), @@ -1247,7 +1250,7 @@ fn copy_prop_reverse( let original_ptr = match dst { Symbol::Local(_) => { continue; - }, + } Symbol::Arg(block_argument) => block_argument.as_value(context), };