diff options
author | Jeff Law <law@redhat.com> | 2002-04-03 03:21:29 +0000 |
---|---|---|
committer | Hans-Peter Nilsson <hp@gcc.gnu.org> | 2002-04-03 03:21:29 +0000 |
commit | 5add6d1a6d7221a24424c78a6eff9981e281043c (patch) | |
tree | 81d13ae636c1c2ef3fc57e33050a792f8398c3e7 /gcc | |
parent | 2e839a04cf14dadf85f376c4e2c6ba13945ff73b (diff) | |
download | gcc-5add6d1a6d7221a24424c78a6eff9981e281043c.zip gcc-5add6d1a6d7221a24424c78a6eff9981e281043c.tar.gz gcc-5add6d1a6d7221a24424c78a6eff9981e281043c.tar.bz2 |
combine.c (simplify_comparison): Avoid narrowing a comparison with a paradoxical subreg when...
* combine.c (simplify_comparison): Avoid narrowing a comparison
with a paradoxical subreg when doing so would drop signficant bits.
Co-Authored-By: Hans-Peter Nilsson <hp@bitrange.com>
From-SVN: r51785
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/combine.c | 64 |
2 files changed, 47 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5559699..ed2f083 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-04-03 Jeffrey A Law (law@redhat.com) + Hans-Peter Nilsson <hp@bitrange.com> + + * combine.c (simplify_comparison): Avoid narrowing a comparison + with a paradoxical subreg when doing so would drop signficant bits. + 2002-04-02 Steve Ellcey <sje@cup.hp.com> * builtins.c (expand_builtin_prefetch): Force op0 pointer to Pmode diff --git a/gcc/combine.c b/gcc/combine.c index de3bcef..9a9d648 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -10955,38 +10955,56 @@ simplify_comparison (code, pop0, pop1) /* Now make any compound operations involved in this comparison. Then, check for an outmost SUBREG on OP0 that is not doing anything or is - paradoxical. The latter case can only occur when it is known that the - "extra" bits will be zero. Therefore, it is safe to remove the SUBREG. - We can never remove a SUBREG for a non-equality comparison because the - sign bit is in a different place in the underlying object. */ + paradoxical. The latter transformation must only be performed when + it is known that the "extra" bits will be the same in op0 and op1 or + that they don't matter. There are three cases to consider: + + 1. SUBREG_REG (op0) is a register. In this case the bits are don't + care bits and we can assume they have any convenient value. So + making the transformation is safe. + + 2. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is not defined. + In this case the upper bits of op0 are undefined. We should not make + the simplification in that case as we do not know the contents of + those bits. + + 3. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is defined and not + NIL. In that case we know those bits are zeros or ones. We must + also be sure that they are the same as the upper bits of op1. + + We can never remove a SUBREG for a non-equality comparison because + the sign bit is in a different place in the underlying object. */ op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET); op1 = make_compound_operation (op1, SET); if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0) + /* Case 3 above, to sometimes allow (subreg (mem x)), isn't + implemented. */ + && GET_CODE (SUBREG_REG (op0)) == REG && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT - && (code == NE || code == EQ) - && ((GET_MODE_SIZE (GET_MODE (op0)) - > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))) + && (code == NE || code == EQ)) { - op0 = SUBREG_REG (op0); - op1 = gen_lowpart_for_combine (GET_MODE (op0), op1); - } + if (GET_MODE_SIZE (GET_MODE (op0)) + > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))) + { + op0 = SUBREG_REG (op0); + op1 = gen_lowpart_for_combine (GET_MODE (op0), op1); + } + else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) + <= HOST_BITS_PER_WIDE_INT) + && (nonzero_bits (SUBREG_REG (op0), + GET_MODE (SUBREG_REG (op0))) + & ~GET_MODE_MASK (GET_MODE (op0))) == 0) + { + tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), op1); - else if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0) - && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT - && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT - && (code == NE || code == EQ) - && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) - <= HOST_BITS_PER_WIDE_INT) - && (nonzero_bits (SUBREG_REG (op0), GET_MODE (SUBREG_REG (op0))) - & ~GET_MODE_MASK (GET_MODE (op0))) == 0 - && (tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), - op1), - (nonzero_bits (tem, GET_MODE (SUBREG_REG (op0))) - & ~GET_MODE_MASK (GET_MODE (op0))) == 0)) - op0 = SUBREG_REG (op0), op1 = tem; + if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0))) + & ~GET_MODE_MASK (GET_MODE (op0))) == 0) + op0 = SUBREG_REG (op0), op1 = tem; + } + } /* We now do the opposite procedure: Some machines don't have compare insns in all modes. If OP0's mode is an integer mode smaller than a |