public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Re: [RFC] x86_64: Add SSE sfp-exceptions
@ 2020-04-19  9:54 Uros Bizjak
  2020-04-19 20:17 ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: Uros Bizjak @ 2020-04-19  9:54 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, Florian Weimer, adhemerval.zanella, H. J. Lu

[-- Attachment #1: Type: text/plain, Size: 1918 bytes --]

> Can somebody of the x86 maintainers have a look at this patch, please?
>
> On 3/30/20 9:28 PM, Adhemerval Zanella via Libc-alpha wrote:
> > The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> > they should work on both float, double, and long double) while the
> > internal libc_fe* set either SSE (float, double, and float128) or
> > i387 (long double).
> >
> > The libgcc __sfp_handle_exceptions (used on float128 implementation),
> > however, will set either SEE or i387 exception depending of the
> > exception to raise.  This broke the internal assumption of float128
> > where only SSE operations will be used.
> >
> > This patch reimplements the libgcc __sfp_handle_exceptions to use only
> > SSE operations and sets libgcc to use it instead of its own
> > implementation.
> >
> > And I think we should fix libgcc in a similar manner, since checking on
> > config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> > and x86_64 ABI also expectes float128 to use SSE registers [1]
> > (although it is not clear on how future implementation might implement
> > it).
> >
> > Checked on x86_64-linux-gnu.

I don't think the new implementation is correct. Please consider
attached testcase that compares GCC implementation to the new
implementation. Specifically, PE, OF and UF exceptions do not work as
expected.

For the compiled testcase, GCC version returns:

$ ./a.out
 PE  .  .  .  .
  . UE  .  .  .
  .  . OF  .  .
  .  .  . ZE  .
  .  .  .  .  .
  .  .  .  . IE

where the new implementation (compile with -DNEW) returns:

$ ./a.out
  .  .  .  .  .
  .  .  .  .  .
 PE  . OF  .  .
  .  .  . ZE  .
  .  .  .  .  .
  .  .  .  . IE

For reference, with -m32 -DNEW (so, x87 math) , the new implementation return:

$ ./a.out
  .  .  .  .  .
  .  .  .  .  .
  .  .  .  .  .
  .  .  . ZE  .
  .  .  .  .  .
  .  .  .  . IE

which is again different from GCC version.

Uros.

[-- Attachment #2: exc.c --]
[-- Type: text/x-csrc, Size: 4674 bytes --]

#include <fenv.h>
#include <float.h>
#include <stdio.h>

#define FP_EX_INVALID           0x01
#define FP_EX_DENORM            0x02
#define FP_EX_DIVZERO           0x04
#define FP_EX_OVERFLOW          0x08
#define FP_EX_UNDERFLOW         0x10
#define FP_EX_INEXACT           0x20
#define FP_EX_ALL \
        (FP_EX_INVALID | FP_EX_DENORM | FP_EX_DIVZERO | FP_EX_OVERFLOW \
         | FP_EX_UNDERFLOW | FP_EX_INEXACT)


#ifdef NEW
#ifdef __SSE_MATH__
# define math_force_eval(x) __asm __volatile ("" : : "x" (x));
#else
# define math_force_eval(x) __asm __volatile ("" : : "f" (x));
#endif

void
__attribute__((noinline))
__sfp_handle_exceptions (int _fex)
{
  if (_fex & FP_EX_INVALID)
    {
      float f = 0.0f;
      math_force_eval (f / f);
    }
  if (_fex & FP_EX_DENORM)
    {
      float f = FLT_MIN, g = 2.0f;
      math_force_eval (f / g);
    }
  if (_fex & FP_EX_DIVZERO)
    {
      float f = 1.0f, g = 0.0f;
      math_force_eval (f / g);
    }
  if (_fex & FP_EX_OVERFLOW)
    {
      float force_underflow = FLT_MAX * FLT_MAX;
      math_force_eval (force_underflow);
    }
  if (_fex & FP_EX_UNDERFLOW)
    {
      float force_overflow = FLT_MIN * FLT_MIN;
      math_force_eval (force_overflow);
    }
  if (_fex & FP_EX_INEXACT)
    {
      float f = 1.0f, g = 3.0f;
      math_force_eval (f / g);
    }
}
#else
struct fenv
{
  unsigned short int __control_word;
  unsigned short int __unused1;
  unsigned short int __status_word;
  unsigned short int __unused2;
  unsigned short int __tags;
  unsigned short int __unused3;
  unsigned int __eip;
  unsigned short int __cs_selector;
  unsigned int __opcode:11;
  unsigned int __unused4:5;
  unsigned int __data_offset;
  unsigned short int __data_selector;
  unsigned short int __unused5;
};

void
__attribute__((noinline))
__sfp_handle_exceptions (int _fex)
{
  if (_fex & FP_EX_INVALID)
    {
      float f = 0.0f;
#ifdef __SSE_MATH__
      volatile float r __attribute__ ((unused));
      asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
      r = f; /* Needed to trigger exception.   */
#else
      asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
      /* No need for fwait, exception is triggered by emitted fstp.  */
#endif
    }
  if (_fex & FP_EX_DENORM)
    {
      struct fenv temp;
      asm volatile ("fnstenv\t%0" : "=m" (temp));
      temp.__status_word |= FP_EX_DENORM;
      asm volatile ("fldenv\t%0" : : "m" (temp));
      asm volatile ("fwait");
    }
  if (_fex & FP_EX_DIVZERO)
    {
      float f = 1.0f, g = 0.0f;
#ifdef __SSE_MATH__
      volatile float r __attribute__ ((unused));
      asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
      r = f; /* Needed to trigger exception.   */
#else
      asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
      /* No need for fwait, exception is triggered by emitted fstp.  */
#endif
    }
  if (_fex & FP_EX_OVERFLOW)
    {
      struct fenv temp;
      asm volatile ("fnstenv\t%0" : "=m" (temp));
      temp.__status_word |= FP_EX_OVERFLOW;
      asm volatile ("fldenv\t%0" : : "m" (temp));
      asm volatile ("fwait");
    }
  if (_fex & FP_EX_UNDERFLOW)
    {
      struct fenv temp;
      asm volatile ("fnstenv\t%0" : "=m" (temp));
      temp.__status_word |= FP_EX_UNDERFLOW;
      asm volatile ("fldenv\t%0" : : "m" (temp));
      asm volatile ("fwait");
    }
  if (_fex & FP_EX_INEXACT)
    {
      float f = 1.0f, g = 3.0f;
#ifdef __SSE_MATH__
      volatile float r __attribute__ ((unused));
      asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
      r = f; /* Needed to trigger exception.   */
#else
      asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
      /* No need for fwait, exception is triggered by emitted fstp.  */
#endif
    }
}
#endif

void
printexcepts (void)
{
  int __excepts = fetestexcept (FE_ALL_EXCEPT);

  printf ("%3s%3s%3s%3s%3s\n",
	  __excepts & FE_INEXACT ? "PE" : ".",
	  __excepts & FE_UNDERFLOW ? "UE" : ".",
	  __excepts & FE_OVERFLOW ? "OF" : ".",
	  __excepts & FE_DIVBYZERO ? "ZE" : ".",
	  __excepts & FE_INVALID ? "IE" : ".");
}

int
main ()
{
  feclearexcept (FE_ALL_EXCEPT);
  __sfp_handle_exceptions (FP_EX_INEXACT);
  printexcepts ();

  feclearexcept (FE_ALL_EXCEPT);
  __sfp_handle_exceptions (FP_EX_UNDERFLOW);
  printexcepts();

  feclearexcept (FE_ALL_EXCEPT);
  __sfp_handle_exceptions (FP_EX_OVERFLOW);
  printexcepts ();

  feclearexcept (FE_ALL_EXCEPT);
  __sfp_handle_exceptions (FP_EX_DIVZERO);
  printexcepts ();

  feclearexcept (FE_ALL_EXCEPT);
  __sfp_handle_exceptions (FP_EX_DENORM);
  printexcepts ();

  feclearexcept (FE_ALL_EXCEPT);
  __sfp_handle_exceptions (FP_EX_INVALID);
  printexcepts ();

  return 0;
}
    

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-19  9:54 [RFC] x86_64: Add SSE sfp-exceptions Uros Bizjak
@ 2020-04-19 20:17 ` Adhemerval Zanella
  2020-04-19 20:48   ` Uros Bizjak
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2020-04-19 20:17 UTC (permalink / raw)
  To: Uros Bizjak, libc-alpha; +Cc: stli, Florian Weimer, H. J. Lu



On 19/04/2020 06:54, Uros Bizjak wrote:
>> Can somebody of the x86 maintainers have a look at this patch, please?
>>
>> On 3/30/20 9:28 PM, Adhemerval Zanella via Libc-alpha wrote:
>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
>>> they should work on both float, double, and long double) while the
>>> internal libc_fe* set either SSE (float, double, and float128) or
>>> i387 (long double).
>>>
>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
>>> however, will set either SEE or i387 exception depending of the
>>> exception to raise.  This broke the internal assumption of float128
>>> where only SSE operations will be used.
>>>
>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
>>> SSE operations and sets libgcc to use it instead of its own
>>> implementation.
>>>
>>> And I think we should fix libgcc in a similar manner, since checking on
>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
>>> (although it is not clear on how future implementation might implement
>>> it).
>>>
>>> Checked on x86_64-linux-gnu.
> 
> I don't think the new implementation is correct. Please consider
> attached testcase that compares GCC implementation to the new
> implementation. Specifically, PE, OF and UF exceptions do not work as
> expected.

Indeed my patch does not work correctly for underflow and overflow 
exceptions.  But your example also is not fully correct because
glibc fetestexcept will return an union of both i387 and SSE
exception, where we should test only for SSE in this specific case. 

