2017-03-15 Uros Bizjak <ubiz...@gmail.com> PR target/80019 * config/i386/i386.c (ix86_vector_duplicate_value): Create subreg of inner mode for values already in registers.
testsuite/ChangeLog: 2017-03-15 Uros Bizjak <ubiz...@gmail.com> PR target/80019 * gcc.target/i386/pr80019.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline, will be backported to other release branches. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 246156) +++ config/i386/i386.c (working copy) @@ -42571,10 +42571,16 @@ ix86_vector_duplicate_value (machine_mode mode, rt if (recog_memoized (insn) < 0) { rtx_insn *seq; + machine_mode innermode = GET_MODE_INNER (mode); + rtx reg; + /* If that fails, force VAL into a register. */ start_sequence (); - XEXP (dup, 0) = force_reg (GET_MODE_INNER (mode), val); + reg = force_reg (innermode, val); + if (GET_MODE (reg) != innermode) + reg = gen_lowpart (innermode, reg); + XEXP (dup, 0) = reg; seq = get_insns (); end_sequence (); if (seq) Index: testsuite/gcc.target/i386/pr80019.c =================================================================== --- testsuite/gcc.target/i386/pr80019.c (nonexistent) +++ testsuite/gcc.target/i386/pr80019.c (working copy) @@ -0,0 +1,13 @@ +/* PR target/80019 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mxop -mavx2" } */ + +typedef char v16qi __attribute__ ((vector_size (16))); + +extern v16qi b, c; + +void +foo (int e) +{ + b = c << e; +}