]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/70799 (STV pass does not convert DImode shifts)
authorIlya Enkovich <ilya.enkovich@intel.com>
Tue, 10 May 2016 16:08:42 +0000 (16:08 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Tue, 10 May 2016 16:08:42 +0000 (16:08 +0000)
gcc/

PR target/70799
* config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Allow
integer constants.
(dimode_scalar_chain::vector_const_cost): New.
(dimode_scalar_chain::compute_convert_gain): Handle constants.
(dimode_scalar_chain::convert_op): Likewise.
(dimode_scalar_chain::convert_insn): Likewise.

gcc/testsuite/

PR target/70799
* gcc.target/i386/pr70799-1.c: New test.

From-SVN: r236090

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr70799-1.c [new file with mode: 0644]

index 562d303ca6abffe4c6e033c196e62b69ad432cc0..a2257cea32ced016672a1cac6ebab775e6e1ec1a 100644 (file)
@@ -1,3 +1,13 @@
+2016-05-10  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       PR target/70799
+       * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Allow
+       integer constants.
+       (dimode_scalar_chain::vector_const_cost): New.
+       (dimode_scalar_chain::compute_convert_gain): Handle constants.
+       (dimode_scalar_chain::convert_op): Likewise.
+       (dimode_scalar_chain::convert_insn): Likewise.
+
 2016-05-10  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        * dwarf2out.c (resolve_args_picking_1): Consider DW_OP_neg as an
index 05476f37449e932e6441949343c39186a62b4a3c..530a6e84a0c2e196aa6b83635a89f039749d534c 100644 (file)
@@ -2789,7 +2789,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
     return convertible_comparison_p (insn);
 
   /* We are interested in DImode promotion only.  */
-  if (GET_MODE (src) != DImode
+  if ((GET_MODE (src) != DImode
+       && !CONST_INT_P (src))
       || GET_MODE (dst) != DImode)
     return false;
 
@@ -2809,24 +2810,31 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
       return true;
 
     case MEM:
+    case CONST_INT:
       return REG_P (dst);
 
     default:
       return false;
     }
 
-  if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0))
+  if (!REG_P (XEXP (src, 0))
+      && !MEM_P (XEXP (src, 0))
+      && !CONST_INT_P (XEXP (src, 0))
       /* Check for andnot case.  */
       && (GET_CODE (src) != AND
          || GET_CODE (XEXP (src, 0)) != NOT
          || !REG_P (XEXP (XEXP (src, 0), 0))))
       return false;
 
-  if (!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
+  if (!REG_P (XEXP (src, 1))
+      && !MEM_P (XEXP (src, 1))
+      && !CONST_INT_P (XEXP (src, 1)))
       return false;
 
-  if (GET_MODE (XEXP (src, 0)) != DImode
-      || GET_MODE (XEXP (src, 1)) != DImode)
+  if ((GET_MODE (XEXP (src, 0)) != DImode
+       && !CONST_INT_P (XEXP (src, 0)))
+      || (GET_MODE (XEXP (src, 1)) != DImode
+         && !CONST_INT_P (XEXP (src, 1))))
     return false;
 
   return true;
@@ -3120,6 +3128,7 @@ class dimode_scalar_chain : public scalar_chain
   void convert_reg (unsigned regno);
   void make_vector_copies (unsigned regno);
   void convert_registers ();
+  int vector_const_cost (rtx exp);
 };
 
 class timode_scalar_chain : public scalar_chain
@@ -3328,6 +3337,19 @@ scalar_chain::build (bitmap candidates, unsigned insn_uid)
   BITMAP_FREE (queue);
 }
 
+/* Return a cost of building a vector costant
+   instead of using a scalar one.  */
+
+int
+dimode_scalar_chain::vector_const_cost (rtx exp)
+{
+  gcc_assert (CONST_INT_P (exp));
+
+  if (standard_sse_constant_p (exp, V2DImode))
+    return COSTS_N_INSNS (1);
+  return ix86_cost->sse_load[1];
+}
+
 /* Compute a gain for chain conversion.  */
 
 int
