OSDN Git Service

PR optimization/10817
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Nov 2003 13:56:42 +0000 (13:56 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Nov 2003 13:56:42 +0000 (13:56 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@73200 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ifcvt.c
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20031102-1.c [new file with mode: 0644]

index dd9854a..25dd9c1 100644 (file)
@@ -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.
index fe38060..9844bf4 100644 (file)
@@ -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))
index ee75e34..bf44b55 100644 (file)
@@ -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;
index 8bfe899..1dabd38 100644 (file)
@@ -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 ==
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031102-1.c b/gcc/testsuite/gcc.c-torture/compile/20031102-1.c
new file mode 100644 (file)
index 0000000..e32b8bd
--- /dev/null
@@ -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;
+}
+