Patchwork [Solaris] Catch FP exceptions

login
register
mail settings
Submitter Eric Botcazou
Date May 23, 2013, 5:27 p.m.
Message ID <1665825.0OqtZUyZYm@polaris>
Download mbox | patch
Permalink /patch/245987/
State New
Headers show

Comments

Eric Botcazou - May 23, 2013, 5:27 p.m.
Hi,

this isn't really valid Ada semantics, but some people enable traps-on-fp-
exceptions in the FPU on Solaris and expect the Ada exception to be caught.
There is a glitch with the x87 and the SPARC FPUs: the SIGFPE is delivered 
after the faulting instruction by Solaris, so the unwinder is fooled and 
miscomputes the faulting address.

Fixed thusly, tested on x86/Solaris and SPARC/Solaris, OK for mainline?


2013-05-23  Eric Botcazou  <ebotcazou@adacore.com>

libgcc/
	* config/sparc/sol2-unwind.h (MD_FALLBACK_FRAME_STATE_FOR): Do not set
	fs->signal_frame for SIGFPE raised for IEEE-754 exceptions.
	* config/i386/sol2-unwind.h (x86_fallback_frame_state): Likewise.


2013-05-23  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/fp_exception.adb: New test.
Rainer Orth - May 28, 2013, 10:03 a.m.
Hi Eric,

> this isn't really valid Ada semantics, but some people enable traps-on-fp-
> exceptions in the FPU on Solaris and expect the Ada exception to be caught.
> There is a glitch with the x87 and the SPARC FPUs: the SIGFPE is delivered 
> after the faulting instruction by Solaris, so the unwinder is fooled and 
> miscomputes the faulting address.
>
> Fixed thusly, tested on x86/Solaris and SPARC/Solaris, OK for mainline?

I've included the patch in my Solaris bootstraps this weekend, and
results don't look good:

* On Solaris 9/x86 and Solaris 10/x86 (both 32- and 64-bit), I get a new
  ACATS failure which may or may not be related:

+FAIL:  cxg2021

  i386 only, might be related

,.,. CXG2021 ACATS 2.5 13-05-27 17:47:57
---- CXG2021 Check the accuracy of the complex SIN and COS functions.
   * CXG2021 Identity_2_Test  3 0: Cos(( 1.60300E+01,  1.60000E+01)) 
                imaginary part actual:  1.40623E+06 expected: 
                1.40622E+06 difference:  4.00000E+00 max err:
                3.68797E+00 efactor: 1.40623E+06.
**** CXG2021 FAILED ****************************.

* The new gnat.dg/fp_exception.adb test fails on Solaris 9 and 10/x86,
  Solaris 9 and 11/SPARC:

+FAIL: gnat.dg/fp_exception.adb execution test

raised CONSTRAINT_ERROR : SIGFPE

I haven't yet checked what might be going on.

	Rainer


> 2013-05-23  Eric Botcazou  <ebotcazou@adacore.com>
>
> libgcc/
> 	* config/sparc/sol2-unwind.h (MD_FALLBACK_FRAME_STATE_FOR): Do not set
> 	fs->signal_frame for SIGFPE raised for IEEE-754 exceptions.
> 	* config/i386/sol2-unwind.h (x86_fallback_frame_state): Likewise.
>
>
> 2013-05-23  Eric Botcazou  <ebotcazou@adacore.com>
>
> 	* gnat.dg/fp_exception.adb: New test.
Eric Botcazou - May 28, 2013, 11:29 a.m.
> I've included the patch in my Solaris bootstraps this weekend, and
> results don't look good:
> 
> * On Solaris 9/x86 and Solaris 10/x86 (both 32- and 64-bit), I get a new
>   ACATS failure which may or may not be related:
> 
> +FAIL:  cxg2021
> 
>   i386 only, might be related
> 
> ,.,. CXG2021 ACATS 2.5 13-05-27 17:47:57
> ---- CXG2021 Check the accuracy of the complex SIN and COS functions.
>    * CXG2021 Identity_2_Test  3 0: Cos(( 1.60300E+01,  1.60000E+01))
>                 imaginary part actual:  1.40623E+06 expected:
>                 1.40622E+06 difference:  4.00000E+00 max err:
>                 3.68797E+00 efactor: 1.40623E+06.
> **** CXG2021 FAILED ****************************.

