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? 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.