@@ -120,7 +120,7 @@ impl<'ll, 'tcx> Deref for Builder<'_, 'll, 'tcx> {
120120 }
121121}
122122
123- macro_rules! builder_methods_for_value_instructions {
123+ macro_rules! math_builder_methods {
124124 ( $( $name: ident( $( $arg: ident) ,* ) => $llvm_capi: ident) ,+ $( , ) ?) => {
125125 $( fn $name( & mut self , $( $arg: & ' ll Value ) ,* ) -> & ' ll Value {
126126 unsafe {
@@ -130,6 +130,18 @@ macro_rules! builder_methods_for_value_instructions {
130130 }
131131}
132132
133+ macro_rules! set_math_builder_methods {
134+ ( $( $name: ident( $( $arg: ident) ,* ) => ( $llvm_capi: ident, $llvm_set_math: ident) ) ,+ $( , ) ?) => {
135+ $( fn $name( & mut self , $( $arg: & ' ll Value ) ,* ) -> & ' ll Value {
136+ unsafe {
137+ let instr = llvm:: $llvm_capi( self . llbuilder, $( $arg, ) * UNNAMED ) ;
138+ llvm:: $llvm_set_math( instr) ;
139+ instr
140+ }
141+ } ) +
142+ }
143+ }
144+
133145impl < ' a , ' ll , ' tcx > BuilderMethods < ' a , ' tcx > for Builder < ' a , ' ll , ' tcx > {
134146 type CodegenCx = CodegenCx < ' ll , ' tcx > ;
135147
@@ -267,7 +279,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
267279 }
268280 }
269281
270- builder_methods_for_value_instructions ! {
282+ math_builder_methods ! {
271283 add( a, b) => LLVMBuildAdd ,
272284 fadd( a, b) => LLVMBuildFAdd ,
273285 sub( a, b) => LLVMBuildSub ,
@@ -299,84 +311,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
299311 unchecked_umul( x, y) => LLVMBuildNUWMul ,
300312 }
301313
302- fn fadd_fast ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
303- unsafe {
304- let instr = llvm:: LLVMBuildFAdd ( self . llbuilder , lhs, rhs, UNNAMED ) ;
305- llvm:: LLVMRustSetFastMath ( instr) ;
306- instr
307- }
308- }
309-
310- fn fsub_fast ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
311- unsafe {
312- let instr = llvm:: LLVMBuildFSub ( self . llbuilder , lhs, rhs, UNNAMED ) ;
313- llvm:: LLVMRustSetFastMath ( instr) ;
314- instr
315- }
316- }
317-
318- fn fmul_fast ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
319- unsafe {
320- let instr = llvm:: LLVMBuildFMul ( self . llbuilder , lhs, rhs, UNNAMED ) ;
321- llvm:: LLVMRustSetFastMath ( instr) ;
322- instr
323- }
324- }
325-
326- fn fdiv_fast ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
327- unsafe {
328- let instr = llvm:: LLVMBuildFDiv ( self . llbuilder , lhs, rhs, UNNAMED ) ;
329- llvm:: LLVMRustSetFastMath ( instr) ;
330- instr
331- }
332- }
333-
334- fn frem_fast ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
335- unsafe {
336- let instr = llvm:: LLVMBuildFRem ( self . llbuilder , lhs, rhs, UNNAMED ) ;
337- llvm:: LLVMRustSetFastMath ( instr) ;
338- instr
339- }
340- }
341-
342- fn fadd_algebraic ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
343- unsafe {
344- let instr = llvm:: LLVMBuildFAdd ( self . llbuilder , lhs, rhs, UNNAMED ) ;
345- llvm:: LLVMRustSetAlgebraicMath ( instr) ;
346- instr
347- }
348- }
349-
350- fn fsub_algebraic ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
351- unsafe {
352- let instr = llvm:: LLVMBuildFSub ( self . llbuilder , lhs, rhs, UNNAMED ) ;
353- llvm:: LLVMRustSetAlgebraicMath ( instr) ;
354- instr
355- }
356- }
357-
358- fn fmul_algebraic ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
359- unsafe {
360- let instr = llvm:: LLVMBuildFMul ( self . llbuilder , lhs, rhs, UNNAMED ) ;
361- llvm:: LLVMRustSetAlgebraicMath ( instr) ;
362- instr
363- }
364- }
365-
366- fn fdiv_algebraic ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
367- unsafe {
368- let instr = llvm:: LLVMBuildFDiv ( self . llbuilder , lhs, rhs, UNNAMED ) ;
369- llvm:: LLVMRustSetAlgebraicMath ( instr) ;
370- instr
371- }
372- }
373-
374- fn frem_algebraic ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
375- unsafe {
376- let instr = llvm:: LLVMBuildFRem ( self . llbuilder , lhs, rhs, UNNAMED ) ;
377- llvm:: LLVMRustSetAlgebraicMath ( instr) ;
378- instr
379- }
314+ set_math_builder_methods ! {
315+ fadd_fast( x, y) => ( LLVMBuildFAdd , LLVMRustSetFastMath ) ,
316+ fsub_fast( x, y) => ( LLVMBuildFSub , LLVMRustSetFastMath ) ,
317+ fmul_fast( x, y) => ( LLVMBuildFMul , LLVMRustSetFastMath ) ,
318+ fdiv_fast( x, y) => ( LLVMBuildFDiv , LLVMRustSetFastMath ) ,
319+ frem_fast( x, y) => ( LLVMBuildFRem , LLVMRustSetFastMath ) ,
320+ fadd_algebraic( x, y) => ( LLVMBuildFAdd , LLVMRustSetAlgebraicMath ) ,
321+ fsub_algebraic( x, y) => ( LLVMBuildFSub , LLVMRustSetAlgebraicMath ) ,
322+ fmul_algebraic( x, y) => ( LLVMBuildFMul , LLVMRustSetAlgebraicMath ) ,
323+ fdiv_algebraic( x, y) => ( LLVMBuildFDiv , LLVMRustSetAlgebraicMath ) ,
324+ frem_algebraic( x, y) => ( LLVMBuildFRem , LLVMRustSetAlgebraicMath ) ,
380325 }
381326
382327 fn checked_binop (
@@ -459,6 +404,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
459404 val
460405 }
461406 }
407+
462408 fn to_immediate_scalar ( & mut self , val : Self :: Value , scalar : abi:: Scalar ) -> Self :: Value {
463409 if scalar. is_bool ( ) {
464410 return self . trunc ( val, self . cx ( ) . type_i1 ( ) ) ;
@@ -727,11 +673,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
727673 // for performance. LLVM doesn't seem to care about this, and will happily treat
728674 // `!nontemporal` stores as-if they were normal stores (for reordering optimizations
729675 // etc) even on x86, despite later lowering them to MOVNT which do *not* behave like
730- // regular stores but require special fences.
731- // So we keep a list of architectures where `!nontemporal` is known to be truly just
732- // a hint, and use regular stores everywhere else.
733- // (In the future, we could alternatively ensure that an sfence gets emitted after a sequence of movnt
734- // before any kind of synchronizing operation. But it's not clear how to do that with LLVM.)
676+ // regular stores but require special fences. So we keep a list of architectures
677+ // where `!nontemporal` is known to be truly just a hint, and use regular stores
678+ // everywhere else. (In the future, we could alternatively ensure that an sfence
679+ // gets emitted after a sequence of movnt before any kind of synchronizing
680+ // operation. But it's not clear how to do that with LLVM.)
735681 // For more context, see <https://github.com/rust-lang/rust/issues/114582> and
736682 // <https://github.com/llvm/llvm-project/issues/64521>.
737683 const WELL_BEHAVED_NONTEMPORAL_ARCHS : & [ & str ] =
@@ -1160,6 +1106,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11601106 ( val, success)
11611107 }
11621108 }
1109+
11631110 fn atomic_rmw (
11641111 & mut self ,
11651112 op : rustc_codegen_ssa:: common:: AtomicRmwBinOp ,
0 commit comments