Hi! Ths chunk of code wants to expand 16-bit rotate by 8 as bswaphi, but if mode is a vector mode (or complex mode), trying to use bswaphi pattern to swap say V16HImode vector is just wrong.
This patch arranges to use bswapv16hi etc. instead in those cases, which isn't 100% clear to me from the docs if they only swap bytes of each of the vector element, but from looking at a few backends it seems like that is the case and if it wasn't, e.g. simplify-rtx.c would missimplify stuff. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-12-30 Jakub Jelinek <ja...@redhat.com> PR middle-end/83623 * expmed.c (expand_shift_1): For 2-byte rotates by BITS_PER_UNIT, check for bswap in mode rather than HImode and use that in expand_unop too. * gcc.dg/pr83623.c: New test. --- gcc/expmed.c.jj 2017-12-20 20:40:18.000000000 +0100 +++ gcc/expmed.c 2017-12-30 11:44:47.045433528 +0100 @@ -2490,9 +2490,8 @@ expand_shift_1 (enum tree_code code, mac && CONST_INT_P (op1) && INTVAL (op1) == BITS_PER_UNIT && GET_MODE_SIZE (scalar_mode) == 2 - && optab_handler (bswap_optab, HImode) != CODE_FOR_nothing) - return expand_unop (HImode, bswap_optab, shifted, NULL_RTX, - unsignedp); + && optab_handler (bswap_optab, mode) != CODE_FOR_nothing) + return expand_unop (mode, bswap_optab, shifted, NULL_RTX, unsignedp); if (op1 == const0_rtx) return shifted; --- gcc/testsuite/gcc.dg/pr83623.c.jj 2017-12-30 11:49:23.259470538 +0100 +++ gcc/testsuite/gcc.dg/pr83623.c 2017-12-30 11:49:01.309467592 +0100 @@ -0,0 +1,12 @@ +/* PR middle-end/83623 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mmovbe" { target i?86-*-* x86_64-*-* } } */ + +unsigned short __attribute__ ((__vector_size__ (16))) x; + +void +foo (void) +{ + x = x << 8 | x >> 8; +} Jakub