mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 17:21:03 +08:00
re PR rtl-optimization/10817 (gcc does not optimize result=0;if(t!=0)result=t; to result=t;)
PR optimization/10817 * ifcvt.c (noce_emit_move_insn): Improve documentation comment. (noce_try_move): New function to optimize an if-the-else into an unconditional move, i.e. "if (a!=b) x=a; else x=b" into "x=a". (noce_process_if_block): Attempt simplification with noce_try_move. * simplify-rtx.c (simplify_ternary_operation): Some minor fixes and improvements to the optimizations of IF_THEN_ELSE expressions. (simplify_subreg): Silence signed/unsigned comparison warning. * gcc.c-torture/compile/20031102-1.c: New test case. From-SVN: r73200
This commit is contained in:
parent
2077750a86
commit
31f0f571e6
@ -1,3 +1,15 @@
|
||||
2003-11-02 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR optimization/10817
|
||||
* ifcvt.c (noce_emit_move_insn): Improve documentation comment.
|
||||
(noce_try_move): New function to optimize an if-the-else into an
|
||||
unconditional move, i.e. "if (a!=b) x=a; else x=b" into "x=a".
|
||||
(noce_process_if_block): Attempt simplification with noce_try_move.
|
||||
|
||||
* simplify-rtx.c (simplify_ternary_operation): Some minor fixes
|
||||
and improvements to the optimizations of IF_THEN_ELSE expressions.
|
||||
(simplify_subreg): Silence signed/unsigned comparison warning.
|
||||
|
||||
2003-11-02 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* Makefile.in (targhooks.o, reload.o): Update dependencies.
|
||||
|
50
gcc/ifcvt.c
50
gcc/ifcvt.c
@ -602,6 +602,7 @@ struct noce_if_info
|
||||
};
|
||||
|
||||
static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
|
||||
static int noce_try_move (struct noce_if_info *);
|
||||
static int noce_try_store_flag (struct noce_if_info *);
|
||||
static int noce_try_addcc (struct noce_if_info *);
|
||||
static int noce_try_store_flag_constants (struct noce_if_info *);
|
||||
@ -674,7 +675,9 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
|
||||
|| code == GEU || code == GTU), normalize);
|
||||
}
|
||||
|
||||
/* Emit instruction to move an rtx into STRICT_LOW_PART. */
|
||||
/* Emit instruction to move an rtx, possibly into STRICT_LOW_PART.
|
||||
X is the destination/target and Y is the value to copy. */
|
||||
|
||||
static void
|
||||
noce_emit_move_insn (rtx x, rtx y)
|
||||
{
|
||||
@ -697,6 +700,49 @@ noce_emit_move_insn (rtx x, rtx y)
|
||||
GET_MODE_BITSIZE (inmode));
|
||||
}
|
||||
|
||||
/* Convert "if (a != b) x = a; else x = b" into "x = a" and
|
||||
"if (a == b) x = a; else x = b" into "x = b". */
|
||||
|
||||
static int
|
||||
noce_try_move (struct noce_if_info *if_info)
|
||||
{
|
||||
rtx cond = if_info->cond;
|
||||
enum rtx_code code = GET_CODE (cond);
|
||||
rtx y, seq;
|
||||
|
||||
if (code != NE && code != EQ)
|
||||
return FALSE;
|
||||
|
||||
/* This optimization isn't valid if either A or B could be a NaN
|
||||
or a signed zero. */
|
||||
if (HONOR_NANS (GET_MODE (if_info->x))
|
||||
|| HONOR_SIGNED_ZEROS (GET_MODE (if_info->x)))
|
||||
return FALSE;
|
||||
|
||||
/* Check whether the operands of the comparison are A and in
|
||||
either order. */
|
||||
if ((rtx_equal_p (if_info->a, XEXP (cond, 0))
|
||||
&& rtx_equal_p (if_info->b, XEXP (cond, 1)))
|
||||
|| (rtx_equal_p (if_info->a, XEXP (cond, 1))
|
||||
&& rtx_equal_p (if_info->b, XEXP (cond, 0))))
|
||||
{
|
||||
y = (code == EQ) ? if_info->a : if_info->b;
|
||||
|
||||
/* Avoid generating the move if the source is the destination. */
|
||||
if (! rtx_equal_p (if_info->x, y))
|
||||
{
|
||||
start_sequence ();
|
||||
noce_emit_move_insn (if_info->x, y);
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insn_before_setloc (seq, if_info->jump,
|
||||
INSN_LOCATOR (if_info->insn_a));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Convert "if (test) x = 1; else x = 0".
|
||||
|
||||
Only try 0 and STORE_FLAG_VALUE here. Other combinations will be
|
||||
@ -1894,6 +1940,8 @@ noce_process_if_block (struct ce_if_block * ce_info)
|
||||
goto success;
|
||||
}
|
||||
|
||||
if (noce_try_move (&if_info))
|
||||
goto success;
|
||||
if (noce_try_store_flag (&if_info))
|
||||
goto success;
|
||||
if (noce_try_minmax (&if_info))
|
||||
|
@ -2821,18 +2821,33 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
|
||||
if (GET_CODE (op0) == CONST_INT)
|
||||
return op0 != const0_rtx ? op1 : op2;
|
||||
|
||||
/* Convert a == b ? b : a to "a". */
|
||||
if (GET_CODE (op0) == NE && ! side_effects_p (op0)
|
||||
&& !HONOR_NANS (mode)
|
||||
&& rtx_equal_p (XEXP (op0, 0), op1)
|
||||
&& rtx_equal_p (XEXP (op0, 1), op2))
|
||||
/* Convert c ? a : a into "a". */
|
||||
if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
|
||||
return op1;
|
||||
else if (GET_CODE (op0) == EQ && ! side_effects_p (op0)
|
||||
&& !HONOR_NANS (mode)
|
||||
&& rtx_equal_p (XEXP (op0, 1), op1)
|
||||
&& rtx_equal_p (XEXP (op0, 0), op2))
|
||||
|
||||
/* Convert a != b ? a : b into "a". */
|
||||
if (GET_CODE (op0) == NE
|
||||
&& ! side_effects_p (op0)
|
||||
&& ! HONOR_NANS (mode)
|
||||
&& ! HONOR_SIGNED_ZEROS (mode)
|
||||
&& ((rtx_equal_p (XEXP (op0, 0), op1)
|
||||
&& rtx_equal_p (XEXP (op0, 1), op2))
|
||||
|| (rtx_equal_p (XEXP (op0, 0), op2)
|
||||
&& rtx_equal_p (XEXP (op0, 1), op1))))
|
||||
return op1;
|
||||
|
||||
/* Convert a == b ? a : b into "b". */
|
||||
if (GET_CODE (op0) == EQ
|
||||
&& ! side_effects_p (op0)
|
||||
&& ! HONOR_NANS (mode)
|
||||
&& ! HONOR_SIGNED_ZEROS (mode)
|
||||
&& ((rtx_equal_p (XEXP (op0, 0), op1)
|
||||
&& rtx_equal_p (XEXP (op0, 1), op2))
|
||||
|| (rtx_equal_p (XEXP (op0, 0), op2)
|
||||
&& rtx_equal_p (XEXP (op0, 1), op1))))
|
||||
return op2;
|
||||
else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
|
||||
|
||||
if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
|
||||
{
|
||||
enum machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
|
||||
? GET_MODE (XEXP (op0, 1))
|
||||
@ -2874,6 +2889,7 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VEC_MERGE:
|
||||
if (GET_MODE (op0) != mode
|
||||
|| GET_MODE (op1) != mode
|
||||
@ -3286,7 +3302,7 @@ simplify_subreg (enum machine_mode outermode, rtx op,
|
||||
of real and imaginary part. */
|
||||
if (GET_CODE (op) == CONCAT)
|
||||
{
|
||||
int is_realpart = byte < GET_MODE_UNIT_SIZE (innermode);
|
||||
int is_realpart = byte < (unsigned int) GET_MODE_UNIT_SIZE (innermode);
|
||||
rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
|
||||
unsigned int final_offset;
|
||||
rtx res;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-11-02 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR optimization/10817
|
||||
* gcc.c-torture/compile/20031102-1.c: New test case.
|
||||
|
||||
2003-11-02 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* gcc.c-torture/execute/va-arg-25.c: Enable only if INT_MAX ==
|
||||
|
12
gcc/testsuite/gcc.c-torture/compile/20031102-1.c
Normal file
12
gcc/testsuite/gcc.c-torture/compile/20031102-1.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* PR optimization/10817.
|
||||
Check that the following code doesn't cause any problems
|
||||
for GCC's if-conversion passes. */
|
||||
|
||||
int foo(int t)
|
||||
{
|
||||
int result = 0;
|
||||
if (t != 0)
|
||||
result = t;
|
||||
return result;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user