[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