The following fixes PR91469 where STV replaced uses inside address expressions. The issue arises here because convert_regs is called before convert_insns which eventually splits out memory operands.
Bootstrapped / tested on x86_64-unknown-linux-gnu, OK? Thanks, Richard. 2019-08-16 Richard Biener <rguent...@suse.de> PR target/91469 * config/i386/i386-features.c (general_scalar_chain::replace_with_subreg): Stop at memory operands. * gcc.target/i386/pr91469-1.c: New testcase. * gcc.target/i386/pr91469-2.c: Likewise. Index: gcc/config/i386/i386-features.c =================================================================== --- gcc/config/i386/i386-features.c (revision 274536) +++ gcc/config/i386/i386-features.c (working copy) @@ -613,6 +613,10 @@ general_scalar_chain::replace_with_subre if (x == reg) return gen_rtx_SUBREG (vmode, new_reg, 0); + /* But not in memory addresses. */ + if (MEM_P (x)) + return x; + const char *fmt = GET_RTX_FORMAT (GET_CODE (x)); int i, j; for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) Index: gcc/testsuite/gcc.target/i386/pr91469-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr91469-1.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr91469-1.c (working copy) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-funroll-loops -O2 -fno-gcse -mavx512vbmi -fno-ivopts -mstv" } */ + +int a, b, e; +long long c; +int d[6]; + +void fn1() { + int i; + unsigned f; + c = a; + f = i; + for (; i < b; i++) + if (d[i] > f) + f = d[i]; + e = f; +} Index: gcc/testsuite/gcc.target/i386/pr91469-2.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr91469-2.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr91469-2.c (working copy) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-Os --param scev-max-expr-size=0 -mavx512vnni -funroll-all-loops" } */ + +int a, b, c, d; +int *e; +void fn1() +{ + b = c > 0 ? c : 0; + d += e[b]; + a = d > 0 ? d : 0; +}