From: Jeff Law Date: Wed, 3 Apr 2002 03:21:29 +0000 (+0000) Subject: combine.c (simplify_comparison): Avoid narrowing a comparison with a paradoxical... X-Git-Tag: releases/gcc-3.3.0~5935 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5add6d1a6d7221a24424c78a6eff9981e281043c;p=thirdparty%2Fgcc.git 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 From-SVN: r51785 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 55596999468a..ed2f08343946 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-04-03 Jeffrey A Law (law@redhat.com) + Hans-Peter Nilsson + + * combine.c (simplify_comparison): Avoid narrowing a comparison + with a paradoxical subreg when doing so would drop signficant bits. + 2002-04-02 Steve Ellcey * builtins.c (expand_builtin_prefetch): Force op0 pointer to Pmode diff --git a/gcc/combine.c b/gcc/combine.c index de3bcefc0c58..9a9d6484f565 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