[PATCH] PR opt/10764: ICE using x86 logdf2

Roger Sayle roger@www.eyesopen.com
Wed May 14 20:05:00 GMT 2003


Many thanks to Toon for bringing the GNATS PR to my attention.
My recent patch to add support for log, logf and logl as inline
intrinsics on IA-32 is interactly badly with CSE and/or reload.

The problem is that the log?f2 expanders internally make use
of a constant which is placed in a pseudo.  CSE currently tries
to propagate this constant between invocations of "log" in the
source code.  Unfortunately, the fyl2x instruction pops its two
operands from the FP stack, performs the calculation and pushes
its single result.  This effectively clobbers (consumes) the st(1)
register.  Hence if the pseudo holding the constant is assigned
to st(1), the pseudo won't be available/valid later in the code.
Hence the ICE.

Although reg-stack understands the behaviour of "fyl2x", we need
to either prevent CSE from propagating the constant or persuade
reload to make a copy before using st(1) to hold it.  The patch
below achieves the first, by making the clobber of the second
arguments of fyl2x and fpatan explicit in the RTL.  This indeed
fixes the problem/ICE: the constant isn't available for CSE, and
is instead loaded each time its required.


Is this the correct fix?


The following patch has been tested on i686-pc-linux-gnu with a
complete "make bootstrap", all languages except treelang (including
Ada!), and regression tested with a top-level "make -k check" with
no new failures.  I've confirmed that we now generate the correct
code for the new testcase, that ICEs without this patch.


Ok for mainline?


