Hi! As mentioned in the PR, both instructions this expander uses use register_mmxmem_operand predicate in the operands operands[2] and [3] are passed to, and register_mmxmem_operand is for TARGET_MMX_WITH_SSE just register_operand. Thus, the following patch adjusts the expander's predicates to match that.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk as obvious. 2019-08-10 Jakub Jelinek <ja...@redhat.com> PR target/91408 * config/i386/mmx.md (usadv8qi): Use register_operand instead of vector_operand. * gcc.target/i386/pr91408.c: New test. --- gcc/config/i386/mmx.md.jj 2019-08-05 09:58:10.120454205 +0200 +++ gcc/config/i386/mmx.md 2019-08-09 09:49:09.933071645 +0200 @@ -1973,8 +1973,8 @@ (define_expand "reduc_plus_scal_v8qi" (define_expand "usadv8qi" [(match_operand:V2SI 0 "register_operand") (match_operand:V8QI 1 "register_operand") - (match_operand:V8QI 2 "vector_operand") - (match_operand:V2SI 3 "vector_operand")] + (match_operand:V8QI 2 "register_operand") + (match_operand:V2SI 3 "register_operand")] "TARGET_MMX_WITH_SSE" { rtx t1 = gen_reg_rtx (V1DImode); --- gcc/testsuite/gcc.target/i386/pr91408.c.jj 2019-08-09 09:52:08.357389049 +0200 +++ gcc/testsuite/gcc.target/i386/pr91408.c 2019-08-09 09:51:40.217812123 +0200 @@ -0,0 +1,29 @@ +/* PR target/91408 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-vectorize -fno-tree-forwprop" } */ + +long long a; +unsigned char b; +short *c; +int d; + +void +foo (long long *x) +{ + unsigned char *e = (char *) x; + int f, g = 0; + for (d = 0; d < 8; d++) + { + f = b - e[d]; + if (f < 0) + f = -f; + g += f; + } + c[0] = g; +} + +void +bar (void) +{ + foo (&a); +} Jakub