Hi! This weird hink has been added by Alex in r228175, it isn't clear why nor how it ever can be correct. While say for DECL_MODE we have the problem that for global vars when switching between functions with different ISA selections the mode might not be ok, TYPE_MODE is stored as a raw vector mode that a function overrides to BLKmode if that particular vector mode is not supported. This hunk breaks that assumption and leaks unsupported vector modes in the IL of the functions which then have no way to handle that, but even before that happens usually it breaks because we try to convert_mode between BLKmode and the unsupported vector mode or vice versa on PHI nodes.
Alex, do you remember why this has been done? Patch has been bootstrapped/regtested on x86_64-linux and i686-linux (the latter didn't have SSE enabled by default), Jeff said he'll test it on many crosses. Ok for trunk if that testing succeeds? 2019-07-03 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/90756 * explow.c (promote_ssa_mode): Always use TYPE_MODE, don't bypass it for VECTOR_TYPE_P. * gcc.dg/pr90756.c: New test. --- gcc/explow.c.jj 2019-06-26 13:51:54.289358743 +0200 +++ gcc/explow.c 2019-07-02 20:32:11.318360013 +0200 @@ -892,16 +892,7 @@ promote_ssa_mode (const_tree name, int * tree type = TREE_TYPE (name); int unsignedp = TYPE_UNSIGNED (type); - machine_mode mode = TYPE_MODE (type); - - /* Bypass TYPE_MODE when it maps vector modes to BLKmode. */ - if (mode == BLKmode) - { - gcc_assert (VECTOR_TYPE_P (type)); - mode = type->type_common.mode; - } - - machine_mode pmode = promote_mode (type, mode, &unsignedp); + machine_mode pmode = promote_mode (type, TYPE_MODE (type), &unsignedp); if (punsignedp) *punsignedp = unsignedp; --- gcc/testsuite/gcc.dg/pr90756.c.jj 2019-07-02 20:30:17.651131684 +0200 +++ gcc/testsuite/gcc.dg/pr90756.c 2019-07-02 20:29:49.038574696 +0200 @@ -0,0 +1,26 @@ +/* PR rtl-optimization/90756 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wno-psabi" } */ +/* { dg-additional-options "-mno-sse" { target ia32 } } */ + +typedef float B __attribute__((vector_size(4 * sizeof (float)))); +typedef unsigned long long C __attribute__((vector_size(4 * sizeof (long long)))); +typedef short D __attribute__((vector_size(4 * sizeof (short)))); +B z; +void foo (C); +C bar (D); +B baz (); +D qux (B); + +void +quux (int x) +{ + B n = z, b = z; + while (1) + switch (x) + { + case 0: n = baz (); /* FALLTHRU */ + case 1: { B o = n; n = b; b = o; } /* FALLTHRU */ + case 2: { D u = qux (b); C v = bar (u); foo (v); } + } +} Jakub