[PATCH] Simplify more non-paradoxical subregs in simplify_comparison
Ulrich Weigand
weigand@i1.informatik.uni-erlangen.de
Tue Jul 22 19:19:00 GMT 2003
Hello,
on s390x we're seeing sub-optimal code generation in some cases because
combine often tends to generate RTL like this for bit-tests:
(compare (subreg:SI (zero_extract:DI (subreg:DI (reg:SI ...))
(const_int 1)
(const_int ...)) 4)
(const_int 0))
(The subregs are apparently there because zero_extract:SI is not valid
on a platform with DImode word size.)
However, the simplifier should be able to reduce this to
(compare (zero_extract:DI (subreg:DI (reg:SI ...))
(const_int 1)
(const_int ...))
(const_int 0))
(which would actually match a TEST UNDER MASK pattern in s390.md).
In fact, there's code in simplify_comparison that used to do that,
but it was disabled by what appears to be an overly conservative
test introduced by this patch:
http://gcc.gnu.org/ml/gcc-patches/2002-04/msg00066.html
Note the the problem fixed by this patch was caused by the peculiar
semantics of *paradoxical* subregs, but the patch actually changed
the handling of non-paradoxical subregs as well.
The following patch restores the handling of non-paradoxical
subregs (to allow the simplifcation above to proceed), without
changing the handling of paradoxical subregs.
Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.
OK?
ChangeLog:
* combine.c (simplify_comparison): Re-enable widening of comparisons
with non-paradoxical subregs of non-REG expressions.
Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.373
diff -c -p -r1.373 combine.c
*** gcc/combine.c 19 Jul 2003 14:47:00 -0000 1.373
--- gcc/combine.c 22 Jul 2003 16:11:57 -0000
*************** simplify_comparison (enum rtx_code code,
*** 11274,11282 ****
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))
--- 11274,11279 ----
*************** simplify_comparison (enum rtx_code code,
*** 11284,11291 ****
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)
--- 11281,11293 ----
if (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
{
! /* For paradoxical subregs, allow case 1 as above. Case 3 isn't
! implemented. */
! if (GET_CODE (SUBREG_REG (op0)) == REG)
! {
! 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)
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de
More information about the Gcc-patches
mailing list