@@ -4,9 +4,7 @@ mod simd;
44#[ cfg( feature = "master" ) ]
55use std:: iter;
66
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 } ;
108#[ cfg( feature = "master" ) ]
119use rustc_abi:: ExternAbi ;
1210use rustc_abi:: { BackendRepr , HasDataLayout } ;
@@ -96,6 +94,72 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
9694 Some ( cx. context . get_builtin_function ( gcc_name) )
9795}
9896
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+
99163impl < ' a , ' gcc , ' tcx > IntrinsicCallBuilderMethods < ' tcx > for Builder < ' a , ' gcc , ' tcx > {
100164 fn codegen_intrinsic_call (
101165 & mut self ,
@@ -124,14 +188,23 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
124188 let result = PlaceRef :: new_sized ( llresult, fn_abi. ret . layout ) ;
125189
126190 let simple = get_simple_intrinsic ( self , name) ;
191+ let simple_func = get_simple_function ( self , name) ;
127192
128193 // FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved:
129194 // https://github.com/rust-lang/rust-clippy/issues/12497
130195 // and leave `else if use_integer_compare` to be placed "as is".
131196 #[ allow( clippy:: suspicious_else_formatting) ]
132197 let value = match name {
133198 _ 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" ) ;
135208 self . cx . context . new_call (
136209 self . location ,
137210 func,
@@ -399,7 +472,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
399472 }
400473
401474 // 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 ) ) ,
403476 } ;
404477
405478 if !fn_abi. ret . is_ignore ( ) {
0 commit comments