diff mbox

[i386] : Fix PR 80019, ICE in ix86_vector_duplicate_value

Message ID CAFULd4YJp02YCL0xpBkoXr-GsN7XyT-nN19EQDw14BAMd6xLmA@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak March 15, 2017, 1:41 p.m. UTC
2017-03-15  Uros Bizjak  <ubizjak@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  <ubizjak@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.
diff mbox

Patch

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;
+}