Commit 5add6d1a by Jeff Law Committed by Hans-Peter Nilsson

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
parent 2e839a04
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> 2002-04-02 Steve Ellcey <sje@cup.hp.com>
* builtins.c (expand_builtin_prefetch): Force op0 pointer to Pmode * builtins.c (expand_builtin_prefetch): Force op0 pointer to Pmode
......
...@@ -10955,38 +10955,56 @@ simplify_comparison (code, pop0, pop1) ...@@ -10955,38 +10955,56 @@ simplify_comparison (code, pop0, pop1)
/* Now make any compound operations involved in this comparison. Then, /* Now make any compound operations involved in this comparison. Then,
check for an outmost SUBREG on OP0 that is not doing anything or is 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 paradoxical. The latter transformation must only be performed when
"extra" bits will be zero. Therefore, it is safe to remove the SUBREG. it is known that the "extra" bits will be the same in op0 and op1 or
We can never remove a SUBREG for a non-equality comparison because the that they don't matter. There are three cases to consider:
sign bit is in a different place in the underlying object. */
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); op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
op1 = make_compound_operation (op1, SET); op1 = make_compound_operation (op1, SET);
if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0) 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 (op0)) == MODE_INT
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
&& (code == NE || code == EQ) && (code == NE || code == EQ))
&& ((GET_MODE_SIZE (GET_MODE (op0)) {
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))) if (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
{ {
op0 = SUBREG_REG (op0); op0 = SUBREG_REG (op0);
op1 = gen_lowpart_for_combine (GET_MODE (op0), op1); op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
} }
else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
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) <= HOST_BITS_PER_WIDE_INT)
&& (nonzero_bits (SUBREG_REG (op0), GET_MODE (SUBREG_REG (op0))) && (nonzero_bits (SUBREG_REG (op0),
& ~GET_MODE_MASK (GET_MODE (op0))) == 0 GET_MODE (SUBREG_REG (op0)))
&& (tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
op1), {
(nonzero_bits (tem, GET_MODE (SUBREG_REG (op0))) tem = gen_lowpart_for_combine (GET_MODE (SUBREG_REG (op0)), op1);
& ~GET_MODE_MASK (GET_MODE (op0))) == 0))
if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
& ~GET_MODE_MASK (GET_MODE (op0))) == 0)
op0 = SUBREG_REG (op0), op1 = tem; op0 = SUBREG_REG (op0), op1 = tem;
}
}
/* We now do the opposite procedure: Some machines don't have compare /* 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 insns in all modes. If OP0's mode is an integer mode smaller than a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment