Attached patch fixes a corner case in STV pass where the shift operand register equals shift count register. The specialization for shift insns marked register as processed, but didn't process shift input operand, leaving an unprocessed DImode register.
2019-03-26 Uroš Bizjak <ubiz...@gmail.com> PR target/89827 * config/i386/i386.c (dimode_scalar_chain::convert_reg): Also process XEXP (src, 0) of a shift insn. testsuite/ChangeLog: 2019-03-26 Uroš Bizjak <ubiz...@gmail.com> PR target/89827 * gcc.target/i386/pr89827.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN, will be backported to gcc-8 branch. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 269950) +++ config/i386/i386.c (working copy) @@ -2040,6 +2040,7 @@ dimode_scalar_chain::convert_reg (unsigned regno) emit_insn_before (seq, insn); + XEXP (src, 0) = replace_with_subreg (XEXP (src, 0), reg, reg); XEXP (src, 1) = gen_rtx_SUBREG (DImode, tmp2, 0); } else if (!MEM_P (dst) || !REG_P (src)) Index: testsuite/gcc.target/i386/pr89827.c =================================================================== --- testsuite/gcc.target/i386/pr89827.c (nonexistent) +++ testsuite/gcc.target/i386/pr89827.c (working copy) @@ -0,0 +1,11 @@ +/* PR target/89827 */ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2 -msse2 -mstv -mno-stackrealign" } */ + +unsigned long long a; + +void +foo (void) +{ + a >>= (unsigned short) a; +}