Message ID | 20210331074137.1046367-1-stli@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | S390: Allow "v" constraint for long double math_opt_barrier and math_force_eval with GCC 11. | expand |
* Stefan Liebler via Libc-alpha: with GCC 11, long double values can also be processed in vector > registers if build with -march >= z14. Then GCC defines the > __LONG_DOUBLE_VX__ macro. > > FYI: GCC commit "IBM Z: Introduce __LONG_DOUBLE_VX__ macro" > https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=f47df2af313d2ce7f9149149010a142c2237beda > --- > sysdeps/s390/fpu/math-barriers.h | 21 +++++++++++++++++++-- > 1 file changed, 19 insertions(+), 2 deletions(-) > > diff --git a/sysdeps/s390/fpu/math-barriers.h b/sysdeps/s390/fpu/math-barriers.h > index 68a3e55098..a47cda8b24 100644 > --- a/sysdeps/s390/fpu/math-barriers.h > +++ b/sysdeps/s390/fpu/math-barriers.h > @@ -25,9 +25,22 @@ > # define ASM_CONSTRAINT_VR > #endif > > +/* Starting with gcc 11, long double values can also be processed in vector > + registers if build with -march >= z14. Then GCC defines the > + __LONG_DOUBLE_VX__ macro. */ > +#ifdef __LONG_DOUBLE_VX__ > +# define ASM_LONG_DOUBLE_IN_VR 1 > +#else > +# define ASM_LONG_DOUBLE_IN_VR 0 > +#endif Above that there is: #ifdef HAVE_S390_VX_GCC_SUPPORT # define ASM_CONSTRAINT_VR "v" #else # define ASM_CONSTRAINT_VR #endif I think conceptually, ASM_LONG_DOUBLE_IN_VR should be set under HAVE_S390_VX_GCC_SUPPORT, right? Or maybe enforce this with #error?
On 31/03/2021 11:34, Florian Weimer wrote: > * Stefan Liebler via Libc-alpha: >> +/* Starting with gcc 11, long double values can also be processed in vector >> + registers if build with -march >= z14. Then GCC defines the >> + __LONG_DOUBLE_VX__ macro. */ >> +#ifdef __LONG_DOUBLE_VX__ >> +# define ASM_LONG_DOUBLE_IN_VR 1 >> +#else >> +# define ASM_LONG_DOUBLE_IN_VR 0 >> +#endif > > Above that there is: > > #ifdef HAVE_S390_VX_GCC_SUPPORT > # define ASM_CONSTRAINT_VR "v" > #else > # define ASM_CONSTRAINT_VR > #endif > > I think conceptually, ASM_LONG_DOUBLE_IN_VR should be set under > HAVE_S390_VX_GCC_SUPPORT, right? Hi Florian, yes, you are right. GCC will only define __LONG_DOUBLE_VX__ if it knows about vector registers and HAVE_S390_VX_GCC_SUPPORT will always be defined in this case. If HAVE_S390_VX_GCC_SUPPORT would not be defined, but __LONG_DOUBLE_VX__, then the constraint "fm" will be used in all asm statements. But nevertheless, setting ASM_LONG_DOUBLE_IN_VR under HAVE_S390_VX_GCC_SUPPORT makes it more cleanly. I've just posted a v2: https://sourceware.org/pipermail/libc-alpha/2021-March/124606.html Thanks, Stefan
diff --git a/sysdeps/s390/fpu/math-barriers.h b/sysdeps/s390/fpu/math-barriers.h index 68a3e55098..a47cda8b24 100644 --- a/sysdeps/s390/fpu/math-barriers.h +++ b/sysdeps/s390/fpu/math-barriers.h @@ -25,9 +25,22 @@ # define ASM_CONSTRAINT_VR #endif +/* Starting with gcc 11, long double values can also be processed in vector + registers if build with -march >= z14. Then GCC defines the + __LONG_DOUBLE_VX__ macro. */ +#ifdef __LONG_DOUBLE_VX__ +# define ASM_LONG_DOUBLE_IN_VR 1 +#else +# define ASM_LONG_DOUBLE_IN_VR 0 +#endif + #define math_opt_barrier(x) \ ({ __typeof (x) __x = (x); \ - if (__builtin_types_compatible_p (__typeof (x), _Float128)) \ + if (! ASM_LONG_DOUBLE_IN_VR \ + && (__builtin_types_compatible_p (__typeof (x), _Float128) \ + || __builtin_types_compatible_p (__typeof (x), long double) \ + ) \ + ) \ __asm__ ("# math_opt_barrier_f128 %0" : "+fm" (__x)); \ else \ __asm__ ("# math_opt_barrier %0" \ @@ -35,7 +48,11 @@ __x; }) #define math_force_eval(x) \ ({ __typeof (x) __x = (x); \ - if (__builtin_types_compatible_p (__typeof (x), _Float128)) \ + if (! ASM_LONG_DOUBLE_IN_VR \ + && (__builtin_types_compatible_p (__typeof (x), _Float128) \ + || __builtin_types_compatible_p (__typeof (x), long double) \ + ) \ + ) \ __asm__ __volatile__ ("# math_force_eval_f128 %0" \ : : "fm" (__x)); \ else \