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]

Re: [PATCH] Improve simplify_subreg


On Thu, May 02, 2013 at 06:53:31PM +0100, Richard Sandiford wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> > When working on PR57130, I've wondered why we don't simplify it much earlier
> > and end up with creating such weirdness.
> >
> > The following patch fixes that, by using nonzero_bits to see if all the low
> > bits must be zero and in that case just return zero.
> >
> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> >
> > 2013-05-02  Jakub Jelinek  <jakub@redhat.com>
> >
> > 	* simplify-rtx.c (simplify_truncation): If nonzero_bits
> > 	on op shows all bits zero in mode, return zero.
> 
> I'm probably wrong, but just in case: it looks like this might
> fall foul of:
> 
> /* Try to simplify a MODE truncation of OP, which has OP_MODE.
>    Only handle cases where the truncated value is inherently an rvalue.
> 
> If op is a register, it might be being used as an lvalue instead of an rvalue.
> We don't want to simplify (subreg (reg ..)) to (const_int 0) in that case.
> 
> It should be OK to put this under the TRUNCATE case in
> simplify_unary_operation_1, but I don't know if that'd be good
> enough for your testcase.

I understand, if simplify_subreg would be called on LHS, that would be a bad
transformation.  Unfortunately, simplify_rtx isn't called on the testcase
and there isn't a TRUNCATE, just a SUBREG, so simplify_unary_operation_1
wouldn't be the right spot for it anyway.

What about this?  Is combine_simplify_rtx only called on rvalues?

This improves the *.combine dump on the testcase too.

Bootstrapped/regtested on x86_64-linux and i686-linux.

2013-05-03  Jakub Jelinek  <jakub@redhat.com>

	* combine.c (combine_simplify_rtx) <case SUBREG>: If nonzero_bits
	on op shows all bits zero in mode of a lowpart subreg, return zero.

--- gcc/combine.c.jj	2013-05-03 14:55:32.000000000 +0200
+++ gcc/combine.c	2013-05-03 15:46:31.923323029 +0200
@@ -5417,6 +5417,16 @@ combine_simplify_rtx (rtx x, enum machin
 				SUBREG_BYTE (x));
 	if (temp)
 	  return temp;
+
+	/* If op is known to have all lower bits zero, the result is zero.  */
+	if (SCALAR_INT_MODE_P (mode)
+	    && SCALAR_INT_MODE_P (op0_mode)
+	    && GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (op0_mode)
+	    && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x)
+	    && HWI_COMPUTABLE_MODE_P (op0_mode)
+	    && (nonzero_bits (SUBREG_REG (x), op0_mode)
+		& GET_MODE_MASK (mode)) == 0)
+	  return CONST0_RTX (mode);
       }
 
       /* Don't change the mode of the MEM if that would change the meaning


	Jakub


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