diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2005-11-09 21:34:31 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2005-11-09 21:34:31 +0000 |
commit | c8e90f4053f0e366630c5147d28d4d9c56e56668 (patch) | |
tree | ca883f3b1639764277c88f95e1f44f59c48c0459 /gcc | |
parent | 7ef67393c7454bb93a070d0290b4196c06a93ce8 (diff) | |
download | gcc-c8e90f4053f0e366630c5147d28d4d9c56e56668.zip gcc-c8e90f4053f0e366630c5147d28d4d9c56e56668.tar.gz gcc-c8e90f4053f0e366630c5147d28d4d9c56e56668.tar.bz2 |
ifcvt.c (noce_get_alt_condition): Use prev_nonnote_insn.
* ifcvt.c (noce_get_alt_condition): Use prev_nonnote_insn.
(noce_try_abs): Negate if the comparison is reversed.
Look only one instruction backwards for a REG_EQUAL note.
From-SVN: r106706
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ifcvt.c | 37 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ifcvt-fabs-1.c | 21 |
4 files changed, 53 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e97e5a3..96381d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-11-09 Eric Botcazou <ebotcazou@adacore.com> + + * ifcvt.c (noce_get_alt_condition): Use prev_nonnote_insn. + (noce_try_abs): Negate if the comparison is reversed. + Look only one instruction backwards for a REG_EQUAL note. + 2005-11-09 Alexandre Oliva <aoliva@redhat.com> PR other/4372 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index da32ab4..e7eec87 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1485,7 +1485,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target, rtx prev_insn; /* First, look to see if we put a constant in a register. */ - prev_insn = PREV_INSN (if_info->cond_earliest); + prev_insn = prev_nonnote_insn (if_info->cond_earliest); if (prev_insn && INSN_P (prev_insn) && GET_CODE (PATTERN (prev_insn)) == SET) @@ -1697,7 +1697,9 @@ noce_try_abs (struct noce_if_info *if_info) if (no_new_pseudos) return FALSE; - /* Recognize A and B as constituting an ABS or NABS. */ + /* Recognize A and B as constituting an ABS or NABS. The canonical + form is a branch around the negation, taken when the object is the + first operand of a comparison against 0 that evaluates to true. */ a = if_info->a; b = if_info->b; if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b)) @@ -1718,25 +1720,30 @@ noce_try_abs (struct noce_if_info *if_info) if (rtx_equal_p (XEXP (cond, 0), b)) c = XEXP (cond, 1); else if (rtx_equal_p (XEXP (cond, 1), b)) - c = XEXP (cond, 0); + { + c = XEXP (cond, 0); + negate = !negate; + } else return FALSE; - /* Verify that C is zero. Search backward through the block for - a REG_EQUAL note if necessary. */ + /* Verify that C is zero. Search one step backward for a + REG_EQUAL note or a simple source if necessary. */ if (REG_P (c)) { - rtx insn, note = NULL; - for (insn = earliest; - insn != BB_HEAD (if_info->test_bb); - insn = PREV_INSN (insn)) - if (INSN_P (insn) - && ((note = find_reg_note (insn, REG_EQUAL, c)) - || (note = find_reg_note (insn, REG_EQUIV, c)))) - break; - if (! note) + rtx set, insn = prev_nonnote_insn (earliest); + if (insn + && (set = single_set (insn)) + && rtx_equal_p (SET_DEST (set), c)) + { + rtx note = find_reg_equal_equiv_note (insn); + if (note) + c = XEXP (note, 0); + else + c = SET_SRC (set); + } + else return FALSE; - c = XEXP (note, 0); } if (MEM_P (c) && GET_CODE (XEXP (c, 0)) == SYMBOL_REF diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 43444c8..2adff34 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-11-09 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/ifcvt-fabs-1.c: New test. + 2005-11-09 Alexandre Oliva <aoliva@redhat.com> PR other/4372 diff --git a/gcc/testsuite/gcc.dg/ifcvt-fabs-1.c b/gcc/testsuite/gcc.dg/ifcvt-fabs-1.c new file mode 100644 index 0000000..6808a8f --- /dev/null +++ b/gcc/testsuite/gcc.dg/ifcvt-fabs-1.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ +/* { dg-options "-O -march=i686" { target i686-*-* } } */ + +extern void abort(void); + +float foo(float f) +{ + if (f < 0.0f) + f = -f; + + return f; +} + +int main(void) +{ + if (foo (-1.0f) != 1.0f) + abort (); + + return 0; +} |