To correctly check if SSE exceptions flags your testcase should
use something like:

  int
  feclearexcept_sse (int excepts)
  {
    unsigned int mxcsr;
    excepts &= FE_ALL_EXCEPT;
    __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
    mxcsr &= ~excepts;
    __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
    return 0;
  }

  int
  fetestexcept_sse (int excepts)
  {
    unsigned int mxscr;
    __asm__ ("stmxcsr %0" : "=m" (*&mxscr));
    return (mxscr) & excepts & FE_ALL_EXCEPT;
  }

I thought I could force overflow and underflow with only math operations,
but it seems it no easy without also generating inexact ones. We should 
use instead:

  if (_fex & FP_EX_OVERFLOW)
    {
      unsigned int mxcsr;
      __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
      mxcsr |= FP_EX_OVERFLOW & FE_ALL_EXCEPT;
      __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
    }
  if (_fex & FP_EX_UNDERFLOW)
    {
      unsigned int mxcsr;
      __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
      mxcsr |= FP_EX_UNDERFLOW & FE_ALL_EXCEPT;
      __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
    }

With these change and checking only SSE exceptions I see:

$ gcc -Wall -m64 exe.c -o exe -DNEW -O0 -g && ./exe 
 PE  .  .  .  .
  . UE  .  .  .
  .  . OF  .  .
  .  .  . ZE  .
  .  .  .  .  .
  .  .  .  . IE

I will fix and add a testcase as well.

> 
> For the compiled testcase, GCC version returns:
> 
> $ ./a.out
>  PE  .  .  .  .
>   . UE  .  .  .
>   .  . OF  .  .
>   .  .  . ZE  .
>   .  .  .  .  .
>   .  .  .  . IE
> 
> where the new implementation (compile with -DNEW) returns:
> 
> $ ./a.out
>   .  .  .  .  .
>   .  .  .  .  .
>  PE  . OF  .  .
>   .  .  . ZE  .
>   .  .  .  .  .
>   .  .  .  . IE
> 
> For reference, with -m32 -DNEW (so, x87 math) , the new implementation return:

Yes, this implementation does not handle i686/x87 and it is compiled only
for x86_64. And assuming that i686 _Float128 ABI follows x86_64, we should
fix for i686 as well.

> 
> $ ./a.out
>   .  .  .  .  .
>   .  .  .  .  .
>   .  .  .  .  .
>   .  .  . ZE  .
>   .  .  .  .  .
>   .  .  .  . IE
> 
> which is again different from GCC version.

But the question is whether _Float128 operation should generate x87 exceptions.
My understanding is it shouldn't for x86_64, however I am not sure for i686
(since I am not sure how extensible __sfp_handle_exceptions is used on i686
target and in which routines).


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-19 20:17 ` Adhemerval Zanella
@ 2020-04-19 20:48   ` Uros Bizjak
  2020-04-20 11:09     ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: Uros Bizjak @ 2020-04-19 20:48 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, stli, Florian Weimer, H. J. Lu

On Sun, Apr 19, 2020 at 10:17 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 19/04/2020 06:54, Uros Bizjak wrote:
> >> Can somebody of the x86 maintainers have a look at this patch, please?
> >>
> >> On 3/30/20 9:28 PM, Adhemerval Zanella via Libc-alpha wrote:
> >>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> >>> they should work on both float, double, and long double) while the
> >>> internal libc_fe* set either SSE (float, double, and float128) or
> >>> i387 (long double).
> >>>
> >>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> >>> however, will set either SEE or i387 exception depending of the
> >>> exception to raise.  This broke the internal assumption of float128
> >>> where only SSE operations will be used.
> >>>
> >>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> >>> SSE operations and sets libgcc to use it instead of its own
> >>> implementation.
> >>>
> >>> And I think we should fix libgcc in a similar manner, since checking on
> >>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> >>> and x86_64 ABI also expectes float128 to use SSE registers [1]
> >>> (although it is not clear on how future implementation might implement
> >>> it).
> >>>
> >>> Checked on x86_64-linux-gnu.
> >
> > I don't think the new implementation is correct. Please consider
> > attached testcase that compares GCC implementation to the new
> > implementation. Specifically, PE, OF and UF exceptions do not work as
> > expected.
>
> Indeed my patch does not work correctly for underflow and overflow
> exceptions.  But your example also is not fully correct because
> glibc fetestexcept will return an union of both i387 and SSE
> exception, where we should test only for SSE in this specific case.

True, but this is what we want to do. Using stmxcsr and ldmxcsr wil
only set corresponding flag and won't trigger the exception in the
same way as using fnstenv/fldenv does. Please see example below.

> To correctly check if SSE exceptions flags your testcase should
> use something like:
>
>   int
>   feclearexcept_sse (int excepts)
>   {
>     unsigned int mxcsr;
>     excepts &= FE_ALL_EXCEPT;
>     __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
>     mxcsr &= ~excepts;
>     __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
>     return 0;
>   }
>
>   int
>   fetestexcept_sse (int excepts)
>   {
>     unsigned int mxscr;
>     __asm__ ("stmxcsr %0" : "=m" (*&mxscr));
>     return (mxscr) & excepts & FE_ALL_EXCEPT;
>   }

This approach won't trigger the exception:

--cut here--
#define _GNU_SOURCE
#include <fenv.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>

#include <x86intrin.h>

void
__attribute__((noinline))
__overflow_ex (void)
{
  unsigned int mxcsr = _mm_getcsr ();
  mxcsr |= _MM_EXCEPT_OVERFLOW;
  _mm_setcsr (mxcsr);
}

void handler (int i)
{
  exit (0);
}

int
main ()
{
  struct sigaction s;
  sigemptyset (&s.sa_mask);
  s.sa_handler = handler;
  s.sa_flags = 0;
  sigaction (SIGFPE, &s, NULL);

  feenableexcept (FE_OVERFLOW);

  __overflow_ex ();

  abort ();
}
--cut here--

>
> I thought I could force overflow and underflow with only math operations,
> but it seems it no easy without also generating inexact ones. We should
> use instead:
>
>   if (_fex & FP_EX_OVERFLOW)
>     {
>       unsigned int mxcsr;
>       __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
>       mxcsr |= FP_EX_OVERFLOW & FE_ALL_EXCEPT;
>       __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
>     }
>   if (_fex & FP_EX_UNDERFLOW)
>     {
>       unsigned int mxcsr;
>       __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
>       mxcsr |= FP_EX_UNDERFLOW & FE_ALL_EXCEPT;
>       __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
>     }
>
> With these change and checking only SSE exceptions I see:
>
> $ gcc -Wall -m64 exe.c -o exe -DNEW -O0 -g && ./exe
>  PE  .  .  .  .
>   . UE  .  .  .
>   .  . OF  .  .
>   .  .  . ZE  .
>   .  .  .  .  .
>   .  .  .  . IE
>
> I will fix and add a testcase as well.
>
> >
> > For the compiled testcase, GCC version returns:
> >
> > $ ./a.out
> >  PE  .  .  .  .
> >   . UE  .  .  .
> >   .  . OF  .  .
> >   .  .  . ZE  .
> >   .  .  .  .  .
> >   .  .  .  . IE
> >
> > where the new implementation (compile with -DNEW) returns:
> >
> > $ ./a.out
> >   .  .  .  .  .
> >   .  .  .  .  .
> >  PE  . OF  .  .
> >   .  .  . ZE  .
> >   .  .  .  .  .
> >   .  .  .  . IE
> >
> > For reference, with -m32 -DNEW (so, x87 math) , the new implementation return:
>
> Yes, this implementation does not handle i686/x87 and it is compiled only
> for x86_64. And assuming that i686 _Float128 ABI follows x86_64, we should
> fix for i686 as well.
>
> >
> > $ ./a.out
> >   .  .  .  .  .
> >   .  .  .  .  .
> >   .  .  .  .  .
> >   .  .  . ZE  .
> >   .  .  .  .  .
> >   .  .  .  . IE
> >
> > which is again different from GCC version.
>
> But the question is whether _Float128 operation should generate x87 exceptions.

I see no problem here. __sfp_handle_exceptions is used to generate
exceptions, i.e. fire real signal to a signal handler. Whether the
source of a signal is x87 or SSE hardware does not really matter. Both
status words have to be checked with:

--cut here--
  __asm__ __volatile__ ("fnstsw\t%0" : "=am" (cw));
  excepts = cw;

  if (has_sse())
    {
      unsigned int cw_sse;

      __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
      excepts |= cw_sse;
    }
--cut here--

Uros.