Weird, this test shouldn't exercise the unwinder at all.  This might be 
related to the patch mentioned below...

> * The new gnat.dg/fp_exception.adb test fails on Solaris 9 and 10/x86,
>   Solaris 9 and 11/SPARC:
> 
> +FAIL: gnat.dg/fp_exception.adb execution test
> 
> raised CONSTRAINT_ERROR : SIGFPE

Patch collision.  After

2013-05-24  Eric Botcazou  <ebotcazou@adacore.com>

        * gcc-interface/gigi.h (gnat_init_gcc_fp): Declare.
        * gcc-interface/trans.c (gigi): Call it.
        * gcc-interface/misc.c (gnat_init_gcc_fp): New function.

you need to compile with -ftrapping-math; revised testcase attached.
Rainer Orth - May 28, 2013, 11:52 a.m.
Eric Botcazou <ebotcazou@adacore.com> writes:

>> * The new gnat.dg/fp_exception.adb test fails on Solaris 9 and 10/x86,
>>   Solaris 9 and 11/SPARC:
>> 
>> +FAIL: gnat.dg/fp_exception.adb execution test
>> 
>> raised CONSTRAINT_ERROR : SIGFPE
>
> Patch collision.  After
>
> 2013-05-24  Eric Botcazou  <ebotcazou@adacore.com>
>
>         * gcc-interface/gigi.h (gnat_init_gcc_fp): Declare.
>         * gcc-interface/trans.c (gigi): Call it.
>         * gcc-interface/misc.c (gnat_init_gcc_fp): New function.
>
> you need to compile with -ftrapping-math; revised testcase attached.

This works.  Patch is ok with that revision.

Thanks.
        Rainer
Eric Botcazou - May 28, 2013, 11:14 p.m.
>   i386 only, might be related
> 
> ,.,. CXG2021 ACATS 2.5 13-05-27 17:47:57
> ---- CXG2021 Check the accuracy of the complex SIN and COS functions.
>    * CXG2021 Identity_2_Test  3 0: Cos(( 1.60300E+01,  1.60000E+01))
>                 imaginary part actual:  1.40623E+06 expected:
>                 1.40622E+06 difference:  4.00000E+00 max err:
>                 3.68797E+00 efactor: 1.40623E+06.
> **** CXG2021 FAILED ****************************.

I can reproduce with the unpatched compiler.  Investigating...

Patch

Index: config/sparc/sol2-unwind.h
===================================================================
--- config/sparc/sol2-unwind.h	(revision 199191)
+++ config/sparc/sol2-unwind.h	(working copy)
@@ -403,7 +403,12 @@  MD_FALLBACK_FRAME_STATE_FOR (struct _Unw
   fs->retaddr_column = 0;
   fs->regs.reg[0].how = REG_SAVED_OFFSET;
   fs->regs.reg[0].loc.offset = (long)shifted_ra_location - new_cfa;
-  fs->signal_frame = 1;
+
+  /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn
+     rather than before it, so don't set fs->signal_frame in that case.
+     We test whether the cexc field of the FSR is zero.  */
+  if ((mctx->fpregs.fpu_fsr & 0x1f) == 0)
+    fs->signal_frame = 1;
 
   return _URC_NO_REASON;
 }
Index: config/i386/sol2-unwind.h
===================================================================
--- config/i386/sol2-unwind.h	(revision 199190)
+++ config/i386/sol2-unwind.h	(working copy)
@@ -249,7 +249,12 @@  x86_fallback_frame_state (struct _Unwind
   fs->regs.reg[8].how = REG_SAVED_OFFSET;
   fs->regs.reg[8].loc.offset = (long)&mctx->gregs[EIP] - new_cfa;
   fs->retaddr_column = 8;
-  fs->signal_frame = 1;
+
+  /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn
+     rather than before it, so don't set fs->signal_frame in that case.
+     We test whether the ES field of the Status Register is zero.  */
+  if ((mctx->fpregs.fp_reg_set.fpchip_state.status & 0x80) == 0)
+    fs->signal_frame = 1;
 
   return _URC_NO_REASON;
 }