Message ID | 20130503171323.GE28963@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
Jakub Jelinek <jakub@redhat.com> writes: > 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? Both lvalues and rvalues I think, but at least in_dest says which. The patch looks good to me with an "&& !in_dest". Thanks, Richard
--- 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