]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Use the proper mode for blend in vshuffle.
authorRichard Henderson <rth@redhat.com>
Thu, 6 Oct 2011 17:12:44 +0000 (10:12 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 6 Oct 2011 17:12:44 +0000 (10:12 -0700)
From-SVN: r179625

gcc/ChangeLog
gcc/config/i386/i386.c

index 89905f5b7279bb3bbc317682cd151b4ab833c86e..19516c0a649781c3a44d5895606c39e8c4f8bf67 100644 (file)
@@ -7,6 +7,12 @@
        (vshuffle<mode>): Use it.
        (avx_vec_concat<V_256>): Rename from *vec_concat<V_256>_avx.
 
+       * config/i386/i386.c (ix86_expand_sse_movcc): Use correct mode
+       for vector_all_ones_operand.
+       (ix86_expand_int_vcond): Distinguish between comparison mode
+       and data mode.  Allow them to differ.
+       (ix86_expand_vshuffle): Don't force data mode to match maskmode.
+
 2001-10-06  Richard Henderson  <rth@redhat.com>
 
        * optabs.c (expand_vec_shuffle_expr): Use the proper mode for the
index 9960fd29ee607a1920f194d60a9095b152de701e..2fdf540526064af938b98001da648faba6315573 100644 (file)
@@ -18941,7 +18941,7 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
   enum machine_mode mode = GET_MODE (dest);
   rtx t2, t3, x;
 
-  if (vector_all_ones_operand (op_true, GET_MODE (op_true))
+  if (vector_all_ones_operand (op_true, mode)
       && rtx_equal_p (op_false, CONST0_RTX (mode)))
     {
       emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
@@ -19170,7 +19170,8 @@ ix86_expand_fp_vcond (rtx operands[])
 bool
 ix86_expand_int_vcond (rtx operands[])
 {
-  enum machine_mode mode = GET_MODE (operands[0]);
+  enum machine_mode data_mode = GET_MODE (operands[0]);
+  enum machine_mode mode = GET_MODE (operands[4]);
   enum rtx_code code = GET_CODE (operands[3]);
   bool negate = false;
   rtx x, cop0, cop1;
@@ -19297,8 +19298,21 @@ ix86_expand_int_vcond (rtx operands[])
        }
     }
 
-  x = ix86_expand_sse_cmp (operands[0], code, cop0, cop1,
-                          operands[1+negate], operands[2-negate]);
+  /* Allow the comparison to be done in one mode, but the movcc to
+     happen in another mode.  */
+  if (data_mode == mode)
+    {
+      x = ix86_expand_sse_cmp (operands[0], code, cop0, cop1,
+                              operands[1+negate], operands[2-negate]);
+    }
+  else
+    {
+      gcc_assert (GET_MODE_SIZE (data_mode) == GET_MODE_SIZE (mode));
+      x = ix86_expand_sse_cmp (gen_lowpart (mode, operands[0]),
+                              code, cop0, cop1,
+                              operands[1+negate], operands[2-negate]);
+      x = gen_lowpart (data_mode, x);
+    }
 
   ix86_expand_sse_movcc (operands[0], x, operands[1+negate],
                         operands[2-negate]);
@@ -19533,9 +19547,9 @@ ix86_expand_vshuffle (rtx operands[])
       mask = expand_simple_binop (maskmode, AND, mask, vt,
                                  NULL_RTX, 0, OPTAB_DIRECT);
 
-      xops[0] = gen_lowpart (maskmode, operands[0]);
-      xops[1] = gen_lowpart (maskmode, t2);
-      xops[2] = gen_lowpart (maskmode, t1);
+      xops[0] = operands[0];
+      xops[1] = gen_lowpart (mode, t2);
+      xops[2] = gen_lowpart (mode, t1);
       xops[3] = gen_rtx_EQ (maskmode, mask, vt);
       xops[4] = mask;
       xops[5] = vt;