This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Committed] PR middle-end/18520: ICE in emit_store_flag


The following patch resolves PR middle-end/18520 which is an ICE on
valid regression for GCC 4.0.  It transpires that the cause of the
problem is that compare_from_rtx accidentally swaps the machine mode
arguments in it's call to simplify_relational_operation.  In this
function "mode" is the mode of the objects being compared, but
instead of calling simplify_relational_operation using "mode" for
cmp_mode, and VOIDmode for mode, it instead specifies a cmp_mode
of VOIDmode and a result mode of DFmode.  This eventually results
in an gcc_assert failure as for the testcase in the PR, we return
a (const_double:DF 0.0) representing Boolean false.  Doh!

Whilst I was looking through compare_from_rtx I noticed another
place it was confusing mode/cmp_mode, and a latent bug where the
result of simplify_relational_operation is always assumed to be
a comparison if it isn't a constant.  To be safe, I've also fixed
both of these latent problems, and clarified the meaning of the
MODE argument in the commentary before this function.

The following patch has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check".  Committed to mainline CVS.



2004-11-21  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/18520
	* dojump.c (compare_from_rtx): Clarify mode argument in function
	description.  Correct order of mode/cmp_mode arguments in call to
	simplify_relational_operation.  Check "tem" for COMPARISON_P.

	* gcc.dg/pr18520-1.c: New test case.


Index: dojump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dojump.c,v
retrieving revision 1.30
diff -c -3 -p -r1.30 dojump.c
*** dojump.c	18 Oct 2004 22:06:35 -0000	1.30
--- dojump.c	21 Nov 2004 22:15:28 -0000
*************** do_jump_by_parts_equality_rtx (rtx op0,
*** 689,697 ****
  }

  /* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
!    (including code to compute the values to be compared)
!    and set (CC0) according to the result.
!    The decision as to signed or unsigned comparison must be made by the caller.

     We force a stack adjustment unless there are currently
     things pushed on the stack that aren't yet used.
--- 689,698 ----
  }

  /* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
!    MODE is the machine mode of the comparison, not of the result.
!    (including code to compute the values to be compared) and set CC0
!    according to the result.  The decision as to signed or unsigned
!    comparison must be made by the caller.

     We force a stack adjustment unless there are currently
     things pushed on the stack that aren't yet used.
*************** compare_from_rtx (rtx op0, rtx op1, enum
*** 725,741 ****
    do_pending_stack_adjust ();

    code = unsignedp ? unsigned_condition (code) : code;
!   if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
! 						 op0, op1)))
      {
        if (CONSTANT_P (tem))
  	return tem;

!       code = GET_CODE (tem);
!       mode = GET_MODE (tem);
!       op0 = XEXP (tem, 0);
!       op1 = XEXP (tem, 1);
!       unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
      }

    emit_cmp_insn (op0, op1, code, size, mode, unsignedp);
--- 726,746 ----
    do_pending_stack_adjust ();

    code = unsignedp ? unsigned_condition (code) : code;
!   tem = simplify_relational_operation (code, VOIDmode, mode, op0, op1);
!   if (tem)
      {
        if (CONSTANT_P (tem))
  	return tem;

!       if (COMPARISON_P (tem))
! 	{
! 	  code = GET_CODE (tem);
! 	  op0 = XEXP (tem, 0);
! 	  op1 = XEXP (tem, 1);
! 	  mode = GET_MODE (op0);
! 	  unsignedp = (code == GTU || code == LTU
! 		       || code == GEU || code == LEU);
! 	}
      }

    emit_cmp_insn (op0, op1, code, size, mode, unsignedp);


/* PR middle-end/18520 */
/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math" } */

extern int isnan (double __value) __attribute__ ((__const__));

int gsl_isnan (const double x)
{
  return isnan(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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]