]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorRichard Biener <rguenther@suse.de>
Wed, 10 Jun 2015 12:53:09 +0000 (12:53 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 10 Jun 2015 12:53:09 +0000 (12:53 +0000)
2015-06-10  Richard Biener  <rguenther@suse.de>

Backport from mainline
2014-04-04  Cong Hou  <congh@google.com>

PR tree-optimization/60656
* tree-vect-stmts.c (supportable_widening_operation):
Fix a bug that elements in a vector with vect_used_by_reduction
property are incorrectly reordered when the operation on it is not
consistant with the one in reduction operation.

* gcc.dg/vect/pr60656.c: New test.

2014-01-31  Richard Biener  <rguenther@suse.de>

PR middle-end/59990
* builtins.c (fold_builtin_memory_op): Make sure to not
use a floating-point mode or a boolean or enumeral type for
the copy operation.

* gcc.dg/torture/pr59990.c: New testcase.
* gcc.target/i386/pr49168-1.c: Adjust.

From-SVN: r224327

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr59990.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr60656.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr49168-1.c
gcc/tree-vect-stmts.c

index 80c4ee859c0dc1430a5bf979ce3b52160acba412..885e9c70cfaa213b1856854b52d0979b61908aba 100644 (file)
@@ -1,3 +1,21 @@
+2015-06-10  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2014-04-04  Cong Hou  <congh@google.com>
+
+       PR tree-optimization/60656
+       * tree-vect-stmts.c (supportable_widening_operation):
+       Fix a bug that elements in a vector with vect_used_by_reduction
+       property are incorrectly reordered when the operation on it is not
+       consistant with the one in reduction operation.
+
+       2014-01-31  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/59990
+       * builtins.c (fold_builtin_memory_op): Make sure to not
+       use a floating-point mode or a boolean or enumeral type for
+       the copy operation.
+
 2015-06-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/66470
index bb6c664394bc2dfdd7cdcfa502c3567227ced60a..c3c3ce37d39a609fe8037cf0e78d45fb0baec1df 100644 (file)
@@ -8911,6 +8911,12 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
       if (!POINTER_TYPE_P (TREE_TYPE (src))
          || !POINTER_TYPE_P (TREE_TYPE (dest)))
        return NULL_TREE;
+      /* In the following try to find a type that is most natural to be
+        used for the memcpy source and destination and that allows
+        the most optimization when memcpy is turned into a plain assignment
+        using that type.  In theory we could always use a char[len] type
+        but that only gains us that the destination and source possibly
+        no longer will have their address taken.  */
       /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
       if (TREE_CODE (src) == POINTER_PLUS_EXPR)
        {
@@ -8946,6 +8952,41 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
          || TREE_ADDRESSABLE (desttype))
        return NULL_TREE;
 
+      /* Make sure we are not copying using a floating-point mode or
+         a type whose size possibly does not match its precision.  */
+      if (FLOAT_MODE_P (TYPE_MODE (desttype))
+         || TREE_CODE (desttype) == BOOLEAN_TYPE
+         || TREE_CODE (desttype) == ENUMERAL_TYPE)
+       {
+         /* A more suitable int_mode_for_mode would return a vector
+            integer mode for a vector float mode or a integer complex
+            mode for a float complex mode if there isn't a regular
+            integer mode covering the mode of desttype.  */
+         enum machine_mode mode = int_mode_for_mode (TYPE_MODE (desttype));
+         if (mode == BLKmode)
+           desttype = NULL_TREE;
+         else
+           desttype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode),
+                                                      1);
+       }
+      if (FLOAT_MODE_P (TYPE_MODE (srctype))
+         || TREE_CODE (srctype) == BOOLEAN_TYPE
+         || TREE_CODE (srctype) == ENUMERAL_TYPE)
+       {
+         enum machine_mode mode = int_mode_for_mode (TYPE_MODE (srctype));
+         if (mode == BLKmode)
+           srctype = NULL_TREE;
+         else
+           srctype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode),
+                                                     1);
+       }
+      if (!srctype)
+       srctype = desttype;
+      if (!desttype)
+       desttype = srctype;
+      if (!srctype)
+       return NULL_TREE;
+
       src_align = get_pointer_alignment (src);
       dest_align = get_pointer_alignment (dest);
       if (dest_align < TYPE_ALIGN (desttype)
index 9bda3339c2e2ff85edede91c609266086aaeb5da..a66ec2ec0bdc843db2d019671f21fa561c604b21 100644 (file)
@@ -1,3 +1,17 @@
+2015-06-10  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2014-04-04  Cong Hou  <congh@google.com>
+
+       PR tree-optimization/60656
+       * gcc.dg/vect/pr60656.c: New test.
+
+       2014-01-31  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/59990
+       * gcc.dg/torture/pr59990.c: New testcase.
+       * gcc.target/i386/pr49168-1.c: Adjust.
+
 2015-06-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/66470
diff --git a/gcc/testsuite/gcc.dg/torture/pr59990.c b/gcc/testsuite/gcc.dg/torture/pr59990.c
new file mode 100644 (file)
index 0000000..e54f9b7
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+unsigned char value[4] = { 66, 9, 160, 255 };
+
+int main (void)
+{
+  volatile float f;
+  unsigned char a[4];
+
+  __builtin_memcpy ((void *)&f, value, 4);
+  __builtin_memcpy (a, (void *)&f, 4);
+  if (a[2] != 160)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr60656.c b/gcc/testsuite/gcc.dg/vect/pr60656.c
new file mode 100644 (file)
index 0000000..a787f04
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_long } */
+
+#include "tree-vect.h"
+
+__attribute__ ((noinline)) long
+foo ()
+{
+  int v[] = {5000, 5001, 5002, 5003};
+  long s = 0;
+  int i;
+
+  for(i = 0; i < 4; ++i)
+    {
+      long P = v[i];
+      s += P * P * P;
+    }
+  return s;
+}
+
+long
+bar ()
+{
+  int v[] = {5000, 5001, 5002, 5003};
+  long s = 0;
+  int i;
+
+  for(i = 0; i < 4; ++i)
+    {
+      long P = v[i];
+      s += P * P * P;
+      __asm__ volatile ("");
+    }
+  return s;
+}
+
+int main()
+{
+  check_vect ();
+
+  if (foo () != bar ())
+    abort ();
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 9676dc85a8effa2153c459409e6e5463786693b7..f8cce4a8ac97bb387e23a561a384b69faa1af37e 100644 (file)
@@ -2,7 +2,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -msse2 -mtune=generic" } */
 /* { dg-final { scan-assembler-not "movdqa\[\t \]*%xmm\[0-9\]\+,\[^,\]*" } } */
-/* { dg-final { scan-assembler "movdqu\[\t \]*%xmm\[0-9\]\+,\[^,\]*" } } */
+/* { dg-final { scan-assembler "mov\[dlh\]\[qp\]\[us\]\[\t \]*%xmm\[0-9\]\+,\[^,\]*" } } */
 
 void
 flt128_va (void *mem, __float128 d)
index 2301ce89f329a199395e997b0884030d933cec81..53c286c95085178d526248ce99a705924798f5f7 100644 (file)
@@ -6459,7 +6459,21 @@ supportable_widening_operation (enum tree_code code, gimple stmt,
                                             stmt, vectype_out, vectype_in,
                                             code1, code2, multi_step_cvt,
                                             interm_types))
-       return true;
+        {
+          /* Elements in a vector with vect_used_by_reduction property cannot
+             be reordered if the use chain with this property does not have the
+             same operation.  One such an example is s += a * b, where elements
+             in a and b cannot be reordered.  Here we check if the vector defined
+             by STMT is only directly used in the reduction statement.  */
+          tree lhs = gimple_assign_lhs (stmt);
+          use_operand_p dummy;
+          gimple use_stmt;
+          stmt_vec_info use_stmt_info = NULL;
+          if (single_imm_use (lhs, &dummy, &use_stmt)
+              && (use_stmt_info = vinfo_for_stmt (use_stmt))
+              && STMT_VINFO_DEF_TYPE (use_stmt_info) == vect_reduction_def)
+            return true;
+        }
       c1 = VEC_WIDEN_MULT_LO_EXPR;
       c2 = VEC_WIDEN_MULT_HI_EXPR;
       break;