aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2002-07-18 10:48:04 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-07-18 10:48:04 -0700
commit30484ccf418d52a3b7ad165785dc7853ae01a77f (patch)
treebe72f09712cf01a23ee3111573e710a3877998c1
parentc1740ae3c12105406dffbf001d67f5905b70b069 (diff)
downloadgcc-30484ccf418d52a3b7ad165785dc7853ae01a77f.zip
gcc-30484ccf418d52a3b7ad165785dc7853ae01a77f.tar.gz
gcc-30484ccf418d52a3b7ad165785dc7853ae01a77f.tar.bz2
ifcvt.c (noce_get_condition): Make certain that the condition is valid at JUMP.
* ifcvt.c (noce_get_condition): Make certain that the condition is valid at JUMP. From-SVN: r55560
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ifcvt.c68
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20020716-1.c36
3 files changed, 91 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 574f0d8..27839a3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 6bc522d..cf7b660 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -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
index 0000000..7f55959
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20020716-1.c
@@ -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);
+}