2003-05-14  Roger Sayle  <roger@eyesopen.com>

	PR optimization/10764
	* config/i386/i386.md (atan2df3, atan2sf3, atan2xf3, atan2tf3):
	Add an explicit clobber to show that UNSPEC_FPATAN clobbers st(1).
	(*fyl2x_sfxf3, *fyl2x_dfxf3, *fyl2x_xf3, *fyl2x_tfxf3):  Likewise,
	add an explicit clobber to show that UNSPEC_FYL2X clobbers st(1).
	(logsf2, logdf2, logxf2, logtf2): Update expander patterns to match
	the corresponding *fyl2x_?fxf3 instructions.

	* gcc.dg/builtins-15.c: New test case.


Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.459
diff -c -3 -p -r1.459 i386.md
*** i386.md	12 May 2003 02:51:37 -0000	1.459
--- i386.md	14 May 2003 16:22:39 -0000
***************
*** 15481,15490 ****
     (set_attr "mode" "XF")])

  (define_insn "atan2df3"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
! 		    (match_operand:DF 1 "register_operand" "u")]
! 	 UNSPEC_FPATAN))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
--- 15481,15491 ----
     (set_attr "mode" "XF")])

  (define_insn "atan2df3"
!   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
! 		   (unspec:DF [(match_operand:DF 2 "register_operand" "0")
! 			       (match_operand:DF 1 "register_operand" "u")]
! 		    UNSPEC_FPATAN))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
***************
*** 15492,15501 ****
     (set_attr "mode" "DF")])

  (define_insn "atan2sf3"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(unspec:SF [(match_operand:SF 2 "register_operand" "0")
! 		    (match_operand:SF 1 "register_operand" "u")]
! 	 UNSPEC_FPATAN))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
--- 15493,15503 ----
     (set_attr "mode" "DF")])

  (define_insn "atan2sf3"
!   [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
! 		   (unspec:SF [(match_operand:SF 2 "register_operand" "0")
! 			       (match_operand:SF 1 "register_operand" "u")]
! 		    UNSPEC_FPATAN))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
***************
*** 15503,15512 ****
     (set_attr "mode" "SF")])

  (define_insn "atan2xf3"
!   [(set (match_operand:XF 0 "register_operand" "=f")
! 	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
! 		    (match_operand:XF 1 "register_operand" "u")]
! 	 UNSPEC_FPATAN))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
--- 15505,15515 ----
     (set_attr "mode" "SF")])

  (define_insn "atan2xf3"
!   [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
! 		   (unspec:XF [(match_operand:XF 2 "register_operand" "0")
! 			       (match_operand:XF 1 "register_operand" "u")]
! 		    UNSPEC_FPATAN))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
***************
*** 15514,15523 ****
     (set_attr "mode" "XF")])

  (define_insn "atan2tf3"
!   [(set (match_operand:TF 0 "register_operand" "=f")
! 	(unspec:TF [(match_operand:TF 2 "register_operand" "0")
! 		    (match_operand:TF 1 "register_operand" "u")]
! 	 UNSPEC_FPATAN))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
--- 15517,15527 ----
     (set_attr "mode" "XF")])

  (define_insn "atan2tf3"
!   [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
! 		   (unspec:TF [(match_operand:TF 2 "register_operand" "0")
! 			       (match_operand:TF 1 "register_operand" "u")]
! 		    UNSPEC_FPATAN))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fpatan"
***************
*** 15525,15534 ****
     (set_attr "mode" "XF")])

  (define_insn "*fyl2x_sfxf3"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(unspec:SF [(match_operand:SF 2 "register_operand" "0")
! 		    (match_operand:XF 1 "register_operand" "u")]
! 	 UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
--- 15529,15539 ----
     (set_attr "mode" "XF")])

  (define_insn "*fyl2x_sfxf3"
!   [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
! 		   (unspec:SF [(match_operand:SF 2 "register_operand" "0")
! 			       (match_operand:XF 1 "register_operand" "u")]
! 		    UNSPEC_FYL2X))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
***************
*** 15536,15545 ****
     (set_attr "mode" "SF")])

  (define_insn "*fyl2x_dfxf3"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
! 		    (match_operand:XF 1 "register_operand" "u")]
! 	 UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
--- 15541,15551 ----
     (set_attr "mode" "SF")])

  (define_insn "*fyl2x_dfxf3"
!   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
! 		   (unspec:DF [(match_operand:DF 2 "register_operand" "0")
! 			       (match_operand:XF 1 "register_operand" "u")]
! 		    UNSPEC_FYL2X))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
***************
*** 15547,15556 ****
     (set_attr "mode" "DF")])

  (define_insn "*fyl2x_xf3"
!   [(set (match_operand:XF 0 "register_operand" "=f")
! 	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
! 		    (match_operand:XF 1 "register_operand" "u")]
! 	 UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
--- 15553,15563 ----
     (set_attr "mode" "DF")])

  (define_insn "*fyl2x_xf3"
!   [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
! 		   (unspec:XF [(match_operand:XF 2 "register_operand" "0")
! 			       (match_operand:XF 1 "register_operand" "u")]
! 		    UNSPEC_FYL2X))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
***************
*** 15558,15567 ****
     (set_attr "mode" "XF")])

  (define_insn "*fyl2x_tfxf3"
!   [(set (match_operand:TF 0 "register_operand" "=f")
! 	(unspec:TF [(match_operand:TF 2 "register_operand" "0")
! 		    (match_operand:XF 1 "register_operand" "u")]
! 	 UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
--- 15565,15575 ----
     (set_attr "mode" "XF")])

  (define_insn "*fyl2x_tfxf3"
!   [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
! 		   (unspec:TF [(match_operand:TF 2 "register_operand" "0")
! 			       (match_operand:XF 1 "register_operand" "u")]
! 		    UNSPEC_FYL2X))
! 	      (clobber (match_dup 1))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fyl2x"
***************
*** 15569,15577 ****
     (set_attr "mode" "XF")])

  (define_expand "logsf2"
!   [(set (match_operand:SF 0 "register_operand" "")
! 	(unspec:SF [(match_operand:SF 1 "register_operand" "")
! 		    (match_dup 2)] UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {
--- 15577,15586 ----
     (set_attr "mode" "XF")])

  (define_expand "logsf2"
!   [(parallel [(set (match_operand:SF 0 "register_operand" "")
! 		   (unspec:SF [(match_operand:SF 1 "register_operand" "")
! 			       (match_dup 2)] UNSPEC_FYL2X))
! 	      (clobber (match_dup 2))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {
***************
*** 15583,15591 ****
  })

  (define_expand "logdf2"
!   [(set (match_operand:DF 0 "register_operand" "")
! 	(unspec:DF [(match_operand:DF 1 "register_operand" "")
! 		    (match_dup 2)] UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {
--- 15592,15601 ----
  })

  (define_expand "logdf2"
!   [(parallel [(set (match_operand:DF 0 "register_operand" "")
! 		   (unspec:DF [(match_operand:DF 1 "register_operand" "")
! 			       (match_dup 2)] UNSPEC_FYL2X))
! 	      (clobber (match_dup 2))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {
***************
*** 15597,15605 ****
  })

  (define_expand "logxf2"
!   [(set (match_operand:XF 0 "register_operand" "")
! 	(unspec:XF [(match_operand:XF 1 "register_operand" "")
! 		    (match_dup 2)] UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {
--- 15607,15616 ----
  })

  (define_expand "logxf2"
!   [(parallel [(set (match_operand:XF 0 "register_operand" "")
! 		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
! 			       (match_dup 2)] UNSPEC_FYL2X))
! 	      (clobber (match_dup 2))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {
***************
*** 15611,15619 ****
  })

  (define_expand "logtf2"
!   [(set (match_operand:TF 0 "register_operand" "")
! 	(unspec:TF [(match_operand:TF 1 "register_operand" "")
! 		    (match_dup 2)] UNSPEC_FYL2X))]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {
--- 15622,15631 ----
  })

  (define_expand "logtf2"
!   [(parallel [(set (match_operand:TF 0 "register_operand" "")
! 		   (unspec:TF [(match_operand:TF 1 "register_operand" "")
! 			       (match_dup 2)] UNSPEC_FYL2X))
! 	      (clobber (match_dup 2))])]
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
  {


/* Derived from PR optimization/10764  */

/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math" } */

double log(double x);

double ndtri(double y0)
{
  double x;

  x = log(y0);
  x = log(x);

  return x;
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list