> My understanding is it shouldn't for x86_64, however I am not sure for i686
> (since I am not sure how extensible __sfp_handle_exceptions is used on i686
> target and in which routines).
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-19 20:48   ` Uros Bizjak
@ 2020-04-20 11:09     ` Adhemerval Zanella
  2020-04-20 21:03       ` Joseph Myers
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2020-04-20 11:09 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: libc-alpha, stli, Florian Weimer, H. J. Lu



On 19/04/2020 17:48, Uros Bizjak wrote:
> On Sun, Apr 19, 2020 at 10:17 PM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 19/04/2020 06:54, Uros Bizjak wrote:
>>>> Can somebody of the x86 maintainers have a look at this patch, please?
>>>>
>>>> On 3/30/20 9:28 PM, Adhemerval Zanella via Libc-alpha wrote:
>>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
>>>>> they should work on both float, double, and long double) while the
>>>>> internal libc_fe* set either SSE (float, double, and float128) or
>>>>> i387 (long double).
>>>>>
>>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
>>>>> however, will set either SEE or i387 exception depending of the
>>>>> exception to raise.  This broke the internal assumption of float128
>>>>> where only SSE operations will be used.
>>>>>
>>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
>>>>> SSE operations and sets libgcc to use it instead of its own
>>>>> implementation.
>>>>>
>>>>> And I think we should fix libgcc in a similar manner, since checking on
>>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
>>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
>>>>> (although it is not clear on how future implementation might implement
>>>>> it).
>>>>>
>>>>> Checked on x86_64-linux-gnu.
>>>
>>> I don't think the new implementation is correct. Please consider
>>> attached testcase that compares GCC implementation to the new
>>> implementation. Specifically, PE, OF and UF exceptions do not work as
>>> expected.
>>
>> Indeed my patch does not work correctly for underflow and overflow
>> exceptions.  But your example also is not fully correct because
>> glibc fetestexcept will return an union of both i387 and SSE
>> exception, where we should test only for SSE in this specific case.
> 
> True, but this is what we want to do. Using stmxcsr and ldmxcsr wil
> only set corresponding flag and won't trigger the exception in the
> same way as using fnstenv/fldenv does. Please see example below.

Sigh... indeed there is no easy way to trigger an underflow/overflow
without also trigger a invalid exception on SSE.  

> 
>> To correctly check if SSE exceptions flags your testcase should
>> use something like:
>>
>>   int
>>   feclearexcept_sse (int excepts)
>>   {
>>     unsigned int mxcsr;
>>     excepts &= FE_ALL_EXCEPT;
>>     __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
>>     mxcsr &= ~excepts;
>>     __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
>>     return 0;
>>   }
>>
>>   int
>>   fetestexcept_sse (int excepts)
>>   {
>>     unsigned int mxscr;
>>     __asm__ ("stmxcsr %0" : "=m" (*&mxscr));
>>     return (mxscr) & excepts & FE_ALL_EXCEPT;
>>   }
> 
> This approach won't trigger the exception:
> 
> --cut here--
> #define _GNU_SOURCE
> #include <fenv.h>
> #include <signal.h>
> #include <stddef.h>
> #include <stdlib.h>
> 
> #include <x86intrin.h>
> 
> void
> __attribute__((noinline))
> __overflow_ex (void)
> {
>   unsigned int mxcsr = _mm_getcsr ();
>   mxcsr |= _MM_EXCEPT_OVERFLOW;
>   _mm_setcsr (mxcsr);
> }
> 
> void handler (int i)
> {
>   exit (0);
> }
> 
> int
> main ()
> {
>   struct sigaction s;
>   sigemptyset (&s.sa_mask);
>   s.sa_handler = handler;
>   s.sa_flags = 0;
>   sigaction (SIGFPE, &s, NULL);
> 
>   feenableexcept (FE_OVERFLOW);
> 
>   __overflow_ex ();
> 
>   abort ();
> }
> --cut here--
> 
>>
>> I thought I could force overflow and underflow with only math operations,
>> but it seems it no easy without also generating inexact ones. We should
>> use instead:
>>
>>   if (_fex & FP_EX_OVERFLOW)
>>     {
>>       unsigned int mxcsr;
>>       __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
>>       mxcsr |= FP_EX_OVERFLOW & FE_ALL_EXCEPT;
>>       __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
>>     }
>>   if (_fex & FP_EX_UNDERFLOW)
>>     {
>>       unsigned int mxcsr;
>>       __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
>>       mxcsr |= FP_EX_UNDERFLOW & FE_ALL_EXCEPT;
>>       __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
>>     }
>>
>> With these change and checking only SSE exceptions I see:
>>
>> $ gcc -Wall -m64 exe.c -o exe -DNEW -O0 -g && ./exe
>>  PE  .  .  .  .
>>   . UE  .  .  .
>>   .  . OF  .  .
>>   .  .  . ZE  .
>>   .  .  .  .  .
>>   .  .  .  . IE
>>
>> I will fix and add a testcase as well.
>>
>>>
>>> For the compiled testcase, GCC version returns:
>>>
>>> $ ./a.out
>>>  PE  .  .  .  .
>>>   . UE  .  .  .
>>>   .  . OF  .  .
>>>   .  .  . ZE  .
>>>   .  .  .  .  .
>>>   .  .  .  . IE
>>>
>>> where the new implementation (compile with -DNEW) returns:
>>>
>>> $ ./a.out
>>>   .  .  .  .  .
>>>   .  .  .  .  .
>>>  PE  . OF  .  .
>>>   .  .  . ZE  .
>>>   .  .  .  .  .
>>>   .  .  .  . IE
>>>
>>> For reference, with -m32 -DNEW (so, x87 math) , the new implementation return:
>>
>> Yes, this implementation does not handle i686/x87 and it is compiled only
>> for x86_64. And assuming that i686 _Float128 ABI follows x86_64, we should
>> fix for i686 as well.
>>
>>>
>>> $ ./a.out
>>>   .  .  .  .  .
>>>   .  .  .  .  .
>>>   .  .  .  .  .
>>>   .  .  . ZE  .
>>>   .  .  .  .  .
>>>   .  .  .  . IE
>>>
>>> which is again different from GCC version.
>>
>> But the question is whether _Float128 operation should generate x87 exceptions.
> 
> I see no problem here. __sfp_handle_exceptions is used to generate
> exceptions, i.e. fire real signal to a signal handler. Whether the
> source of a signal is x87 or SSE hardware does not really matter. Both
> status words have to be checked with:

Ok, I will revert the patch on glibc and change our internal assumptions
on _Float128 handling to expect both x87 and SSE exceptions.

I still think raising x87 is not fully correct for _Float128 because it
might not be fully compatible with a possible hardware implementation
that most likely will most likely use mxcsr or an extension. But I don't
see a better alternative as well.

> 
> --cut here--
>   __asm__ __volatile__ ("fnstsw\t%0" : "=am" (cw));
>   excepts = cw;
> 
>   if (has_sse())
>     {
>       unsigned int cw_sse;
> 
>       __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
>       excepts |= cw_sse;
>     }
> --cut here--
> 
> Uros.
> 
>> My understanding is it shouldn't for x86_64, however I am not sure for i686
>> (since I am not sure how extensible __sfp_handle_exceptions is used on i686
>> target and in which routines).
>>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-20 11:09     ` Adhemerval Zanella
@ 2020-04-20 21:03       ` Joseph Myers
  0 siblings, 0 replies; 18+ messages in thread
From: Joseph Myers @ 2020-04-20 21:03 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Uros Bizjak, stli, libc-alpha

On Mon, 20 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:

> Sigh... indeed there is no easy way to trigger an underflow/overflow
> without also trigger a invalid exception on SSE.  

For the case of exact underflow, you can do an operation that produces an 
exact subnormal result, such as FLT_TRUE_MIN + FLT_TRUE_MIN.  (For x87 
you'd want a long double operation such as LDBL_TRUE_MIN + LDBL_TRUE_MIN.  
And if inexact is to be raised at the same time, you should do an inexact 
underflowing operation instead.)  This code is only used with exception 
combinations that can occur from floating-point operations, so the case of 
exact overflow cannot occur; overflow will always occur together with 
inexact.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-17 14:36                   ` Adhemerval Zanella
@ 2020-04-17 14:38                     ` H.J. Lu
  0 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-04-17 14:38 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha

On Fri, Apr 17, 2020 at 7:37 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 17/04/2020 10:46, H.J. Lu wrote:
> > On Fri, Apr 17, 2020 at 5:10 AM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >>
> >>
> >> On 16/04/2020 11:46, H.J. Lu wrote:
> >>> On Thu, Apr 16, 2020 at 7:38 AM Adhemerval Zanella
> >>> <adhemerval.zanella@linaro.org> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 16/04/2020 11:24, H.J. Lu wrote:
> >>>>> On Thu, Apr 16, 2020 at 7:17 AM Adhemerval Zanella
> >>>>> <adhemerval.zanella@linaro.org> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 16/04/2020 11:12, H.J. Lu wrote:
> >>>>>>> On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
> >>>>>>> <libc-alpha@sourceware.org> wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 16/04/2020 07:14, Florian Weimer wrote:
> >>>>>>>>> * Adhemerval Zanella via Libc-alpha:
> >>>>>>>>>
> >>>>>>>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> >>>>>>>>>> they should work on both float, double, and long double) while the
> >>>>>>>>>> internal libc_fe* set either SSE (float, double, and float128) or
> >>>>>>>>>> i387 (long double).
> >>>>>>>>>>
> >>>>>>>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> >>>>>>>>>> however, will set either SEE or i387 exception depending of the
> >>>>>>>>>> exception to raise.  This broke the internal assumption of float128
> >>>>>>>>>> where only SSE operations will be used.
> >>>>>>>>>>
> >>>>>>>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> >>>>>>>>>> SSE operations and sets libgcc to use it instead of its own
> >>>>>>>>>> implementation.
> >>>>>>>>>>
> >>>>>>>>>> And I think we should fix libgcc in a similar manner, since checking on
> >>>>>>>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> >>>>>>>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
> >>>>>>>>>> (although it is not clear on how future implementation might implement
> >>>>>>>>>> it).
> >>>>>>>>>
> >>>>>>>>> Is this another bug similar to bug 23253, fixed in commit
> >>>>>>>>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
> >>>>>>>>> rounding mode for tgamma on i386 [BZ #23253]")?
> >>>>>>>>>
> >>>>>>>>> Thanks,
> >>>>>>>>> Florian
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> I think this is slight different because _Float128 on x86_64 is
> >>>>>>>> not subject to -mfpmath switch (afaik).  The issue is libgcc
> >>>>>>>> generates i387 exceptions where the expectation is it should be
> >>>>>>>> only use SSE one.
> >>>>>>>
> >>>>>>> Should it be fixed in libgcc?
> >>>>>>
> >>>>>> I can send a patch to libgcc, but it would require backporting to
> >>>>>> all glibc support gcc to fix on all possible scenarios.  Should we
> >>>>>> only go to libgcc fix or make this fix independent of the gcc
> >>>>>> version?
> >>>>>
> >>>>> I think we should do both.
> >>>>>
> >>>>> Also
> >>>>>
> >>>>> # Variables for libmvec tests.
> >>>>>  ifeq ($(subdir),math)
> >>>>> +libm-routines += sfp-exceptions
> >>>>> +LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> >>>>> +
> >>>>>
> >>>>> I think you should move the "# Variables for libmvec tests." line
> >>>>> before "ifeq ($(build-mathvec),yes)".
> >>>>
> >>>> Ack.
> >>>>
> >>>>>
> >>>>> Why is
> >>>>>
> >>>>> LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> >>>>>
> >>>>> needed when sfp-exceptions.o is compiled into libm?
> >>>>>
> >>>>
> >>>> To force libgcc objects use the glibc provided one instead of its
> >>>> own version.
> >>>
> >>> [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc_s.so.1 | grep sfp_handle_exceptions
> >>>    254: 0000000000006bd0   143 FUNC    LOCAL  DEFAULT   14
> >>> __sfp_handle_exceptions
> >>> [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc.a | grep sfp_handle_exceptions
> >>>     19: 0000000000000000   143 FUNC    GLOBAL HIDDEN     1
> >>> __sfp_handle_exceptions
> >>>     18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND
> >>> __sfp_handle_exceptions
> >>>
> >>> Your patch has no impact on libgcc_s.so.1.
> >>>
> >>> BTW, can you include a testcase for the patch?
> >>>
> >>
> >> It does not affect dynamic linking with libgcc_s, but rather how to link
> >> against libgcc.a when building libm.so itself. Instead of libgcc.a use
> >> its own __sfp_handle_exceptions on _Float128 soft-float routines, ld will
> >> make internal calls route to the provided wrapped implementation.
> >>
> >> For instance:
> >>
> >> $ ./debugglibc.sh -- math/test-float128-exp
> >> [...]
> >> (gdb) b __sfp_handle_exceptions
> >> Breakpoint 2 at 0x4076e0: __sfp_handle_exceptions. (3 locations)
> >> (gdb) c
> >> Continuing.
> >> testing _Float128 (without inline functions)
> >>
> >> Breakpoint 2, __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
> >> 27        if (_fex & FP_EX_INVALID)
> >> (gdb) bt
> >> #0  __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
> >> #1  0x00007ffff7f2b178 in __unordtf2 (a=<optimized out>, b=1.18973149535723176508575932662800702e+4932) at /opt/cross/src/gcc/libgcc/soft-fp/unordtf2.c:45
> >> #2  0x00007ffff7ee8191 in __ldexpf128 (exp=-16494, value=6.47517511943802511092443895822764655e-4966) at ./s_ldexp_template.c:25
> >> #3  __ldexpf128 (value=value@entry=1, exp=exp@entry=-16494) at ./s_ldexp_template.c:21
> >> #4  0x0000000000401f02 in ulp (value=<optimized out>, value@entry=0) at ./libm-test-support.c:597
> >> #5  0x0000000000402061 in check_ulp () at ./libm-test-support.c:1078
> >> #6  0x0000000000403ce6 in libm_test_init (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-support.c:1184
> >> #7  0x0000000000401299 in main (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-driver.c:1070
> >> #8  0x00007ffff7cedcdb in __libc_start_main (main=0x401290 <main>, argc=1, argv=0x7fffffffd300, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd2f8)
> >>     at ../csu/libc-start.c:308
> >> #9  0x00000000004012da in _start () at ../sysdeps/x86_64/start.S:120
> >>
> >> And the failures from using libgcc __sfp_exceptions were found when
> >> trying to use the internal libc optimize fenv functions [1]. I have
> >> pushed Stefan patchset on top this patch [2] on a local branch, you
> >> can check that by removing the --wrap build parameter the libgcc
> >> one used and it shows the very issues noted by Stefan.
> >>
> >> [1] https://sourceware.org/pipermail/libc-alpha/2020-March/112123.html
> >> [2] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/sfp-exceptions
> >
> > I applied this patch on top of azanella/sfp-exceptions branch.   There is
> > no regression and sysdeps/x86/fpu/sfp-exceptions.c is included in libm.so.
> > Did I miss something?
>
> Indeed the wrap trick does not seem to be required. I have removed it.
> Is it ok with this change?

Yes, please.  Thanks.

> >
> > BTW, libgcc bug should be fixed in GCC 10 if possible.
> >
>
> I will open a bug report and prepare a patch.

I appreciate it.

-- 
H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-17 13:46                 ` H.J. Lu
@ 2020-04-17 14:36                   ` Adhemerval Zanella
  2020-04-17 14:38                     ` H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2020-04-17 14:36 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 17/04/2020 10:46, H.J. Lu wrote:
