@@ -41,6 +41,10 @@ pub fn assert_instr(
4141 // testing for.
4242 let disable_assert_instr = std:: env:: var ( "STDARCH_DISABLE_ASSERT_INSTR" ) . is_ok ( ) ;
4343
44+ // Disable dedup guard. Only works if the LLVM MergeFunctions pass is disabled, e.g.
45+ // with `-Z merge-functions=disabled` in RUSTFLAGS.
46+ let disable_dedup_guard = std:: env:: var ( "STDARCH_DISABLE_DEDUP_GUARD" ) . is_ok ( ) ;
47+
4448 // If instruction tests are disabled avoid emitting this shim at all, just
4549 // return the original item without our attribute.
4650 if !cfg ! ( optimized) || disable_assert_instr {
@@ -128,27 +132,38 @@ pub fn assert_instr(
128132 syn:: LitStr :: new ( "C" , proc_macro2:: Span :: call_site ( ) )
129133 } ;
130134 let shim_name_str = format ! ( "{}{}" , shim_name, assert_name) ;
131- let to_test = quote ! {
132-
133- const #shim_name_ptr : * const u8 = #shim_name_str. as_ptr( ) ;
134-
135- #attrs
136- #[ no_mangle]
137- #[ inline( never) ]
138- pub unsafe extern #abi fn #shim_name( #( #inputs) , * ) #ret {
139- // The compiler in optimized mode by default runs a pass called
140- // "mergefunc" where it'll merge functions that look identical.
141- // Turns out some intrinsics produce identical code and they're
142- // folded together, meaning that one just jumps to another. This
143- // messes up our inspection of the disassembly of this function and
144- // we're not a huge fan of that.
145- //
146- // To thwart this pass and prevent functions from being merged we
147- // generate some code that's hopefully very tight in terms of
148- // codegen but is otherwise unique to prevent code from being
149- // folded.
150- :: stdarch_test:: _DONT_DEDUP = #shim_name_ptr;
151- #name:: <#( #const_vals) , * >( #( #input_vals) , * )
135+ let to_test = if disable_dedup_guard {
136+ quote ! {
137+ #attrs
138+ #[ no_mangle]
139+ #[ inline( never) ]
140+ pub unsafe extern #abi fn #shim_name( #( #inputs) , * ) #ret {
141+ #name:: <#( #const_vals) , * >( #( #input_vals) , * )
142+ }
143+ }
144+ } else {
145+ quote ! {
146+
147+ const #shim_name_ptr : * const u8 = #shim_name_str. as_ptr( ) ;
148+
149+ #attrs
150+ #[ no_mangle]
151+ #[ inline( never) ]
152+ pub unsafe extern #abi fn #shim_name( #( #inputs) , * ) #ret {
153+ // The compiler in optimized mode by default runs a pass called
154+ // "mergefunc" where it'll merge functions that look identical.
155+ // Turns out some intrinsics produce identical code and they're
156+ // folded together, meaning that one just jumps to another. This
157+ // messes up our inspection of the disassembly of this function and
158+ // we're not a huge fan of that.
159+ //
160+ // To thwart this pass and prevent functions from being merged we
161+ // generate some code that's hopefully very tight in terms of
162+ // codegen but is otherwise unique to prevent code from being
163+ // folded.
164+ :: stdarch_test:: _DONT_DEDUP = #shim_name_ptr;
165+ #name:: <#( #const_vals) , * >( #( #input_vals) , * )
166+ }
152167 }
153168 } ;
154169
0 commit comments