diff --git a/lart/mcsema/lowerreturn.hpp b/lart/mcsema/lowerreturn.hpp
index dc96c95276720420e30e3e2b35164e2966709f33..1cff423700a01d174b41c36783461e196fb88210 100644
--- a/lart/mcsema/lowerreturn.hpp
+++ b/lart/mcsema/lowerreturn.hpp
@@ -111,11 +111,27 @@ namespace lart::mcsema
             return std::string( wrapper_prefix ) + std::to_string( ++counter );
         }
 
-        // FIXME: Currently we leak memory
-        template< typename irb_t >
-        void free( llvm::Value * val, irb_t &irb )
+        void deallocate( llvm::Value *ptr, llvm::Instruction *ret )
+        {
+            auto free_f = _m->getFunction( "__vm_obj_free" );
+            if ( !free_f )
+                UNREACHABLE( "Could not find free function" );
+
+            llvm::IRBuilder<> irb( ret );
+            auto i8ptr = irb.CreateBitCast( ptr, i8PTy() );
+            irb.CreateCall( i8ptr );
+
+        }
+
+        void deallocate( llvm::Value * val )
         {
-            UNREACHABLE( "Not implemented" );
+            auto all_rets = query::query( *util::get_function( val ) )
+                            .flatten()
+                            .filter( query::llvmdyncast< llvm::ReturnInst > )
+                            .map( query::refToPtr )
+                            .freeze();
+            for ( auto ret : all_rets )
+                deallocate( val, ret );
         }
 
         template< typename irb_t >