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]

[PATCH] PR bootstrap/12269: Fix ia64 bootstrap on mainline


I was so close with my last patch, "Numerous simplify_gen_relational
clean-ups", http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00933.html
In fact, the diff between this patch and the previous one is only:

7c7
< --- simplify-rtx.c    14 Sep 2003 19:37:30 -0000
---
> --- simplify-rtx.c    15 Sep 2003 04:46:34 -0000
164c164
< !         return simplify_gen_relational (reversed, mode, op_mode,
---
> !         return simplify_gen_relational (reversed, mode, VOIDmode,
181c181
< !         return simplify_gen_relational (reversed, mode, op_mode,
---
> !         return simplify_gen_relational (reversed, mode, VOIDmode,
199c199
< !         return simplify_gen_relational (GE, mode, op_mode,
---
> !         return simplify_gen_relational (GE, mode, VOIDmode,


My fears were right, the bootstrap failure was caused by a comparison
mode mismatch, indeed caused by my patch to move NOT/NEG simplifications
into simplify-rtx.c.  In simplify_unary_operation, when inverting a
comparison, such as (NOT (EQ X Y)), mode is the mode of the NOT, and
op_mode is the mode of the EQ.  Neither is the actual mode of the
comparison!  For gcc.c-torture/execute/builtins/string-3-lib.c, this
then leads to use simplifying the comparison in BImode, where not
surprisingly "n < 2" is always true.

Thanks to the infrastructure added in the unreviewed patch above,
we can now just pass VOIDmode as the mode of the comparison and
simplify_gen_relational will work out what to do.  This restores
bootstrap for me on ia64-unknown-linux-gnu, all languages except
Ada and treelang, including all the run-time libraries.

This version of the patch has also been tested on i686-pc-linux-gnu
with a complete "make bootstrap", all languages except treelang, and
regression tested with a top-level "make -k check" with no new failures.

Ok for mainline?


Many apologies again for the inconvenience.  Its 5:17am locally, and
time to go to bed.  Fixing this took much longer than I thought...



2003-09-15  Roger Sayle  <roger@eyesopen.com>

	PR bootstrap/12269
	* simplify-rtx.c (simplify_gen_relational): Allow the cmp_mode
	argument to be VOIDmode, taking the mode of the comparison from
	the operands.  Only call simplify_relational_operation if we
	know the mode of the comparison.  Honor FLOAT_STORE_FLAG_VALUE
	if comparison has a floating point result.  Ensure that the
	result is always of the specified mode.
	(simplify_replace_rtx): Simplify call to simplify_gen_relational.
	(simplify_unary_operation): Ensure the correct mode and cmp_mode
	are always passed to simplify_gen_relational.  Simplify NOT of
	comparison operator in any mode, not just BImode.
	(simplify_ternary_operation): Correct tests on the return value
	of simplify_relational_operation to use const_true_rtx, not
	const1_rtx.  Abort if it ever returns a non-constant result.

	* cfgloopanal.c (count_strange_loop_iterations): Use the function
	simplify_relational_operation, not simplify_gen_relational, if
	we're only interested in constant comparisons and will ignore
	non-constant results.


Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.158
diff -c -3 -p -r1.158 simplify-rtx.c
*** simplify-rtx.c	11 Sep 2003 13:01:32 -0000	1.158
--- simplify-rtx.c	15 Sep 2003 04:46:34 -0000
*************** simplify_gen_relational (enum rtx_code c
*** 197,234 ****
  {
    rtx tem;

!   if ((tem = simplify_relational_operation (code, cmp_mode, op0, op1)) != 0)
!     return tem;

    /* For the following tests, ensure const0_rtx is op1.  */
!   if (op0 == const0_rtx && swap_commutative_operands_p (op0, op1))
      tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);

    /* If op0 is a compare, extract the comparison arguments from it.  */
    if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
!     op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);

    /* If op0 is a comparison, extract the comparison arguments form it.  */
!   if (code == NE && op1 == const0_rtx
!       && GET_RTX_CLASS (GET_CODE (op0)) == '<')
!     return op0;
!   else if (code == EQ && op1 == const0_rtx)
!     {
!       /* The following tests GET_RTX_CLASS (GET_CODE (op0)) == '<'.  */
!       enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
!       if (new != UNKNOWN)
!         {
! 	  code = new;
! 	  mode = cmp_mode;
! 	  op1 = XEXP (op0, 1);
! 	  op0 = XEXP (op0, 0);
          }
      }

-   /* Put complex operands first and constants second.  */
-   if (swap_commutative_operands_p (op0, op1))
-     tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
-
    return gen_rtx_fmt_ee (code, mode, op0, op1);
  }

--- 197,258 ----
  {
    rtx tem;

!   if (cmp_mode == VOIDmode)
!     cmp_mode = GET_MODE (op0);
!   if (cmp_mode == VOIDmode)
!     cmp_mode = GET_MODE (op1);
!
!   if (cmp_mode != VOIDmode)
!     {
!       tem = simplify_relational_operation (code, cmp_mode, op0, op1);
!
!       if (tem)
! 	{
! #ifdef FLOAT_STORE_FLAG_VALUE
! 	  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
! 	    {
! 	      REAL_VALUE_TYPE val;
! 	      if (tem == const0_rtx)
! 		return CONST0_RTX (mode);
! 	      if (tem != const_true_rtx)
! 		abort ();
! 	      val = FLOAT_STORE_FLAG_VALUE (mode);
! 	      return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
! 	    }
! #endif
! 	  return tem;
! 	}
!     }

    /* For the following tests, ensure const0_rtx is op1.  */
!   if (swap_commutative_operands_p (op0, op1)
!       || (op0 == const0_rtx && op1 != const0_rtx))
      tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);

    /* If op0 is a compare, extract the comparison arguments from it.  */
    if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
!     return simplify_gen_relational (code, mode, VOIDmode,
! 				    XEXP (op0, 0), XEXP (op0, 1));

    /* If op0 is a comparison, extract the comparison arguments form it.  */
!   if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && op1 == const0_rtx)
!     {
!       if (code == NE)
! 	{
! 	  if (GET_MODE (op0) == mode)
! 	    return op0;
! 	  return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
! 					  XEXP (op0, 0), XEXP (op0, 1));
! 	}
!       else if (code == EQ)
! 	{
! 	  enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
! 	  if (new != UNKNOWN)
! 	    return simplify_gen_relational (new, mode, VOIDmode,
! 					    XEXP (op0, 0), XEXP (op0, 1));
          }
      }

    return gen_rtx_fmt_ee (code, mode, op0, op1);
  }

*************** simplify_replace_rtx (rtx x, rtx old, rt
*** 272,295 ****
  				     : GET_MODE (XEXP (x, 1)));
  	rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
  	rtx op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
! 	rtx temp = simplify_gen_relational (code, mode,
! 					    (op_mode != VOIDmode
! 					     ? op_mode
! 					     : GET_MODE (op0) != VOIDmode
! 					       ? GET_MODE (op0)
! 					       : GET_MODE (op1)),
! 					    op0, op1);
! #ifdef FLOAT_STORE_FLAG_VALUE
! 	if (GET_MODE_CLASS (mode) == MODE_FLOAT)
! 	{
! 	  if (temp == const0_rtx)
! 	    temp = CONST0_RTX (mode);
! 	  else if (temp == const_true_rtx)
! 	    temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
! 						 mode);
! 	}
! #endif
! 	return temp;
        }

      case '3':
