This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Trim surplus zero extends
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 23 Mar 2002 00:59:48 +1030
- Subject: Trim surplus zero extends
This test case:
void foo (unsigned char *p)
{
unsigned long i;
if (p[0] != 0xff)
for (i = 1; i <= p[0]; i++)
p[i] = 0;
}
generates code with an unnecessary zero extend on powerpc64-linux
(also powerpc-linux if using "unsigned long long i", which is a
regression from 2.95 and 3.0).
.foo:
lbz 11,0(3) # zero extended byte
rlwinm 0,11,0,0xff # not needed
cmpwi 0,0,255
[snip]
I guess this problem was introduced when all CONST_INTs became sign
extended.
* combine.c (simplify_comparison): When widening modes, ignore
sign extension on CONST_INTs.
OK for mainline and branch? Currently bootstrapping 3.1 powerpc-linux.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
diff -urpN -xCVS -x*~ gcc-3.1/gcc/combine.c gcc-3.1-patched/gcc/combine.c
--- gcc-3.1/gcc/combine.c Mon Mar 11 19:28:51 2002
+++ gcc-3.1-patched/gcc/combine.c Sat Mar 23 00:48:52 2002
@@ -10970,14 +10970,22 @@ simplify_comparison (code, pop0, pop1)
tmode = GET_MODE_WIDER_MODE (tmode))
if (have_insn_for (COMPARE, tmode))
{
+ int zero_extended;
+
/* If the only nonzero bits in OP0 and OP1 are those in the
narrower mode and this is an equality or unsigned comparison,
we can use the wider mode. Similarly for sign-extended
values, in which case it is true for all comparisons. */
- if (((code == EQ || code == NE
- || code == GEU || code == GTU || code == LEU || code == LTU)
- && (nonzero_bits (op0, tmode) & ~GET_MODE_MASK (mode)) == 0
- && (nonzero_bits (op1, tmode) & ~GET_MODE_MASK (mode)) == 0)
+ zero_extended = ((code == EQ || code == NE
+ || code == GEU || code == GTU
+ || code == LEU || code == LTU)
+ && (nonzero_bits (op0, tmode)
+ & ~GET_MODE_MASK (mode)) == 0
+ && ((GET_CODE (op1) == CONST_INT
+ || (nonzero_bits (op1, tmode)
+ & ~GET_MODE_MASK (mode)) == 0)));
+
+ if (zero_extended
|| ((num_sign_bit_copies (op0, tmode)
> GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode))
&& (num_sign_bit_copies (op1, tmode)
@@ -10994,6 +10999,8 @@ simplify_comparison (code, pop0, pop1)
XEXP (op0, 1)));
op0 = gen_lowpart_for_combine (tmode, op0);
+ if (zero_extended && GET_CODE (op1) == CONST_INT)
+ op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
op1 = gen_lowpart_for_combine (tmode, op1);
break;
}