From 31f0f571e61d1d7f8ff67a4f6a741173dfc4161c Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sun, 2 Nov 2003 13:56:42 +0000 Subject: 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 --- gcc/ifcvt.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'gcc/ifcvt.c') diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index fe38060..9844bf4 100644 --- a/gcc/ifcvt.c +++ b/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)) -- cgit v1.1