--- 296,302 ----
  				     : GET_MODE (XEXP (x, 1)));
  	rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
  	rtx op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
! 	return simplify_gen_relational (code, mode, op_mode, op0, op1);
        }

      case '3':
*************** simplify_unary_operation (enum rtx_code
*** 800,809 ****
  	    return XEXP (op, 0);

  	  /* (not (eq X Y)) == (ne X Y), etc.  */
! 	  if (mode == BImode && GET_RTX_CLASS (GET_CODE (op)) == '<'
  	      && ((reversed = reversed_comparison_code (op, NULL_RTX))
  		  != UNKNOWN))
! 	    return simplify_gen_relational (reversed, op_mode, op_mode,
  					    XEXP (op, 0), XEXP (op, 1));

            /* (not (plus X -1)) can become (neg X).  */
--- 807,816 ----
  	    return XEXP (op, 0);

  	  /* (not (eq X Y)) == (ne X Y), etc.  */
! 	  if (GET_RTX_CLASS (GET_CODE (op)) == '<'
  	      && ((reversed = reversed_comparison_code (op, NULL_RTX))
  		  != UNKNOWN))
! 	    return simplify_gen_relational (reversed, mode, VOIDmode,
  					    XEXP (op, 0), XEXP (op, 1));

            /* (not (plus X -1)) can become (neg X).  */
*************** simplify_unary_operation (enum rtx_code
*** 842,848 ****
  	      && GET_RTX_CLASS (GET_CODE (op)) == '<'
  	      && (reversed = reversed_comparison_code (op, NULL_RTX))
  		 != UNKNOWN)
! 	    return simplify_gen_relational (reversed, op_mode, op_mode,
  					    XEXP (op, 0), XEXP (op, 1));

  	  /* (not (ashiftrt foo C)) where C is the number of bits in FOO
--- 849,855 ----
  	      && GET_RTX_CLASS (GET_CODE (op)) == '<'
  	      && (reversed = reversed_comparison_code (op, NULL_RTX))
  		 != UNKNOWN)
! 	    return simplify_gen_relational (reversed, mode, VOIDmode,
  					    XEXP (op, 0), XEXP (op, 1));

  	  /* (not (ashiftrt foo C)) where C is the number of bits in FOO
*************** simplify_unary_operation (enum rtx_code
*** 853,860 ****
  	      && GET_CODE (op) == ASHIFTRT
  	      && GET_CODE (XEXP (op, 1)) == CONST_INT
  	      && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
! 	    return simplify_gen_relational (GE, mode, mode, XEXP (op, 0),
! 					    const0_rtx);

  	  break;

--- 860,867 ----
  	      && GET_CODE (op) == ASHIFTRT
  	      && GET_CODE (XEXP (op, 1)) == CONST_INT
  	      && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
! 	    return simplify_gen_relational (GE, mode, VOIDmode,
! 					    XEXP (op, 0), const0_rtx);

  	  break;

*************** simplify_ternary_operation (enum rtx_cod
*** 2725,2734 ****
  	  /* See if any simplifications were possible.  */
  	  if (temp == const0_rtx)
  	    return op2;
! 	  else if (temp == const1_rtx)
  	    return op1;
  	  else if (temp)
! 	    op0 = temp;

  	  /* Look for happy constants in op1 and op2.  */
  	  if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
--- 2732,2741 ----
  	  /* See if any simplifications were possible.  */
  	  if (temp == const0_rtx)
  	    return op2;
! 	  else if (temp == const_true_rtx)
  	    return op1;
  	  else if (temp)
! 	    abort ();

  	  /* Look for happy constants in op1 and op2.  */
  	  if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
Index: cfgloopanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloopanal.c,v
retrieving revision 1.11
diff -c -3 -p -r1.11 cfgloopanal.c
*** cfgloopanal.c	19 Aug 2003 23:21:52 -0000	1.11
--- cfgloopanal.c	15 Sep 2003 04:46:35 -0000
*************** count_strange_loop_iterations (rtx init,
*** 470,476 ****

    /* If we are able to prove that we don't pass the first test, we are
       done.  */
!   rqmt = simplify_gen_relational (cond, SImode, mode, init, lim);
    if (rqmt == const0_rtx)
      return const0_rtx;

--- 470,476 ----

    /* If we are able to prove that we don't pass the first test, we are
       done.  */
!   rqmt = simplify_relational_operation (cond, mode, init, lim);
    if (rqmt == const0_rtx)
      return const0_rtx;

*************** count_strange_loop_iterations (rtx init,
*** 560,566 ****
    /* If this is const_true_rtx and we did not take a conservative approximation
       of after_wrap above, we might iterate the calculation (but of course we
       would have to take care about infinite cases).  Ignore this for now.  */
!   rqmt = simplify_gen_relational (cond, SImode, mode, after_wrap, lim);
    if (rqmt != const0_rtx)
      return NULL_RTX;

--- 560,566 ----
    /* If this is const_true_rtx and we did not take a conservative approximation
       of after_wrap above, we might iterate the calculation (but of course we
       would have to take care about infinite cases).  Ignore this for now.  */
!   rqmt = simplify_relational_operation (cond, mode, after_wrap, lim);
    if (rqmt != const0_rtx)
      return NULL_RTX;

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]