This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/RFA] Correct setting of fuller_mask in force_to_mode()


As I discussed here:
    http://gcc.gnu.org/ml/gcc/2003-09/msg00427.html
the variable fuller_mask does not appear to be set correctly in
force_to_mode().  The effect is some minor missed optimizations.  Here
is a patch.

For this test case:

int f(int a, int b) { return ((a & 0xff) + (b & 0xff)) & 0xff; }

compiled on the ARM with -O, the current compiler produces this:

	and	r0, r0, #255
	and	r1, r1, #255
	add	r0, r0, r1
	and	r0, r0, #255
	bx	lr

With the appended patch, the compiler produces this:

	add	r1, r1, r0
	and	r0, r1, #255
	bx	lr

I've appended the patch and a test case.

Tested by bootstraping and running the gcc testsuite on
i686-pc-linux-gnu.

OK for mainline?

Ian


2003-09-09  Ian Lance Taylor  <ian@wasabisystems.com>

	* combine.c (force_to_mode): Set fuller_mask based only on mask,
	not op_mode.


Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.384
diff -c -p -r1.384 combine.c
*** combine.c	7 Sep 2003 20:32:16 -0000	1.384
--- combine.c	9 Sep 2003 22:00:30 -0000
*************** force_to_mode (rtx x, enum machine_mode 
*** 6833,6847 ****
      mask &= GET_MODE_MASK (op_mode);
  
    /* When we have an arithmetic operation, or a shift whose count we
!      do not know, we need to assume that all bit the up to the highest-order
       bit in MASK will be needed.  This is how we form such a mask.  */
!   if (op_mode)
!     fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
! 		   ? GET_MODE_MASK (op_mode)
! 		   : (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
! 		      - 1));
    else
!     fuller_mask = ~(HOST_WIDE_INT) 0;
  
    /* Determine what bits of X are guaranteed to be (non)zero.  */
    nonzero = nonzero_bits (x, mode);
--- 6833,6845 ----
      mask &= GET_MODE_MASK (op_mode);
  
    /* When we have an arithmetic operation, or a shift whose count we
!      do not know, we need to assume that all bits up to the highest-order
       bit in MASK will be needed.  This is how we form such a mask.  */
!   if (mask & ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)))
!     fuller_mask = ~(unsigned HOST_WIDE_INT) 0;
    else
!     fuller_mask = (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
! 		   - 1);
  
    /* Determine what bits of X are guaranteed to be (non)zero.  */
    nonzero = nonzero_bits (x, mode);


2003-09-09  Ian Lance Taylor  <ian@wasabisystems.com>

	* gcc.dg/20030909-1.c: New test.


Index: testsuite/gcc.dg/20030909-1.c
===================================================================
RCS file: testsuite/gcc.dg/20030909-1.c
diff -N testsuite/gcc.dg/20030909-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/20030909-1.c	9 Sep 2003 20:16:32 -0000
@@ -0,0 +1,5 @@
+/* Verify that ands are combined.  */
+/* { dg-do compile { target arm*-*-* strongarm*-*-* xscale*-*-* } } */
+/* { dg-options "-O" } */
+/* { dg-final { scan-assembler-not "#255.*#255" } } */
+int f(int a, int b) { return ((a & 0xff) + (b & 0xff)) & 0xff; }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]