@@ -34,6 +34,10 @@ trait TestableFloat: Sized {
3434 const RAW_12_DOT_5 : Self ;
3535 const RAW_1337 : Self ;
3636 const RAW_MINUS_14_DOT_25 : Self ;
37+ /// The result of 12.3.mul_add(4.5, 6.7)
38+ const MUL_ADD_RESULT : Self ;
39+ /// The result of (-12.3).mul_add(-4.5, -6.7)
40+ const NEG_MUL_ADD_RESULT : Self ;
3741}
3842
3943impl TestableFloat for f16 {
@@ -58,6 +62,8 @@ impl TestableFloat for f16 {
5862 const RAW_12_DOT_5 : Self = Self :: from_bits ( 0x4a40 ) ;
5963 const RAW_1337 : Self = Self :: from_bits ( 0x6539 ) ;
6064 const RAW_MINUS_14_DOT_25 : Self = Self :: from_bits ( 0xcb20 ) ;
65+ const MUL_ADD_RESULT : Self = 62.031 ;
66+ const NEG_MUL_ADD_RESULT : Self = 48.625 ;
6167}
6268
6369impl TestableFloat for f32 {
@@ -84,6 +90,8 @@ impl TestableFloat for f32 {
8490 const RAW_12_DOT_5 : Self = Self :: from_bits ( 0x41480000 ) ;
8591 const RAW_1337 : Self = Self :: from_bits ( 0x44a72000 ) ;
8692 const RAW_MINUS_14_DOT_25 : Self = Self :: from_bits ( 0xc1640000 ) ;
93+ const MUL_ADD_RESULT : Self = 62.05 ;
94+ const NEG_MUL_ADD_RESULT : Self = 48.65 ;
8795}
8896
8997impl TestableFloat for f64 {
@@ -106,6 +114,8 @@ impl TestableFloat for f64 {
106114 const RAW_12_DOT_5 : Self = Self :: from_bits ( 0x4029000000000000 ) ;
107115 const RAW_1337 : Self = Self :: from_bits ( 0x4094e40000000000 ) ;
108116 const RAW_MINUS_14_DOT_25 : Self = Self :: from_bits ( 0xc02c800000000000 ) ;
117+ const MUL_ADD_RESULT : Self = 62.050000000000004 ;
118+ const NEG_MUL_ADD_RESULT : Self = 48.650000000000006 ;
109119}
110120
111121impl TestableFloat for f128 {
@@ -128,6 +138,8 @@ impl TestableFloat for f128 {
128138 const RAW_12_DOT_5 : Self = Self :: from_bits ( 0x40029000000000000000000000000000 ) ;
129139 const RAW_1337 : Self = Self :: from_bits ( 0x40094e40000000000000000000000000 ) ;
130140 const RAW_MINUS_14_DOT_25 : Self = Self :: from_bits ( 0xc002c800000000000000000000000000 ) ;
141+ const MUL_ADD_RESULT : Self = 62.0500000000000000000000000000000037 ;
142+ const NEG_MUL_ADD_RESULT : Self = 48.6500000000000000000000000000000049 ;
131143}
132144
133145/// Determine the tolerance for values of the argument type.
@@ -359,8 +371,6 @@ macro_rules! float_test {
359371
360372mod f128;
361373mod f16;
362- mod f32;
363- mod f64;
364374
365375float_test ! {
366376 name: num,
@@ -1541,3 +1551,28 @@ float_test! {
15411551 assert_biteq!( Float :: from_bits( masked_nan2) , Float :: from_bits( masked_nan2) ) ;
15421552 }
15431553}
1554+
1555+ float_test ! {
1556+ name: mul_add,
1557+ attrs: {
1558+ f16: #[ cfg( any( miri, target_has_reliable_f16) ) ] ,
1559+ // FIXME(#140515): mingw has an incorrect fma https://sourceforge.net/p/mingw-w64/bugs/848/
1560+ f32 : #[ cfg_attr( all( target_os = "windows" , target_env = "gnu" , not( target_abi = "llvm" ) ) , ignore) ] ,
1561+ f64 : #[ cfg_attr( all( target_os = "windows" , target_env = "gnu" , not( target_abi = "llvm" ) ) , ignore) ] ,
1562+ f128: #[ cfg( any( miri, target_has_reliable_f128) ) ] ,
1563+ } ,
1564+ test<Float > {
1565+ let nan: Float = Float :: NAN ;
1566+ let inf: Float = Float :: INFINITY ;
1567+ let neg_inf: Float = Float :: NEG_INFINITY ;
1568+ assert_biteq!( flt( 12.3 ) . mul_add( 4.5 , 6.7 ) , Float :: MUL_ADD_RESULT ) ;
1569+ assert_biteq!( ( flt( -12.3 ) ) . mul_add( -4.5 , -6.7 ) , Float :: NEG_MUL_ADD_RESULT ) ;
1570+ assert_biteq!( flt( 0.0 ) . mul_add( 8.9 , 1.2 ) , 1.2 ) ;
1571+ assert_biteq!( flt( 3.4 ) . mul_add( -0.0 , 5.6 ) , 5.6 ) ;
1572+ assert!( nan. mul_add( 7.8 , 9.0 ) . is_nan( ) ) ;
1573+ assert_biteq!( inf. mul_add( 7.8 , 9.0 ) , inf) ;
1574+ assert_biteq!( neg_inf. mul_add( 7.8 , 9.0 ) , neg_inf) ;
1575+ assert_biteq!( flt( 8.9 ) . mul_add( inf, 3.2 ) , inf) ;
1576+ assert_biteq!( ( flt( -3.2 ) ) . mul_add( 2.4 , neg_inf) , neg_inf) ;
1577+ }
1578+ }
0 commit comments