@@ -7,11 +7,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
77use sway_types:: { FxIndexMap , FxIndexSet } ;
88
99use crate :: {
10- get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols,
11- get_stored_symbols, memory_utils, AnalysisResults , Block , Context , EscapedSymbols ,
12- FuelVmInstruction , Function , InstOp , Instruction , InstructionInserter , IrError , LocalVar , Pass ,
13- PassMutability , ReferredSymbols , ScopedPass , Symbol , Type , Value , ValueDatum ,
14- ESCAPED_SYMBOLS_NAME ,
10+ 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
1511} ;
1612
1713pub const MEMCPYOPT_NAME : & str = "memcpyopt" ;
@@ -1121,9 +1117,11 @@ fn copy_prop_reverse(
11211117 _ => continue ,
11221118 } ;
11231119
1124- if dst_sym. get_type ( context) != src_sym. get_type ( context) {
1125- continue ;
1126- }
1120+ // if types are different, insert a cast_ptr
1121+ // if dst_sym.get_type(context) != src_sym.get_type(context) {
1122+ // eprintln!("MEMCPY: {:?} <- {:?}", dst_sym.get_type(context).with_context(context), src_sym.get_type(context).with_context(context));
1123+ // continue;
1124+ // }
11271125
11281126 // We don't deal with partial memcpys
11291127 if dst_sym
@@ -1230,16 +1228,36 @@ fn copy_prop_reverse(
12301228 }
12311229 }
12321230
1233- // Gather the get_local instructions that need to be replaced.
12341231 let mut repl_locals = vec ! [ ] ;
1232+ let mut value_replacements = FxHashMap :: default ( ) ;
1233+
1234+ // Gather the get_local instructions that need to be replaced.
12351235 for ( _block, inst) in function. instruction_iter ( context) {
1236- match inst. get_instruction ( context) . unwrap ( ) {
1236+ match inst. get_instruction ( context) . cloned ( ) . unwrap ( ) {
12371237 Instruction {
12381238 op : InstOp :: GetLocal ( sym) ,
1239+ parent,
12391240 ..
12401241 } => {
1241- if let Some ( dst) = src_to_dst. get ( & Symbol :: Local ( * sym) ) {
1242- repl_locals. push ( ( inst, * dst) ) ;
1242+ if let Some ( dst) = src_to_dst. get ( & Symbol :: Local ( sym) ) {
1243+ let sym_type = sym. get_type ( context) ;
1244+ let dst_type = dst. get_type ( context) ;
1245+
1246+ if sym_type. eq ( context, & dst_type) {
1247+ repl_locals. push ( ( inst, * dst) ) ;
1248+ } else {
1249+ eprintln ! ( "MEMCPY: {:?} <- {:?}" , dst_type. with_context( context) , sym_type. with_context( context) ) ;
1250+
1251+ let original_ptr = match dst {
1252+ Symbol :: Local ( ..) => todo ! ( ) ,
1253+ Symbol :: Arg ( block_argument) => {
1254+ block_argument. as_value ( context)
1255+ } ,
1256+ } ;
1257+
1258+ let cast_ptr = InstOp :: CastPtr ( original_ptr, sym_type) ;
1259+ value_replacements. insert ( inst, ( parent, cast_ptr) ) ;
1260+ }
12431261 }
12441262 }
12451263 _ => {
@@ -1249,12 +1267,27 @@ fn copy_prop_reverse(
12491267 }
12501268 }
12511269
1252- if repl_locals. is_empty ( ) {
1270+ if repl_locals. is_empty ( ) && value_replacements . is_empty ( ) {
12531271 return Ok ( modified) ;
12541272 }
1273+
12551274 modified = true ;
12561275
1257- let mut value_replacements = FxHashMap :: default ( ) ;
1276+ let mut value_replacements = value_replacements. into_iter ( )
1277+ . map ( |( old, ( block, instruction) ) | {
1278+ let v = Value :: new_instruction ( context, block, instruction) ;
1279+
1280+ let mut inserter = InstructionInserter :: new (
1281+ context,
1282+ block,
1283+ crate :: InsertionPosition :: Before ( old) ,
1284+ ) ;
1285+ inserter. insert ( v) ;
1286+
1287+ ( old, v)
1288+ } )
1289+ . collect :: < FxHashMap < Value , Value > > ( ) ;
1290+
12581291 for ( to_repl, repl_with) in repl_locals {
12591292 let Instruction {
12601293 op : InstOp :: GetLocal ( sym) ,
0 commit comments