expansion of vector shifts...
Richard Sandiford
rdsandiford@googlemail.com
Mon Oct 29 10:18:00 GMT 2012
David Miller <davem@davemloft.net> writes:
> On sparc a simple test like (from the PR tree-optimization/53410 testcase):
>
> ====================
> typedef int V __attribute__((vector_size (4 * sizeof (int))));
> typedef unsigned int W __attribute__((vector_size (4 * sizeof (int))));
>
> void
> f10 (W *p, W *q)
> {
> *p = *p < (((const W) { 1U, 1U, 1U, 1U }) << *q);
> }
> ====================
>
> aborts in convert_move() because we're trying to move a TImode value
> into a V2SImode one. How does that happen?
>
> On sparc the generic tree vector layer turns the above expression into
> two V2SImode shifts. The *q parts of each shift are represented as:
>
> (subreg:V2SI (reg:TI xxx) 0)
> (subreg:V2SI (reg:TI xxx) 8)
>
> When we get down into expand_shift_1(), that SUBREG is stripped out by
> the SHIFT_COUNT_TRUNCATED code, and that's how we end up in the crash
> by the time we reach convert_move() (via expand_binop() -->
> expand_binop_directly() --> convert_modes() --> convert_move()).
>
> Perhaps we should elide the SUBREG stripping if the subreg has a
> vector mode?
Agreed, although...
> Actually, what seems to confuse this code is that we're passing
> TImode values around for this vector that the target doesn't have
> direct support for. The SUBREG stripper explicitly checks for
> INTEGRAL_MODE_P, and indeed TImode is integral.
...given that the code is like you say written:
if (SHIFT_COUNT_TRUNCATED)
{
if (CONST_INT_P (op1)
...
else if (GET_CODE (op1) == SUBREG
&& subreg_lowpart_p (op1)
&& INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (op1))))
op1 = SUBREG_REG (op1);
}
INTEGRAL_MODE_P (GET_MODE (op1)) might be better than an explicit
VECTOR_MODE_P check. The code really doesn't make sense for anything
other than integers.
(It amounts to the same thing in practice, of course...)
Richard
More information about the Gcc
mailing list