@@ -4,9 +4,7 @@ mod simd;
4
4
#[ cfg( feature = "master" ) ]
5
5
use std:: iter;
6
6
7
- #[ cfg( feature = "master" ) ]
8
- use gccjit:: FunctionType ;
9
- use gccjit:: { ComparisonOp , Function , RValue , ToRValue , Type , UnaryOp } ;
7
+ use gccjit:: { ComparisonOp , Function , FunctionType , RValue , ToRValue , Type , UnaryOp } ;
10
8
#[ cfg( feature = "master" ) ]
11
9
use rustc_abi:: ExternAbi ;
12
10
use rustc_abi:: { BackendRepr , HasDataLayout } ;
@@ -96,6 +94,72 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
96
94
Some ( cx. context . get_builtin_function ( gcc_name) )
97
95
}
98
96
97
+ // TODO(antoyo): We can probably remove these and use the fallback intrinsic implementation.
98
+ fn get_simple_function < ' gcc , ' tcx > (
99
+ cx : & CodegenCx < ' gcc , ' tcx > ,
100
+ name : Symbol ,
101
+ ) -> Option < Function < ' gcc > > {
102
+ let ( return_type, parameters, func_name) = match name {
103
+ sym:: minimumf32 => {
104
+ let parameters = [
105
+ cx. context . new_parameter ( None , cx. float_type , "a" ) ,
106
+ cx. context . new_parameter ( None , cx. float_type , "b" ) ,
107
+ ] ;
108
+ ( cx. float_type , parameters, "fminimumf" )
109
+ }
110
+ sym:: minimumf64 => {
111
+ let parameters = [
112
+ cx. context . new_parameter ( None , cx. double_type , "a" ) ,
113
+ cx. context . new_parameter ( None , cx. double_type , "b" ) ,
114
+ ] ;
115
+ ( cx. double_type , parameters, "fminimum" )
116
+ }
117
+ sym:: minimumf128 => {
118
+ let f128_type = cx. type_f128 ( ) ;
119
+ // GCC doesn't have the intrinsic we want so we use the compiler-builtins one
120
+ // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html
121
+ let parameters = [
122
+ cx. context . new_parameter ( None , f128_type, "a" ) ,
123
+ cx. context . new_parameter ( None , f128_type, "b" ) ,
124
+ ] ;
125
+ ( f128_type, parameters, "fminimumf128" )
126
+ }
127
+ sym:: maximumf32 => {
128
+ let parameters = [
129
+ cx. context . new_parameter ( None , cx. float_type , "a" ) ,
130
+ cx. context . new_parameter ( None , cx. float_type , "b" ) ,
131
+ ] ;
132
+ ( cx. float_type , parameters, "fmaximumf" )
133
+ }
134
+ sym:: maximumf64 => {
135
+ let parameters = [
136
+ cx. context . new_parameter ( None , cx. double_type , "a" ) ,
137
+ cx. context . new_parameter ( None , cx. double_type , "b" ) ,
138
+ ] ;
139
+ ( cx. double_type , parameters, "fmaximum" )
140
+ }
141
+ sym:: maximumf128 => {
142
+ let f128_type = cx. type_f128 ( ) ;
143
+ // GCC doesn't have the intrinsic we want so we use the compiler-builtins one
144
+ // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html
145
+ let parameters = [
146
+ cx. context . new_parameter ( None , f128_type, "a" ) ,
147
+ cx. context . new_parameter ( None , f128_type, "b" ) ,
148
+ ] ;
149
+ ( f128_type, parameters, "fmaximumf128" )
150
+ }
151
+ _ => return None ,
152
+ } ;
153
+ Some ( cx. context . new_function (
154
+ None ,
155
+ FunctionType :: Extern ,
156
+ return_type,
157
+ & parameters,
158
+ func_name,
159
+ false ,
160
+ ) )
161
+ }
162
+
99
163
impl < ' a , ' gcc , ' tcx > IntrinsicCallBuilderMethods < ' tcx > for Builder < ' a , ' gcc , ' tcx > {
100
164
fn codegen_intrinsic_call (
101
165
& mut self ,
@@ -124,14 +188,23 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
124
188
let result = PlaceRef :: new_sized ( llresult, fn_abi. ret . layout ) ;
125
189
126
190
let simple = get_simple_intrinsic ( self , name) ;
191
+ let simple_func = get_simple_function ( self , name) ;
127
192
128
193
// FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved:
129
194
// https://github.com/rust-lang/rust-clippy/issues/12497
130
195
// and leave `else if use_integer_compare` to be placed "as is".
131
196
#[ allow( clippy:: suspicious_else_formatting) ]
132
197
let value = match name {
133
198
_ if simple. is_some ( ) => {
134
- let func = simple. expect ( "simple function" ) ;
199
+ let func = simple. expect ( "simple intrinsic function" ) ;
200
+ self . cx . context . new_call (
201
+ self . location ,
202
+ func,
203
+ & args. iter ( ) . map ( |arg| arg. immediate ( ) ) . collect :: < Vec < _ > > ( ) ,
204
+ )
205
+ }
206
+ _ if simple_func. is_some ( ) => {
207
+ let func = simple_func. expect ( "simple function" ) ;
135
208
self . cx . context . new_call (
136
209
self . location ,
137
210
func,
@@ -399,7 +472,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
399
472
}
400
473
401
474
// Fall back to default body
402
- _ => return Err ( Instance :: new ( instance. def_id ( ) , instance. args ) ) ,
475
+ _ => return Err ( Instance :: new_raw ( instance. def_id ( ) , instance. args ) ) ,
403
476
} ;
404
477
405
478
if !fn_abi. ret . is_ignore ( ) {
0 commit comments