> On Fri, Apr 17, 2020 at 5:10 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 16/04/2020 11:46, H.J. Lu wrote:
>>> On Thu, Apr 16, 2020 at 7:38 AM Adhemerval Zanella
>>> <adhemerval.zanella@linaro.org> wrote:
>>>>
>>>>
>>>>
>>>> On 16/04/2020 11:24, H.J. Lu wrote:
>>>>> On Thu, Apr 16, 2020 at 7:17 AM Adhemerval Zanella
>>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 16/04/2020 11:12, H.J. Lu wrote:
>>>>>>> On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
>>>>>>> <libc-alpha@sourceware.org> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On 16/04/2020 07:14, Florian Weimer wrote:
>>>>>>>>> * Adhemerval Zanella via Libc-alpha:
>>>>>>>>>
>>>>>>>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
>>>>>>>>>> they should work on both float, double, and long double) while the
>>>>>>>>>> internal libc_fe* set either SSE (float, double, and float128) or
>>>>>>>>>> i387 (long double).
>>>>>>>>>>
>>>>>>>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
>>>>>>>>>> however, will set either SEE or i387 exception depending of the
>>>>>>>>>> exception to raise.  This broke the internal assumption of float128
>>>>>>>>>> where only SSE operations will be used.
>>>>>>>>>>
>>>>>>>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
>>>>>>>>>> SSE operations and sets libgcc to use it instead of its own
>>>>>>>>>> implementation.
>>>>>>>>>>
>>>>>>>>>> And I think we should fix libgcc in a similar manner, since checking on
>>>>>>>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
>>>>>>>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
>>>>>>>>>> (although it is not clear on how future implementation might implement
>>>>>>>>>> it).
>>>>>>>>>
>>>>>>>>> Is this another bug similar to bug 23253, fixed in commit
>>>>>>>>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
>>>>>>>>> rounding mode for tgamma on i386 [BZ #23253]")?
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Florian
>>>>>>>>>
>>>>>>>>
>>>>>>>> I think this is slight different because _Float128 on x86_64 is
>>>>>>>> not subject to -mfpmath switch (afaik).  The issue is libgcc
>>>>>>>> generates i387 exceptions where the expectation is it should be
>>>>>>>> only use SSE one.
>>>>>>>
>>>>>>> Should it be fixed in libgcc?
>>>>>>
>>>>>> I can send a patch to libgcc, but it would require backporting to
>>>>>> all glibc support gcc to fix on all possible scenarios.  Should we
>>>>>> only go to libgcc fix or make this fix independent of the gcc
>>>>>> version?
>>>>>
>>>>> I think we should do both.
>>>>>
>>>>> Also
>>>>>
>>>>> # Variables for libmvec tests.
>>>>>  ifeq ($(subdir),math)
>>>>> +libm-routines += sfp-exceptions
>>>>> +LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
>>>>> +
>>>>>
>>>>> I think you should move the "# Variables for libmvec tests." line
>>>>> before "ifeq ($(build-mathvec),yes)".
>>>>
>>>> Ack.
>>>>
>>>>>
>>>>> Why is
>>>>>
>>>>> LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
>>>>>
>>>>> needed when sfp-exceptions.o is compiled into libm?
>>>>>
>>>>
>>>> To force libgcc objects use the glibc provided one instead of its
>>>> own version.
>>>
>>> [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc_s.so.1 | grep sfp_handle_exceptions
>>>    254: 0000000000006bd0   143 FUNC    LOCAL  DEFAULT   14
>>> __sfp_handle_exceptions
>>> [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc.a | grep sfp_handle_exceptions
>>>     19: 0000000000000000   143 FUNC    GLOBAL HIDDEN     1
>>> __sfp_handle_exceptions
>>>     18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND
>>> __sfp_handle_exceptions
>>>
>>> Your patch has no impact on libgcc_s.so.1.
>>>
>>> BTW, can you include a testcase for the patch?
>>>
>>
>> It does not affect dynamic linking with libgcc_s, but rather how to link
>> against libgcc.a when building libm.so itself. Instead of libgcc.a use
>> its own __sfp_handle_exceptions on _Float128 soft-float routines, ld will
>> make internal calls route to the provided wrapped implementation.
>>
>> For instance:
>>
>> $ ./debugglibc.sh -- math/test-float128-exp
>> [...]
>> (gdb) b __sfp_handle_exceptions
>> Breakpoint 2 at 0x4076e0: __sfp_handle_exceptions. (3 locations)
>> (gdb) c
>> Continuing.
>> testing _Float128 (without inline functions)
>>
>> Breakpoint 2, __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
>> 27        if (_fex & FP_EX_INVALID)
>> (gdb) bt
>> #0  __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
>> #1  0x00007ffff7f2b178 in __unordtf2 (a=<optimized out>, b=1.18973149535723176508575932662800702e+4932) at /opt/cross/src/gcc/libgcc/soft-fp/unordtf2.c:45
>> #2  0x00007ffff7ee8191 in __ldexpf128 (exp=-16494, value=6.47517511943802511092443895822764655e-4966) at ./s_ldexp_template.c:25
>> #3  __ldexpf128 (value=value@entry=1, exp=exp@entry=-16494) at ./s_ldexp_template.c:21
>> #4  0x0000000000401f02 in ulp (value=<optimized out>, value@entry=0) at ./libm-test-support.c:597
>> #5  0x0000000000402061 in check_ulp () at ./libm-test-support.c:1078
>> #6  0x0000000000403ce6 in libm_test_init (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-support.c:1184
>> #7  0x0000000000401299 in main (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-driver.c:1070
>> #8  0x00007ffff7cedcdb in __libc_start_main (main=0x401290 <main>, argc=1, argv=0x7fffffffd300, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd2f8)
>>     at ../csu/libc-start.c:308
>> #9  0x00000000004012da in _start () at ../sysdeps/x86_64/start.S:120
>>
>> And the failures from using libgcc __sfp_exceptions were found when
>> trying to use the internal libc optimize fenv functions [1]. I have
>> pushed Stefan patchset on top this patch [2] on a local branch, you
>> can check that by removing the --wrap build parameter the libgcc
>> one used and it shows the very issues noted by Stefan.
>>
>> [1] https://sourceware.org/pipermail/libc-alpha/2020-March/112123.html
>> [2] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/sfp-exceptions
> 
> I applied this patch on top of azanella/sfp-exceptions branch.   There is
> no regression and sysdeps/x86/fpu/sfp-exceptions.c is included in libm.so.
> Did I miss something?

Indeed the wrap trick does not seem to be required. I have removed it.
Is it ok with this change?

> 
> BTW, libgcc bug should be fixed in GCC 10 if possible.
> 

I will open a bug report and prepare a patch.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-17 12:10               ` Adhemerval Zanella
@ 2020-04-17 13:46                 ` H.J. Lu
  2020-04-17 14:36                   ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2020-04-17 13:46 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha

[-- Attachment #1: Type: text/plain, Size: 6376 bytes --]

On Fri, Apr 17, 2020 at 5:10 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 16/04/2020 11:46, H.J. Lu wrote:
> > On Thu, Apr 16, 2020 at 7:38 AM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >>
> >>
> >> On 16/04/2020 11:24, H.J. Lu wrote:
> >>> On Thu, Apr 16, 2020 at 7:17 AM Adhemerval Zanella
> >>> <adhemerval.zanella@linaro.org> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 16/04/2020 11:12, H.J. Lu wrote:
> >>>>> On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
> >>>>> <libc-alpha@sourceware.org> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 16/04/2020 07:14, Florian Weimer wrote:
> >>>>>>> * Adhemerval Zanella via Libc-alpha:
> >>>>>>>
> >>>>>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> >>>>>>>> they should work on both float, double, and long double) while the
> >>>>>>>> internal libc_fe* set either SSE (float, double, and float128) or
> >>>>>>>> i387 (long double).
> >>>>>>>>
> >>>>>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> >>>>>>>> however, will set either SEE or i387 exception depending of the
> >>>>>>>> exception to raise.  This broke the internal assumption of float128
> >>>>>>>> where only SSE operations will be used.
> >>>>>>>>
> >>>>>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> >>>>>>>> SSE operations and sets libgcc to use it instead of its own
> >>>>>>>> implementation.
> >>>>>>>>
> >>>>>>>> And I think we should fix libgcc in a similar manner, since checking on
> >>>>>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> >>>>>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
> >>>>>>>> (although it is not clear on how future implementation might implement
> >>>>>>>> it).
> >>>>>>>
> >>>>>>> Is this another bug similar to bug 23253, fixed in commit
> >>>>>>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
> >>>>>>> rounding mode for tgamma on i386 [BZ #23253]")?
> >>>>>>>
> >>>>>>> Thanks,
> >>>>>>> Florian
> >>>>>>>
> >>>>>>
> >>>>>> I think this is slight different because _Float128 on x86_64 is
> >>>>>> not subject to -mfpmath switch (afaik).  The issue is libgcc
> >>>>>> generates i387 exceptions where the expectation is it should be
> >>>>>> only use SSE one.
> >>>>>
> >>>>> Should it be fixed in libgcc?
> >>>>
> >>>> I can send a patch to libgcc, but it would require backporting to
> >>>> all glibc support gcc to fix on all possible scenarios.  Should we
> >>>> only go to libgcc fix or make this fix independent of the gcc
> >>>> version?
> >>>
> >>> I think we should do both.
> >>>
> >>> Also
> >>>
> >>> # Variables for libmvec tests.
> >>>  ifeq ($(subdir),math)
> >>> +libm-routines += sfp-exceptions
> >>> +LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> >>> +
> >>>
> >>> I think you should move the "# Variables for libmvec tests." line
> >>> before "ifeq ($(build-mathvec),yes)".
> >>
> >> Ack.
> >>
> >>>
> >>> Why is
> >>>
> >>> LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> >>>
> >>> needed when sfp-exceptions.o is compiled into libm?
> >>>
> >>
> >> To force libgcc objects use the glibc provided one instead of its
> >> own version.
> >
> > [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc_s.so.1 | grep sfp_handle_exceptions
> >    254: 0000000000006bd0   143 FUNC    LOCAL  DEFAULT   14
> > __sfp_handle_exceptions
> > [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc.a | grep sfp_handle_exceptions
> >     19: 0000000000000000   143 FUNC    GLOBAL HIDDEN     1
> > __sfp_handle_exceptions
> >     18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND
> > __sfp_handle_exceptions
> >
> > Your patch has no impact on libgcc_s.so.1.
> >
> > BTW, can you include a testcase for the patch?
> >
>
> It does not affect dynamic linking with libgcc_s, but rather how to link
> against libgcc.a when building libm.so itself. Instead of libgcc.a use
> its own __sfp_handle_exceptions on _Float128 soft-float routines, ld will
> make internal calls route to the provided wrapped implementation.
>
> For instance:
>
> $ ./debugglibc.sh -- math/test-float128-exp
> [...]
> (gdb) b __sfp_handle_exceptions
> Breakpoint 2 at 0x4076e0: __sfp_handle_exceptions. (3 locations)
> (gdb) c
> Continuing.
> testing _Float128 (without inline functions)
>
> Breakpoint 2, __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
> 27        if (_fex & FP_EX_INVALID)
> (gdb) bt
> #0  __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
> #1  0x00007ffff7f2b178 in __unordtf2 (a=<optimized out>, b=1.18973149535723176508575932662800702e+4932) at /opt/cross/src/gcc/libgcc/soft-fp/unordtf2.c:45
> #2  0x00007ffff7ee8191 in __ldexpf128 (exp=-16494, value=6.47517511943802511092443895822764655e-4966) at ./s_ldexp_template.c:25
> #3  __ldexpf128 (value=value@entry=1, exp=exp@entry=-16494) at ./s_ldexp_template.c:21
> #4  0x0000000000401f02 in ulp (value=<optimized out>, value@entry=0) at ./libm-test-support.c:597
> #5  0x0000000000402061 in check_ulp () at ./libm-test-support.c:1078
> #6  0x0000000000403ce6 in libm_test_init (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-support.c:1184
> #7  0x0000000000401299 in main (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-driver.c:1070
> #8  0x00007ffff7cedcdb in __libc_start_main (main=0x401290 <main>, argc=1, argv=0x7fffffffd300, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd2f8)
>     at ../csu/libc-start.c:308
> #9  0x00000000004012da in _start () at ../sysdeps/x86_64/start.S:120
>
> And the failures from using libgcc __sfp_exceptions were found when
> trying to use the internal libc optimize fenv functions [1]. I have
> pushed Stefan patchset on top this patch [2] on a local branch, you
> can check that by removing the --wrap build parameter the libgcc
> one used and it shows the very issues noted by Stefan.
>
> [1] https://sourceware.org/pipermail/libc-alpha/2020-March/112123.html
> [2] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/sfp-exceptions

I applied this patch on top of azanella/sfp-exceptions branch.   There is
no regression and sysdeps/x86/fpu/sfp-exceptions.c is included in libm.so.
Did I miss something?

BTW, libgcc bug should be fixed in GCC 10 if possible.

-- 
H.J.

[-- Attachment #2: 0001-Remove-__wrap___sfp_handle_exceptions.patch --]
[-- Type: text/x-patch, Size: 1227 bytes --]

From ba323ff5a60679fc55112311c8d19515abdc6eeb Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 17 Apr 2020 06:43:48 -0700
Subject: [PATCH] Remove __wrap___sfp_handle_exceptions

---
 sysdeps/x86/fpu/sfp-exceptions.c | 4 ----
 sysdeps/x86_64/fpu/Makefile      | 1 -
 2 files changed, 5 deletions(-)

diff --git a/sysdeps/x86/fpu/sfp-exceptions.c b/sysdeps/x86/fpu/sfp-exceptions.c
index a60a5f9376..74ce0716e2 100644
--- a/sysdeps/x86/fpu/sfp-exceptions.c
+++ b/sysdeps/x86/fpu/sfp-exceptions.c
@@ -55,7 +55,3 @@ __sfp_handle_exceptions (int _fex)
       math_force_eval (f / g);
     }
 }
-/* The build uses a linker wrap option to force libgcc use this
-   implementation (--wrap) and it requires prepend the symbol name with
-   '__wrap_'.  */
-strong_alias (__sfp_handle_exceptions, __wrap___sfp_handle_exceptions)
diff --git a/sysdeps/x86_64/fpu/Makefile b/sysdeps/x86_64/fpu/Makefile
index aa30ba7b07..a95e3f74f4 100644
--- a/sysdeps/x86_64/fpu/Makefile
+++ b/sysdeps/x86_64/fpu/Makefile
@@ -25,7 +25,6 @@ endif
 
 ifeq ($(subdir),math)
 libm-routines += sfp-exceptions
-LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
 
 # Variables for libmvec tests.
 ifeq ($(build-mathvec),yes)
-- 
2.25.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-16 14:46             ` H.J. Lu
@ 2020-04-17 12:10               ` Adhemerval Zanella
  2020-04-17 13:46                 ` H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2020-04-17 12:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 16/04/2020 11:46, H.J. Lu wrote:
> On Thu, Apr 16, 2020 at 7:38 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 16/04/2020 11:24, H.J. Lu wrote:
>>> On Thu, Apr 16, 2020 at 7:17 AM Adhemerval Zanella
>>> <adhemerval.zanella@linaro.org> wrote:
>>>>
>>>>
>>>>
>>>> On 16/04/2020 11:12, H.J. Lu wrote:
>>>>> On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
>>>>> <libc-alpha@sourceware.org> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 16/04/2020 07:14, Florian Weimer wrote:
>>>>>>> * Adhemerval Zanella via Libc-alpha:
>>>>>>>
>>>>>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
>>>>>>>> they should work on both float, double, and long double) while the
>>>>>>>> internal libc_fe* set either SSE (float, double, and float128) or
>>>>>>>> i387 (long double).
>>>>>>>>
>>>>>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
>>>>>>>> however, will set either SEE or i387 exception depending of the
>>>>>>>> exception to raise.  This broke the internal assumption of float128
>>>>>>>> where only SSE operations will be used.
>>>>>>>>
>>>>>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
>>>>>>>> SSE operations and sets libgcc to use it instead of its own
>>>>>>>> implementation.
>>>>>>>>
>>>>>>>> And I think we should fix libgcc in a similar manner, since checking on
>>>>>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
>>>>>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
>>>>>>>> (although it is not clear on how future implementation might implement
>>>>>>>> it).
>>>>>>>
>>>>>>> Is this another bug similar to bug 23253, fixed in commit
>>>>>>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
>>>>>>> rounding mode for tgamma on i386 [BZ #23253]")?
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Florian
>>>>>>>
>>>>>>
>>>>>> I think this is slight different because _Float128 on x86_64 is
>>>>>> not subject to -mfpmath switch (afaik).  The issue is libgcc
>>>>>> generates i387 exceptions where the expectation is it should be
>>>>>> only use SSE one.
>>>>>
>>>>> Should it be fixed in libgcc?
>>>>
>>>> I can send a patch to libgcc, but it would require backporting to
>>>> all glibc support gcc to fix on all possible scenarios.  Should we
>>>> only go to libgcc fix or make this fix independent of the gcc
>>>> version?
>>>
>>> I think we should do both.
>>>
>>> Also
>>>
>>> # Variables for libmvec tests.
>>>  ifeq ($(subdir),math)
>>> +libm-routines += sfp-exceptions
>>> +LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
>>> +
>>>
>>> I think you should move the "# Variables for libmvec tests." line
>>> before "ifeq ($(build-mathvec),yes)".
>>
>> Ack.
>>
>>>
>>> Why is
>>>
>>> LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
>>>
>>> needed when sfp-exceptions.o is compiled into libm?
>>>
>>
>> To force libgcc objects use the glibc provided one instead of its
>> own version.
> 
> [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc_s.so.1 | grep sfp_handle_exceptions
>    254: 0000000000006bd0   143 FUNC    LOCAL  DEFAULT   14
> __sfp_handle_exceptions
> [hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc.a | grep sfp_handle_exceptions
>     19: 0000000000000000   143 FUNC    GLOBAL HIDDEN     1
> __sfp_handle_exceptions
>     18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND
> __sfp_handle_exceptions
> 
> Your patch has no impact on libgcc_s.so.1.
> 
> BTW, can you include a testcase for the patch?
> 

It does not affect dynamic linking with libgcc_s, but rather how to link
against libgcc.a when building libm.so itself. Instead of libgcc.a use
its own __sfp_handle_exceptions on _Float128 soft-float routines, ld will
make internal calls route to the provided wrapped implementation. 

For instance:

$ ./debugglibc.sh -- math/test-float128-exp
[...]
(gdb) b __sfp_handle_exceptions
Breakpoint 2 at 0x4076e0: __sfp_handle_exceptions. (3 locations)
(gdb) c
Continuing.
testing _Float128 (without inline functions)

Breakpoint 2, __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
27        if (_fex & FP_EX_INVALID)
(gdb) bt
#0  __sfp_handle_exceptions (_fex=2) at ../sysdeps/x86/fpu/sfp-exceptions.c:27
#1  0x00007ffff7f2b178 in __unordtf2 (a=<optimized out>, b=1.18973149535723176508575932662800702e+4932) at /opt/cross/src/gcc/libgcc/soft-fp/unordtf2.c:45
#2  0x00007ffff7ee8191 in __ldexpf128 (exp=-16494, value=6.47517511943802511092443895822764655e-4966) at ./s_ldexp_template.c:25
#3  __ldexpf128 (value=value@entry=1, exp=exp@entry=-16494) at ./s_ldexp_template.c:21
#4  0x0000000000401f02 in ulp (value=<optimized out>, value@entry=0) at ./libm-test-support.c:597
#5  0x0000000000402061 in check_ulp () at ./libm-test-support.c:1078
#6  0x0000000000403ce6 in libm_test_init (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-support.c:1184
#7  0x0000000000401299 in main (argc=argc@entry=1, argv=argv@entry=0x7fffffffd300) at ./libm-test-driver.c:1070
#8  0x00007ffff7cedcdb in __libc_start_main (main=0x401290 <main>, argc=1, argv=0x7fffffffd300, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd2f8)
    at ../csu/libc-start.c:308
#9  0x00000000004012da in _start () at ../sysdeps/x86_64/start.S:120

And the failures from using libgcc __sfp_exceptions were found when
trying to use the internal libc optimize fenv functions [1]. I have
pushed Stefan patchset on top this patch [2] on a local branch, you
can check that by removing the --wrap build parameter the libgcc
one used and it shows the very issues noted by Stefan.

[1] https://sourceware.org/pipermail/libc-alpha/2020-March/112123.html
[2] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/sfp-exceptions

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-16 14:38           ` Adhemerval Zanella
@ 2020-04-16 14:46             ` H.J. Lu
  2020-04-17 12:10               ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2020-04-16 14:46 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha

On Thu, Apr 16, 2020 at 7:38 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 16/04/2020 11:24, H.J. Lu wrote:
> > On Thu, Apr 16, 2020 at 7:17 AM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >>
> >>
> >> On 16/04/2020 11:12, H.J. Lu wrote:
> >>> On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
> >>> <libc-alpha@sourceware.org> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 16/04/2020 07:14, Florian Weimer wrote:
> >>>>> * Adhemerval Zanella via Libc-alpha:
> >>>>>
> >>>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> >>>>>> they should work on both float, double, and long double) while the
> >>>>>> internal libc_fe* set either SSE (float, double, and float128) or
> >>>>>> i387 (long double).
> >>>>>>
> >>>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> >>>>>> however, will set either SEE or i387 exception depending of the
> >>>>>> exception to raise.  This broke the internal assumption of float128
> >>>>>> where only SSE operations will be used.
> >>>>>>
> >>>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> >>>>>> SSE operations and sets libgcc to use it instead of its own
> >>>>>> implementation.
> >>>>>>
> >>>>>> And I think we should fix libgcc in a similar manner, since checking on
> >>>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> >>>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
> >>>>>> (although it is not clear on how future implementation might implement
> >>>>>> it).
> >>>>>
> >>>>> Is this another bug similar to bug 23253, fixed in commit
> >>>>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
> >>>>> rounding mode for tgamma on i386 [BZ #23253]")?
> >>>>>
> >>>>> Thanks,
> >>>>> Florian
> >>>>>
> >>>>
> >>>> I think this is slight different because _Float128 on x86_64 is
> >>>> not subject to -mfpmath switch (afaik).  The issue is libgcc
> >>>> generates i387 exceptions where the expectation is it should be
> >>>> only use SSE one.
> >>>
> >>> Should it be fixed in libgcc?
> >>
> >> I can send a patch to libgcc, but it would require backporting to
> >> all glibc support gcc to fix on all possible scenarios.  Should we
> >> only go to libgcc fix or make this fix independent of the gcc
> >> version?
> >
> > I think we should do both.
> >
> > Also
> >
> > # Variables for libmvec tests.
> >  ifeq ($(subdir),math)
> > +libm-routines += sfp-exceptions
> > +LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> > +
> >
> > I think you should move the "# Variables for libmvec tests." line
> > before "ifeq ($(build-mathvec),yes)".
>
> Ack.
>
> >
> > Why is
> >
> > LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> >
> > needed when sfp-exceptions.o is compiled into libm?
> >
>
> To force libgcc objects use the glibc provided one instead of its
> own version.

[hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc_s.so.1 | grep sfp_handle_exceptions
   254: 0000000000006bd0   143 FUNC    LOCAL  DEFAULT   14
__sfp_handle_exceptions
[hjl@gnu-cfl-2 gcc]$ readelf -sW  libgcc.a | grep sfp_handle_exceptions
    19: 0000000000000000   143 FUNC    GLOBAL HIDDEN     1
__sfp_handle_exceptions
    18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND
__sfp_handle_exceptions

Your patch has no impact on libgcc_s.so.1.

BTW, can you include a testcase for the patch?

-- 
H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-16 14:24         ` H.J. Lu
@ 2020-04-16 14:38           ` Adhemerval Zanella
  2020-04-16 14:46             ` H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2020-04-16 14:38 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 16/04/2020 11:24, H.J. Lu wrote:
> On Thu, Apr 16, 2020 at 7:17 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 16/04/2020 11:12, H.J. Lu wrote:
>>> On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
>>> <libc-alpha@sourceware.org> wrote:
>>>>
>>>>
>>>>
>>>> On 16/04/2020 07:14, Florian Weimer wrote:
>>>>> * Adhemerval Zanella via Libc-alpha:
>>>>>
>>>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
>>>>>> they should work on both float, double, and long double) while the
>>>>>> internal libc_fe* set either SSE (float, double, and float128) or
>>>>>> i387 (long double).
>>>>>>
>>>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
>>>>>> however, will set either SEE or i387 exception depending of the
>>>>>> exception to raise.  This broke the internal assumption of float128
>>>>>> where only SSE operations will be used.
>>>>>>
>>>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
>>>>>> SSE operations and sets libgcc to use it instead of its own
>>>>>> implementation.
>>>>>>
>>>>>> And I think we should fix libgcc in a similar manner, since checking on
>>>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
>>>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
>>>>>> (although it is not clear on how future implementation might implement
>>>>>> it).
>>>>>
>>>>> Is this another bug similar to bug 23253, fixed in commit
>>>>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
>>>>> rounding mode for tgamma on i386 [BZ #23253]")?
>>>>>
>>>>> Thanks,
>>>>> Florian
>>>>>
>>>>
>>>> I think this is slight different because _Float128 on x86_64 is
>>>> not subject to -mfpmath switch (afaik).  The issue is libgcc
>>>> generates i387 exceptions where the expectation is it should be
>>>> only use SSE one.
>>>
>>> Should it be fixed in libgcc?
>>
>> I can send a patch to libgcc, but it would require backporting to
>> all glibc support gcc to fix on all possible scenarios.  Should we
>> only go to libgcc fix or make this fix independent of the gcc
>> version?
> 
> I think we should do both.
> 
> Also
> 
> # Variables for libmvec tests.
>  ifeq ($(subdir),math)
> +libm-routines += sfp-exceptions
> +LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> +
> 
> I think you should move the "# Variables for libmvec tests." line
> before "ifeq ($(build-mathvec),yes)".

Ack.

> 
> Why is
> 
> LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> 
> needed when sfp-exceptions.o is compiled into libm?
> 

To force libgcc objects use the glibc provided one instead of its
own version.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-16 14:17       ` Adhemerval Zanella
@ 2020-04-16 14:24         ` H.J. Lu
  2020-04-16 14:38           ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2020-04-16 14:24 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha

On Thu, Apr 16, 2020 at 7:17 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 16/04/2020 11:12, H.J. Lu wrote:
> > On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
> > <libc-alpha@sourceware.org> wrote:
> >>
> >>
> >>
> >> On 16/04/2020 07:14, Florian Weimer wrote:
> >>> * Adhemerval Zanella via Libc-alpha:
> >>>
> >>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> >>>> they should work on both float, double, and long double) while the
> >>>> internal libc_fe* set either SSE (float, double, and float128) or
> >>>> i387 (long double).
> >>>>
> >>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> >>>> however, will set either SEE or i387 exception depending of the
> >>>> exception to raise.  This broke the internal assumption of float128
> >>>> where only SSE operations will be used.
> >>>>
> >>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> >>>> SSE operations and sets libgcc to use it instead of its own
> >>>> implementation.
> >>>>
> >>>> And I think we should fix libgcc in a similar manner, since checking on
> >>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> >>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
> >>>> (although it is not clear on how future implementation might implement
> >>>> it).
> >>>
> >>> Is this another bug similar to bug 23253, fixed in commit
> >>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
> >>> rounding mode for tgamma on i386 [BZ #23253]")?
> >>>
> >>> Thanks,
> >>> Florian
> >>>
> >>
> >> I think this is slight different because _Float128 on x86_64 is
> >> not subject to -mfpmath switch (afaik).  The issue is libgcc
> >> generates i387 exceptions where the expectation is it should be
> >> only use SSE one.
> >
> > Should it be fixed in libgcc?
>
> I can send a patch to libgcc, but it would require backporting to
> all glibc support gcc to fix on all possible scenarios.  Should we
> only go to libgcc fix or make this fix independent of the gcc
> version?

I think we should do both.

Also

# Variables for libmvec tests.
 ifeq ($(subdir),math)
+libm-routines += sfp-exceptions
+LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
+

I think you should move the "# Variables for libmvec tests." line
before "ifeq ($(build-mathvec),yes)".

Why is

LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions

needed when sfp-exceptions.o is compiled into libm?

-- 
H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-16 14:12     ` H.J. Lu
@ 2020-04-16 14:17       ` Adhemerval Zanella
  2020-04-16 14:24         ` H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2020-04-16 14:17 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 16/04/2020 11:12, H.J. Lu wrote:
> On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
> <libc-alpha@sourceware.org> wrote:
>>
>>
>>
>> On 16/04/2020 07:14, Florian Weimer wrote:
>>> * Adhemerval Zanella via Libc-alpha:
>>>
>>>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
>>>> they should work on both float, double, and long double) while the
>>>> internal libc_fe* set either SSE (float, double, and float128) or
>>>> i387 (long double).
>>>>
>>>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
>>>> however, will set either SEE or i387 exception depending of the
>>>> exception to raise.  This broke the internal assumption of float128
>>>> where only SSE operations will be used.
>>>>
>>>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
>>>> SSE operations and sets libgcc to use it instead of its own
>>>> implementation.
>>>>
>>>> And I think we should fix libgcc in a similar manner, since checking on
>>>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
>>>> and x86_64 ABI also expectes float128 to use SSE registers [1]
>>>> (although it is not clear on how future implementation might implement
>>>> it).
>>>
>>> Is this another bug similar to bug 23253, fixed in commit
>>> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
>>> rounding mode for tgamma on i386 [BZ #23253]")?
>>>
>>> Thanks,
>>> Florian
>>>
>>
>> I think this is slight different because _Float128 on x86_64 is
>> not subject to -mfpmath switch (afaik).  The issue is libgcc
>> generates i387 exceptions where the expectation is it should be
>> only use SSE one.
> 
> Should it be fixed in libgcc?

I can send a patch to libgcc, but it would require backporting to
all glibc support gcc to fix on all possible scenarios.  Should we
only go to libgcc fix or make this fix independent of the gcc
version?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-16 14:06   ` Adhemerval Zanella
@ 2020-04-16 14:12     ` H.J. Lu
  2020-04-16 14:17       ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2020-04-16 14:12 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Florian Weimer, Adhemerval Zanella via Libc-alpha

On Thu, Apr 16, 2020 at 7:06 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
>
>
> On 16/04/2020 07:14, Florian Weimer wrote:
> > * Adhemerval Zanella via Libc-alpha:
> >
> >> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> >> they should work on both float, double, and long double) while the
> >> internal libc_fe* set either SSE (float, double, and float128) or
> >> i387 (long double).
> >>
> >> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> >> however, will set either SEE or i387 exception depending of the
> >> exception to raise.  This broke the internal assumption of float128
> >> where only SSE operations will be used.
> >>
> >> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> >> SSE operations and sets libgcc to use it instead of its own
> >> implementation.
> >>
> >> And I think we should fix libgcc in a similar manner, since checking on
> >> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> >> and x86_64 ABI also expectes float128 to use SSE registers [1]
> >> (although it is not clear on how future implementation might implement
> >> it).
> >
> > Is this another bug similar to bug 23253, fixed in commit
> > f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
> > rounding mode for tgamma on i386 [BZ #23253]")?
> >
> > Thanks,
> > Florian
> >
>
> I think this is slight different because _Float128 on x86_64 is
> not subject to -mfpmath switch (afaik).  The issue is libgcc
> generates i387 exceptions where the expectation is it should be
> only use SSE one.

Should it be fixed in libgcc?

-- 
H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-04-16 10:14 ` Florian Weimer
@ 2020-04-16 14:06   ` Adhemerval Zanella
  2020-04-16 14:12     ` H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2020-04-16 14:06 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 16/04/2020 07:14, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
>> they should work on both float, double, and long double) while the
>> internal libc_fe* set either SSE (float, double, and float128) or
>> i387 (long double).
>>
>> The libgcc __sfp_handle_exceptions (used on float128 implementation),
>> however, will set either SEE or i387 exception depending of the
>> exception to raise.  This broke the internal assumption of float128
>> where only SSE operations will be used.
>>
>> This patch reimplements the libgcc __sfp_handle_exceptions to use only
>> SSE operations and sets libgcc to use it instead of its own
>> implementation.
>>
>> And I think we should fix libgcc in a similar manner, since checking on
>> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
>> and x86_64 ABI also expectes float128 to use SSE registers [1]
>> (although it is not clear on how future implementation might implement
>> it).
> 
> Is this another bug similar to bug 23253, fixed in commit
> f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
> rounding mode for tgamma on i386 [BZ #23253]")?
> 
> Thanks,
> Florian
> 

I think this is slight different because _Float128 on x86_64 is
not subject to -mfpmath switch (afaik).  The issue is libgcc
generates i387 exceptions where the expectation is it should be 
only use SSE one.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-03-30 19:28 Adhemerval Zanella
  2020-04-16  8:35 ` Stefan Liebler
@ 2020-04-16 10:14 ` Florian Weimer
  2020-04-16 14:06   ` Adhemerval Zanella
  1 sibling, 1 reply; 18+ messages in thread
From: Florian Weimer @ 2020-04-16 10:14 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> they should work on both float, double, and long double) while the
> internal libc_fe* set either SSE (float, double, and float128) or
> i387 (long double).
>
> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> however, will set either SEE or i387 exception depending of the
> exception to raise.  This broke the internal assumption of float128
> where only SSE operations will be used.
>
> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> SSE operations and sets libgcc to use it instead of its own
> implementation.
>
> And I think we should fix libgcc in a similar manner, since checking on
> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> and x86_64 ABI also expectes float128 to use SSE registers [1]
> (although it is not clear on how future implementation might implement
> it).

Is this another bug similar to bug 23253, fixed in commit
f496b28e61d0342f579bf794c71b80e9c7d0b1b5 ("math: Set 387 and SSE2
rounding mode for tgamma on i386 [BZ #23253]")?

Thanks,
Florian


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC] x86_64: Add SSE sfp-exceptions
  2020-03-30 19:28 Adhemerval Zanella
@ 2020-04-16  8:35 ` Stefan Liebler
  2020-04-16 10:14 ` Florian Weimer
  1 sibling, 0 replies; 18+ messages in thread
From: Stefan Liebler @ 2020-04-16  8:35 UTC (permalink / raw)
  To: libc-alpha

Can somebody of the x86 maintainers have a look at this patch, please?

On 3/30/20 9:28 PM, Adhemerval Zanella via Libc-alpha wrote:
> The exported x86_64 fenv.h functions operate on both i387 and SSE (since
> they should work on both float, double, and long double) while the
> internal libc_fe* set either SSE (float, double, and float128) or
> i387 (long double).
> 
> The libgcc __sfp_handle_exceptions (used on float128 implementation),
> however, will set either SEE or i387 exception depending of the
> exception to raise.  This broke the internal assumption of float128
> where only SSE operations will be used.
> 
> This patch reimplements the libgcc __sfp_handle_exceptions to use only
> SSE operations and sets libgcc to use it instead of its own
> implementation.
> 
> And I think we should fix libgcc in a similar manner, since checking on
> config/i386/64/sfp-machine.h it already only supports SSE rounding mode
> and x86_64 ABI also expectes float128 to use SSE registers [1]
> (although it is not clear on how future implementation might implement
> it).
> 
> Checked on x86_64-linux-gnu.
> 
> [1] https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
> ---
>   sysdeps/x86/fpu/sfp-exceptions.c | 58 ++++++++++++++++++++++++++++++++
>   sysdeps/x86_64/fpu/Makefile      |  3 ++
>   2 files changed, 61 insertions(+)
>   create mode 100644 sysdeps/x86/fpu/sfp-exceptions.c
> 
> diff --git a/sysdeps/x86/fpu/sfp-exceptions.c b/sysdeps/x86/fpu/sfp-exceptions.c
> new file mode 100644
> index 0000000000..2ddbfe11ba
> --- /dev/null
> +++ b/sysdeps/x86/fpu/sfp-exceptions.c
> @@ -0,0 +1,58 @@
> +/* x86_64 soft-fp exception handling for _Float128.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <fenv.h>
> +#include <float.h>
> +#include <math-barriers.h>
> +#include <soft-fp.h>
> +
> +void
> +__sfp_handle_exceptions (int _fex)
> +{
> +  if (_fex & FP_EX_INVALID)
> +    {
> +      float f = 0.0f;
> +      math_force_eval (f / f);
> +    }
> +  if (_fex & FP_EX_DENORM)
> +    {
> +      float f = FLT_MIN, g = 2.0f;
> +      math_force_eval (f / g);
> +    }
> +  if (_fex & FP_EX_DIVZERO)
> +    {
> +      float f = 1.0f, g = 0.0f;
> +      math_force_eval (f / g);
> +    }
> +  if (_fex & FP_EX_OVERFLOW)
> +    {
> +      float force_underflow = FLT_MAX * FLT_MAX;
> +      math_force_eval (force_underflow);
> +    }
> +  if (_fex & FP_EX_UNDERFLOW)
> +    {
> +      float force_overflow = FLT_MIN * FLT_MIN;
> +      math_force_eval (force_overflow);
> +    }
> +  if (_fex & FP_EX_INEXACT)
> +    {
> +      float f = 1.0f, g = 3.0f;
> +      math_force_eval (f / g);
> +    }
> +}
> +strong_alias (__sfp_handle_exceptions, __wrap___sfp_handle_exceptions)
> diff --git a/sysdeps/x86_64/fpu/Makefile b/sysdeps/x86_64/fpu/Makefile
> index a4ff2723a8..5becb96fa3 100644
> --- a/sysdeps/x86_64/fpu/Makefile
> +++ b/sysdeps/x86_64/fpu/Makefile
> @@ -25,6 +25,9 @@ endif
> 
>   # Variables for libmvec tests.
>   ifeq ($(subdir),math)
> +libm-routines += sfp-exceptions
> +LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
> +
>   ifeq ($(build-mathvec),yes)
>   libmvec-tests += double-vlen2 double-vlen4 double-vlen4-avx2 \
>   		 float-vlen4 float-vlen8 float-vlen8-avx2
> 


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [RFC] x86_64: Add SSE sfp-exceptions
@ 2020-03-30 19:28 Adhemerval Zanella
  2020-04-16  8:35 ` Stefan Liebler
  2020-04-16 10:14 ` Florian Weimer
  0 siblings, 2 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2020-03-30 19:28 UTC (permalink / raw)
  To: libc-alpha

The exported x86_64 fenv.h functions operate on both i387 and SSE (since
they should work on both float, double, and long double) while the
internal libc_fe* set either SSE (float, double, and float128) or
i387 (long double).

The libgcc __sfp_handle_exceptions (used on float128 implementation),
however, will set either SEE or i387 exception depending of the
exception to raise.  This broke the internal assumption of float128
where only SSE operations will be used.

This patch reimplements the libgcc __sfp_handle_exceptions to use only
SSE operations and sets libgcc to use it instead of its own
implementation.

And I think we should fix libgcc in a similar manner, since checking on
config/i386/64/sfp-machine.h it already only supports SSE rounding mode
and x86_64 ABI also expectes float128 to use SSE registers [1]
(although it is not clear on how future implementation might implement
it).

Checked on x86_64-linux-gnu.

[1] https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
---
 sysdeps/x86/fpu/sfp-exceptions.c | 58 ++++++++++++++++++++++++++++++++
 sysdeps/x86_64/fpu/Makefile      |  3 ++
 2 files changed, 61 insertions(+)
 create mode 100644 sysdeps/x86/fpu/sfp-exceptions.c

diff --git a/sysdeps/x86/fpu/sfp-exceptions.c b/sysdeps/x86/fpu/sfp-exceptions.c
new file mode 100644
index 0000000000..2ddbfe11ba
--- /dev/null
+++ b/sysdeps/x86/fpu/sfp-exceptions.c
@@ -0,0 +1,58 @@
+/* x86_64 soft-fp exception handling for _Float128.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <float.h>
+#include <math-barriers.h>
+#include <soft-fp.h>
+
+void
+__sfp_handle_exceptions (int _fex)
+{
+  if (_fex & FP_EX_INVALID)
+    {
+      float f = 0.0f;
+      math_force_eval (f / f);
+    }
+  if (_fex & FP_EX_DENORM)
+    {
+      float f = FLT_MIN, g = 2.0f;
+      math_force_eval (f / g);
+    }
+  if (_fex & FP_EX_DIVZERO)
+    {
+      float f = 1.0f, g = 0.0f;
+      math_force_eval (f / g);
+    }
+  if (_fex & FP_EX_OVERFLOW)
+    {
+      float force_underflow = FLT_MAX * FLT_MAX;
+      math_force_eval (force_underflow);
+    }
+  if (_fex & FP_EX_UNDERFLOW)
+    {
+      float force_overflow = FLT_MIN * FLT_MIN;
+      math_force_eval (force_overflow);
+    }
+  if (_fex & FP_EX_INEXACT)
+    {
+      float f = 1.0f, g = 3.0f;
+      math_force_eval (f / g);
+    }
+}
+strong_alias (__sfp_handle_exceptions, __wrap___sfp_handle_exceptions)
diff --git a/sysdeps/x86_64/fpu/Makefile b/sysdeps/x86_64/fpu/Makefile
index a4ff2723a8..5becb96fa3 100644
--- a/sysdeps/x86_64/fpu/Makefile
+++ b/sysdeps/x86_64/fpu/Makefile
@@ -25,6 +25,9 @@ endif
 
 # Variables for libmvec tests.
 ifeq ($(subdir),math)
+libm-routines += sfp-exceptions
+LDFLAGS-m.so += -Wl,--wrap=__sfp_handle_exceptions
+
 ifeq ($(build-mathvec),yes)
 libmvec-tests += double-vlen2 double-vlen4 double-vlen4-avx2 \
 		 float-vlen4 float-vlen8 float-vlen8-avx2
-- 
2.17.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2020-04-20 21:03 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-19  9:54 [RFC] x86_64: Add SSE sfp-exceptions Uros Bizjak
2020-04-19 20:17 ` Adhemerval Zanella
2020-04-19 20:48   ` Uros Bizjak
2020-04-20 11:09     ` Adhemerval Zanella
2020-04-20 21:03       ` Joseph Myers
  -- strict thread matches above, loose matches on Subject: below --
2020-03-30 19:28 Adhemerval Zanella
2020-04-16  8:35 ` Stefan Liebler
2020-04-16 10:14 ` Florian Weimer
2020-04-16 14:06   ` Adhemerval Zanella
2020-04-16 14:12     ` H.J. Lu
2020-04-16 14:17       ` Adhemerval Zanella
2020-04-16 14:24         ` H.J. Lu
2020-04-16 14:38           ` Adhemerval Zanella
2020-04-16 14:46             ` H.J. Lu
2020-04-17 12:10               ` Adhemerval Zanella
2020-04-17 13:46                 ` H.J. Lu
2020-04-17 14:36                   ` Adhemerval Zanella
2020-04-17 14:38                     ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).