Commit 5ac20c1a by Roger Sayle Committed by Roger Sayle

re PR rtl-optimization/18928 (ice on valid code with -O2 -fPIC)


	PR rtl-optimization/18928
	* simplify_rtx.c (plus_minus_operand_p): New function to encode
	the test for suitable operands for calls to simplify_plus_minus.
	Only allow (CONST (PLUS x y)) if both x and y are CONSTANT_P.
	(simplify_binary_operation): Use plus_minus_operand_p.

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

From-SVN: r92109
parent 04482133
2004-12-13 Roger Sayle <roger@eyesopen.com>
PR rtl-optimization/18928
* simplify_rtx.c (plus_minus_operand_p): New function to encode
the test for suitable operands for calls to simplify_plus_minus.
Only allow (CONST (PLUS x y)) if both x and y are CONSTANT_P.
(simplify_binary_operation): Use plus_minus_operand_p.
2004-12-13 Alexandre Oliva <aoliva@redhat.com> 2004-12-13 Alexandre Oliva <aoliva@redhat.com>
PR tree-opt/16951 PR tree-opt/16951
......
...@@ -50,6 +50,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -50,6 +50,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
((((HOST_WIDE_INT) low) < 0) ? ((HOST_WIDE_INT) -1) : ((HOST_WIDE_INT) 0)) ((((HOST_WIDE_INT) low) < 0) ? ((HOST_WIDE_INT) -1) : ((HOST_WIDE_INT) 0))
static rtx neg_const_int (enum machine_mode, rtx); static rtx neg_const_int (enum machine_mode, rtx);
static bool plus_minus_operand_p (rtx);
static int simplify_plus_minus_op_data_cmp (const void *, const void *); static int simplify_plus_minus_op_data_cmp (const void *, const void *);
static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx, static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx,
rtx, int); rtx, int);
...@@ -1567,12 +1568,8 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, ...@@ -1567,12 +1568,8 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
and subtle programs can break if operations are associated. */ and subtle programs can break if operations are associated. */
if (INTEGRAL_MODE_P (mode) if (INTEGRAL_MODE_P (mode)
&& (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS && (plus_minus_operand_p (op0)
|| GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS || plus_minus_operand_p (op1))
|| (GET_CODE (op0) == CONST
&& GET_CODE (XEXP (op0, 0)) == PLUS)
|| (GET_CODE (op1) == CONST
&& GET_CODE (XEXP (op1, 0)) == PLUS))
&& (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0) && (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0)
return tem; return tem;
...@@ -1724,12 +1721,8 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, ...@@ -1724,12 +1721,8 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
and subtle programs can break if operations are associated. */ and subtle programs can break if operations are associated. */
if (INTEGRAL_MODE_P (mode) if (INTEGRAL_MODE_P (mode)
&& (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS && (plus_minus_operand_p (op0)
|| GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS || plus_minus_operand_p (op1))
|| (GET_CODE (op0) == CONST
&& GET_CODE (XEXP (op0, 0)) == PLUS)
|| (GET_CODE (op1) == CONST
&& GET_CODE (XEXP (op1, 0)) == PLUS))
&& (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0) && (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0)
return tem; return tem;
...@@ -2677,6 +2670,18 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0, ...@@ -2677,6 +2670,18 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
return result; return result;
} }
/* Check whether an operand is suitable for calling simplify_plus_minus. */
static bool
plus_minus_operand_p (rtx x)
{
return GET_CODE (x) == PLUS
|| GET_CODE (x) == MINUS
|| (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& CONSTANT_P (XEXP (XEXP (x, 0), 0))
&& CONSTANT_P (XEXP (XEXP (x, 0), 1)));
}
/* Like simplify_binary_operation except used for relational operators. /* Like simplify_binary_operation except used for relational operators.
MODE is the mode of the result. If MODE is VOIDmode, both operands must MODE is the mode of the result. If MODE is VOIDmode, both operands must
not also be VOIDmode. not also be VOIDmode.
......
2004-12-13 Roger Sayle <roger@eyesopen.com>
PR rtl-optimization/18928
* gcc.dg/pr18928-1.c: New test case.
2004-12-13 Alexandre Oliva <aoliva@redhat.com> 2004-12-13 Alexandre Oliva <aoliva@redhat.com>
PR tree-opt/16951 PR tree-opt/16951
......
/* PR rtl-optimization/18928 */
/* { dg-do compile { target i?86-*-linux* } } */
/* { dg-options "-O2 -fPIC" } */
const char *toHex( unsigned short u )
{
static char hexVal[5];
int i = 3;
while ( i >= 0 ) {
unsigned short hex = (u & 0x000f);
if ( hex < 0x0a )
hexVal[i] = '0'+hex;
else
hexVal[i] = 'A'+(hex-0x0a);
i--;
}
hexVal[4] = '\0';
return hexVal;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment