This is the mail archive of the
mailing list for the GCC project.
Regression introduced by your change
- From: Jeffrey A Law <law at redhat dot com>
- To: roger at eyesopen dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Thu, 02 Mar 2006 12:03:53 -0700
- Subject: Regression introduced by your change
- Reply-to: law at redhat dot com
2006-02-17 Roger Sayle <email@example.com>
* fold-const.c (fold_binary): Fold (X >> C) != 0 into X < 0 when
C is one less than the width of X (and related transformations).
* simplify-rtx.c (simplify_unary_operation_1): Transform
(neg (lt x 0)) into either (ashiftrt X C) or (lshiftrt X C)
depending on STORE_FLAG_VALUE, were C is one less then the
width of X.
Is causing 961206-1.c to regress at -O1 and -O2 on i686-pc-linux-gnu
and possibly other platforms.
The fundamental problem as I can see it is that it assumes
that the mode passed into simplify_unary_operation_1 is the
mode in which the shift should be performed, which is not
For example, if subst creates something like this:
(not:QI (subreg:QI (if_then_else:SI (ge (subreg:SI (reg/v:DI 59 [ i ])
(const_int 0 [0x0]))
(const_int -1 [0xffffffff])
(const_int 0 [0x0])) 0))
We pass that down to combine_simplify_rtx which extracts the mode
of the toplevel expression (QImode in this case) and stuffs the
value into MODE which we pass down to simplify_gen_unary.
In simplify_gen_unary we have:
code = NEG
mode = QImode
op = (lt:QI (subreg:SI (reg/v:DI 59 [ i ]) 0)
(const_int 0 [0x0]))
op0_mode = QImode
[ Note that the QImode attached to the LT is bogus, in general we
should not have modes on comparisons like that. For the purposes
of this problem it is not really relevant. ]
So far, so good.
We pass those down to simplify_unary_operation_1 (except op0_mode)
unchanged. At which time we fall into your newly added code
(ashiftrt:QI (subreg:SI (reg/v:DI 59 [ i ]) 0)
(const_int 7 [0x7]))
OUCH. Instead of testing bit 31, we test bit 7.
It seems to me that we need to emit the shift in the mode of
the comparison's first operand. Then convert the result of the
shift into the desired mode via a subreg or something along