David Miller <da...@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