From: Richard Henderson Date: Thu, 18 Jul 2002 17:45:54 +0000 (-0700) Subject: ifcvt.c (noce_get_condition): Make certain that the condition is valid at JUMP. X-Git-Tag: releases/gcc-3.1.1~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c8245654d91793ce129a33435034d6ec6fbe198;p=thirdparty%2Fgcc.git 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: r55559 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c2b06414a478..267f5bc203d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-07-18 Richard Henderson + + PR optimization/7147 + * ifcvt.c (noce_get_condition): Make certain that the condition + is valid at JUMP. + 2002-07-16 Hans-Peter Nilsson * config/cris/linux.h (CRIS_LINK_SUBTARGET_SPEC): Don't diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 0d65eab6aaa3..166c59c1307c 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1504,45 +1504,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 000000000000..7f559590e9a6 --- /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); +}