@@ -3359,11 +3381,25 @@ dimode_scalar_chain::compute_convert_gain ()
               || GET_CODE (src) == IOR
               || GET_CODE (src) == XOR
               || GET_CODE (src) == AND)
-       gain += ix86_cost->add;
+       {
+         gain += ix86_cost->add;
+         if (CONST_INT_P (XEXP (src, 0)))
+           gain -= vector_const_cost (XEXP (src, 0));
+         if (CONST_INT_P (XEXP (src, 1)))
+           gain -= vector_const_cost (XEXP (src, 1));
+       }
       else if (GET_CODE (src) == COMPARE)
        {
          /* Assume comparison cost is the same.  */
        }
+      else if (GET_CODE (src) == CONST_INT)
+       {
+         if (REG_P (dst))
+           gain += COSTS_N_INSNS (2);
+         else if (MEM_P (dst))
+           gain += 2 * ix86_cost->int_store[2] - ix86_cost->sse_store[1];
+         gain -= vector_const_cost (src);
+       }
       else
        gcc_unreachable ();
     }
@@ -3639,6 +3675,24 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
          }
       *op = gen_rtx_SUBREG (V2DImode, *op, 0);
     }
+  else if (CONST_INT_P (*op))
+    {
+      rtx vec_cst;
+      rtx tmp = gen_rtx_SUBREG (V2DImode, gen_reg_rtx (DImode), 0);
+
+      /* Prefer all ones vector in case of -1.  */
+      if (constm1_operand (*op, GET_MODE (*op)))
+       vec_cst = CONSTM1_RTX (V2DImode);
+      else
+       vec_cst = gen_rtx_CONST_VECTOR (V2DImode,
+                                       gen_rtvec (2, *op, const0_rtx));
+
+      if (!standard_sse_constant_p (vec_cst, V2DImode))
+       vec_cst = validize_mem (force_const_mem (V2DImode, vec_cst));
+
+      emit_insn_before (gen_move_insn (tmp, vec_cst), insn);
+      *op = tmp;
+    }
   else
     {
       gcc_assert (SUBREG_P (*op));
@@ -3711,6 +3765,10 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
                            UNSPEC_PTEST);
       break;
 
+    case CONST_INT:
+      convert_op (&src, insn);
+      break;
+
     default:
       gcc_unreachable ();
     }
index 36b8e2f926d21940e39031cd703783a87bc33718..7ab92a51390ca6bb35b929458cb64e879d6917ca 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-10  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       PR target/70799
+       * gcc.target/i386/pr70799-1.c: New test.
+
 2016-05-10  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        * gnat.dg/debug6.adb, gnat.dg/debug6_pkg.ads: New testcase.
diff --git a/gcc/testsuite/gcc.target/i386/pr70799-1.c b/gcc/testsuite/gcc.target/i386/pr70799-1.c
new file mode 100644 (file)
index 0000000..0abbfb9
--- /dev/null
@@ -0,0 +1,41 @@
+/* PR target/pr70799 */
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O2 -march=slm" } */
+/* { dg-final { scan-assembler "pxor" } } */
+/* { dg-final { scan-assembler "pcmpeqd" } } */
+/* { dg-final { scan-assembler "movdqa\[ \\t\]+.LC0" } } */
+
+long long a, b, c;
+
+void test1 (void)
+{
+  long long t;
+  if (a)
+    t = 0LL;
+  else
+    t = b;
+  a = c & t;
+  b = c | t;
+}
+
+void test2 (void)
+{
+  long long t;
+  if (a)
+    t = -1LL;
+  else
+    t = b;
+  a = c & t;
+  b = c | t;
+}
+
+void test3 (void)
+{
+  long long t;
+  if (a)
+    t = 0xf0f0f0f0f0f0f0f0LL;
+  else
+    t = b;
+  a = c & t;
+  b = c | t;
+}