* ifcvt.c (noce_get_condition): Make certain that the condition
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Jul 2002 17:48:04 +0000 (17:48 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Jul 2002 17:48:04 +0000 (17:48 +0000)
        is valid at JUMP.

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

gcc/ChangeLog
gcc/ifcvt.c
gcc/testsuite/gcc.c-torture/execute/20020716-1.c [new file with mode: 0644]

index 574f0d8..27839a3 100644 (file)
@@ -1,3 +1,9 @@
+2002-07-18  Richard Henderson  <rth@redhat.com>
+
+       PR optimization/7147
+       * ifcvt.c (noce_get_condition): Make certain that the condition
+       is valid at JUMP.
+
 Thu Jul 18 13:44:51 2002  J"orn Rennecke <joern.rennecke@superh.com>
 
        * sh.c (barrier_align, push): Shut up compiler warnings.
@@ -63,7 +69,7 @@ Wed Jul 17 19:23:32 2002  J"orn Rennecke <joern.rennecke@superh.com>
        suppress addition when either ct or cf are zero.
 
 2002-06-17  Eric Botcazou <ebotcazou@multimania.com>
-            Glen Nakamura <glen@imodulo.com>
+           Glen Nakamura <glen@imodulo.com>
 
        PR optimization/6713
        * loop.c (loop_givs_rescan): Explicitly delete the insn that
index 6bc522d..cf7b660 100644 (file)
@@ -1496,45 +1496,73 @@ noce_try_abs (if_info)
   return TRUE;
 }
 
-/* Look for the condition for the jump first.  We'd prefer to avoid
-   get_condition if we can -- it tries to look back for the contents
-   of an original compare.  On targets that use normal integers for
-   comparisons, e.g. alpha, this is wasteful.  */
+/* Similar to get_condition, only the resulting condition must be
+   valid at JUMP, instead of at EARLIEST.  */
 
 static rtx
 noce_get_condition (jump, earliest)
      rtx jump;
      rtx *earliest;
 {
-  rtx cond;
-  rtx set;
-
-  /* If the condition variable is a register and is MODE_INT, accept it.
-     Otherwise, fall back on get_condition.  */
+  rtx cond, set, tmp, insn;
+  bool reverse;
 
   if (! any_condjump_p (jump))
     return NULL_RTX;
 
   set = pc_set (jump);
 
+  /* If this branches to JUMP_LABEL when the condition is false,
+     reverse the condition.  */
+  reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
+            && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump));
+
+  /* If the condition variable is a register and is MODE_INT, accept it.  */
+
   cond = XEXP (SET_SRC (set), 0);
-  if (GET_CODE (XEXP (cond, 0)) == REG
-      && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT)
+  tmp = XEXP (cond, 0);
+  if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT)
     {
       *earliest = jump;
 
-      /* If this branches to JUMP_LABEL when the condition is false,
-        reverse the condition.  */
-      if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
-         && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump))
+      if (reverse)
        cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
-                              GET_MODE (cond), XEXP (cond, 0),
-                              XEXP (cond, 1));
+                              GET_MODE (cond), tmp, XEXP (cond, 1));
+      return cond;
     }
-  else
-    cond = get_condition (jump, earliest);
 
-  return cond;
+  /* Otherwise, fall back on canonicalize_condition to do the dirty
+     work of manipulating MODE_CC values and COMPARE rtx codes.  */
+
+  tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
+  if (!tmp)
+    return NULL_RTX;
+
+  /* We are going to insert code before JUMP, not before EARLIEST.
+     We must therefore be certain that the given condition is valid
+     at JUMP by virtue of not having been modified since.  */
+  for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn))
+    if (INSN_P (insn) && modified_in_p (tmp, insn))
+      break;
+  if (insn == jump)
+    return tmp;
+
+  /* The condition was modified.  See if we can get a partial result
+     that doesn't follow all the reversals.  Perhaps combine can fold
+     them together later.  */
+  tmp = XEXP (tmp, 0);
+  if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
+    return NULL_RTX;
+  tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp);
+  if (!tmp)
+    return NULL_RTX;
+
+  /* For sanity's sake, re-validate the new result.  */
+  for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn))
+    if (INSN_P (insn) && modified_in_p (tmp, insn))
+      return NULL_RTX;
+
+  return tmp;
 }
 
 /* Return true if OP is ok for if-then-else processing.  */
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020716-1.c b/gcc/testsuite/gcc.c-torture/execute/20020716-1.c
new file mode 100644 (file)
index 0000000..7f55959
--- /dev/null
@@ -0,0 +1,36 @@
+extern void abort (void);
+extern void exit (int);
+
+int sub1 (int val)
+{
+  return val;
+}
+
+int testcond (int val)
+{
+  int flag1;
+
+    {
+      int t1 = val;
+        {
+          int t2 = t1;
+            {
+              flag1 = sub1 (t2) ==0;
+              goto lab1;
+            };
+        }
+      lab1: ;
+    }
+
+  if (flag1 != 0)
+    return 0x4d0000;
+  else
+    return 0;
+}
+
+int main (void)
+{
+  if (testcond (1))
+    abort ();
+  exit (0);
+}