@@ -120,7 +120,7 @@ impl<'ll, 'tcx> Deref for Builder<'_, 'll, 'tcx> {
120
120
}
121
121
}
122
122
123
- macro_rules! builder_methods_for_value_instructions {
123
+ macro_rules! math_builder_methods {
124
124
( $( $name: ident( $( $arg: ident) ,* ) => $llvm_capi: ident) ,+ $( , ) ?) => {
125
125
$( fn $name( & mut self , $( $arg: & ' ll Value ) ,* ) -> & ' ll Value {
126
126
unsafe {
@@ -130,6 +130,18 @@ macro_rules! builder_methods_for_value_instructions {
130
130
}
131
131
}
132
132
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
+
133
145
impl < ' a , ' ll , ' tcx > BuilderMethods < ' a , ' tcx > for Builder < ' a , ' ll , ' tcx > {
134
146
type CodegenCx = CodegenCx < ' ll , ' tcx > ;
135
147
@@ -267,7 +279,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
267
279
}
268
280
}
269
281
270
- builder_methods_for_value_instructions ! {
282
+ math_builder_methods ! {
271
283
add( a, b) => LLVMBuildAdd ,
272
284
fadd( a, b) => LLVMBuildFAdd ,
273
285
sub( a, b) => LLVMBuildSub ,
@@ -299,84 +311,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
299
311
unchecked_umul( x, y) => LLVMBuildNUWMul ,
300
312
}
301
313
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 ) ,
380
325
}
381
326
382
327
fn checked_binop (
@@ -459,6 +404,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
459
404
val
460
405
}
461
406
}
407
+
462
408
fn to_immediate_scalar ( & mut self , val : Self :: Value , scalar : abi:: Scalar ) -> Self :: Value {
463
409
if scalar. is_bool ( ) {
464
410
return self . trunc ( val, self . cx ( ) . type_i1 ( ) ) ;
@@ -727,11 +673,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
727
673
// for performance. LLVM doesn't seem to care about this, and will happily treat
728
674
// `!nontemporal` stores as-if they were normal stores (for reordering optimizations
729
675
// 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.)
735
681
// For more context, see <https://github.com/rust-lang/rust/issues/114582> and
736
682
// <https://github.com/llvm/llvm-project/issues/64521>.
737
683
const WELL_BEHAVED_NONTEMPORAL_ARCHS : & [ & str ] =
@@ -1160,6 +1106,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1160
1106
( val, success)
1161
1107
}
1162
1108
}
1109
+
1163
1110
fn atomic_rmw (
1164
1111
& mut self ,
1165
1112
op : rustc_codegen_ssa:: common:: AtomicRmwBinOp ,
0 commit comments