re PR middle-end/52890 (Revision 185336 causes 10% degradation on cpu2000 benchmark...
authorMartin Jambor <mjambor@suse.cz>
Fri, 30 Nov 2012 16:11:33 +0000 (17:11 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 30 Nov 2012 16:11:33 +0000 (17:11 +0100)
2012-11-30  Martin Jambor  <mjambor@suse.cz>

PR middle-end/52890
PR tree-optimization/55415
PR tree-optimization/54386
PR target/55448
* ipa-prop.c (ipa_modify_call_arguments): Be optimistic when
get_pointer_alignment_1 returns false and the base was not a
dereference.
* tree-sra.c (access_precludes_ipa_sra_p): New parameter req_align,
added check for required alignment.  Update the user.

* testsuite/gcc.dg/ipa/ipa-sra-7.c: New test.
* testsuite/gcc.dg/ipa/ipa-sra-8.c: Likewise.
* testsuite/gcc.dg/ipa/ipa-sra-9.c: Likewise.
* testsuite/gcc.target/i386/pr55448.c: Likewise.

From-SVN: r193998

gcc/ChangeLog
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/ipa-sra-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipa-sra-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipa-sra-9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr55448.c [new file with mode: 0644]
gcc/tree-sra.c

index ceba51d..013ccf5 100644 (file)
@@ -1,3 +1,15 @@
+2012-11-30  Martin Jambor  <mjambor@suse.cz>
+
+       PR middle-end/52890
+       PR tree-optimization/55415
+       PR tree-optimization/54386
+       PR target/55448
+       * ipa-prop.c (ipa_modify_call_arguments): Be optimistic when
+       get_pointer_alignment_1 returns false and the base was not a
+       dereference.
+       * tree-sra.c (access_precludes_ipa_sra_p): New parameter req_align,
+       added check for required alignment.  Update the user.
+
 2012-11-30  Ramana Radhakrishnan <Ramana.Radhakrishnan@arm.com>
             Greta Yorsh  <Greta.Yorsh@arm.com>
 
index 6016257..01d142b 100644 (file)
@@ -2888,6 +2888,8 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
        {
          tree expr, base, off;
          location_t loc;
+         unsigned int deref_align;
+         bool deref_base = false;
 
          /* We create a new parameter out of the value of the old one, we can
             do the following kind of transformations:
@@ -2921,9 +2923,15 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
            {
              HOST_WIDE_INT base_offset;
              tree prev_base;
+             bool addrof;
 
              if (TREE_CODE (base) == ADDR_EXPR)
-               base = TREE_OPERAND (base, 0);
+               {
+                 base = TREE_OPERAND (base, 0);
+                 addrof = true;
+               }
+             else
+               addrof = false;
              prev_base = base;
              base = get_addr_base_and_unit_offset (base, &base_offset);
              /* Aggregate arguments can have non-invariant addresses.  */
@@ -2935,6 +2943,11 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
                }
              else if (TREE_CODE (base) == MEM_REF)
                {
+                 if (!addrof)
+                   {
+                     deref_base = true;
+                     deref_align = TYPE_ALIGN (TREE_TYPE (base));
+                   }
                  off = build_int_cst (adj->alias_ptr_type,
                                       base_offset
                                       + adj->offset / BITS_PER_UNIT);
@@ -2957,7 +2970,17 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
              unsigned int align;
              unsigned HOST_WIDE_INT misalign;
 
-             get_pointer_alignment_1 (base, &align, &misalign);
+             if (deref_base)
+               {
+                 align = deref_align;
+                 misalign = 0;
+               }
+             else
+               {
+                 get_pointer_alignment_1 (base, &align, &misalign);
+                 if (TYPE_ALIGN (type) > align)
+                   align = TYPE_ALIGN (type);
+               }
              misalign += (tree_to_double_int (off)
                           .sext (TYPE_PRECISION (TREE_TYPE (off))).low
                           * BITS_PER_UNIT);
index 54692e1..6bfa093 100644 (file)
@@ -1,3 +1,14 @@
+2012-11-30  Martin Jambor  <mjambor@suse.cz>
+
+       PR middle-end/52890
+       PR tree-optimization/55415
+       PR tree-optimization/54386
+       PR target/55448
+       * gcc.dg/ipa/ipa-sra-7.c: New test.
+       * gcc.dg/ipa/ipa-sra-8.c: Likewise.
+       * gcc.dg/ipa/ipa-sra-9.c: Likewise.
+       * gcc.target/i386/pr55448.c: Likewise.
+
 2012-11-29  Eric Botcazou  <ebotcazou@adacore.com>
 
        * loop_optimization14.ad[sb]: New test.
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-7.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-7.c
new file mode 100644 (file)
index 0000000..921334a
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+typedef unsigned int myint __attribute__((aligned(1)));
+
+typedef struct __attribute__((packed)) S {
+  unsigned a, b, c;
+} SS;
+
+typedef SS __attribute__((aligned(1))) SSS;
+
+
+static unsigned int __attribute__ ((noinline))
+get_a (SSS *p)
+{
+  return p->a;
+};
+
+static int __attribute__ ((noinline, noclone))
+foo (SS *p)
+{
+  int r = (int) get_a(p) + 2;
+  return r;
+}
+
+char buf[512];
+
+static SSS * __attribute__ ((noinline, noclone))
+get_sss (void)
+{
+  return (SSS *)(buf + 1);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+  SSS *p = get_sss();
+  if (foo(p) != 2)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-8.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-8.c
new file mode 100644 (file)
index 0000000..9e6e40a
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+typedef unsigned int myint __attribute__((aligned(1)));
+
+typedef struct S {
+  unsigned a, b, c;
+} SS;
+
+typedef SS __attribute__((aligned(1))) SSS;
+
+
+static unsigned int __attribute__ ((noinline))
+get_a (SS s)
+{
+  return s.a;
+};
+
+static int __attribute__ ((noinline, noclone))
+foo (SSS *p)
+{
+  int r = (int) get_a(*p) + 2;
+  return r;
+}
+
+char buf[512];
+
+static SSS * __attribute__ ((noinline, noclone))
+get_sss (void)
+{
+  return (SSS *)(buf + 1);
+}
+
+int
+main(int argc, char *argv[])
+{
+  SSS *p = get_sss();
+  if (foo(p) != 2)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-9.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-9.c
new file mode 100644 (file)
index 0000000..c5468cf
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+typedef unsigned int myint __attribute__((aligned(1)));
+
+typedef struct S {
+  unsigned a, b, c;
+} SS;
+
+typedef struct U {
+  SS s[2];
+} UU;
+
+typedef UU __attribute__((aligned(1))) UUU;
+
+static unsigned int __attribute__ ((noinline))
+get_a (SS s)
+{
+  return s.a;
+};
+
+static int __attribute__ ((noinline, noclone))
+foo (UUU *p)
+{
+  int r = (int) get_a(p->s[0]) + 2;
+  return r;
+}
+
+char buf[512];
+
+static UUU * __attribute__ ((noinline, noclone))
+get_uuu (void)
+{
+  return (UUU *)(buf + 1);
+}
+
+int
+main(int argc, char *argv[])
+{
+  UUU *p = get_uuu();
+  if (foo(p) != 2)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr55448.c b/gcc/testsuite/gcc.target/i386/pr55448.c
new file mode 100644 (file)
index 0000000..874a507
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+
+#include <immintrin.h>
+
+static inline __m256 add1(const __m256 *a, const __m256 *b)
+{
+  return _mm256_add_ps(*a, *b);
+}
+
+void foo1(__m256 *a, const __m256 b)
+{
+  *a = add1(a, &b);
+}
+
+static inline __m128 add2(const __m128 *a, const __m128 *b)
+{
+  return _mm_add_ps(*a, *b);
+}
+
+void foo2(__m128 *a, const __m128 b)
+{
+  *a = add2(a, &b);
+}
+
+/* { dg-final { scan-assembler-not "vmovups" } } */
index b560648..4580ad2 100644 (file)
@@ -3891,12 +3891,13 @@ unmodified_by_ref_scalar_representative (tree parm)
   return repr;
 }
 
-/* Return true iff this access precludes IPA-SRA of the parameter it is
-   associated with. */
+/* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
+   associated with.  REQ_ALIGN is the minimum required alignment.  */
 
 static bool
-access_precludes_ipa_sra_p (struct access *access)
+access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
 {
+  unsigned int exp_align;
   /* Avoid issues such as the second simple testcase in PR 42025.  The problem
      is incompatible assign in a call statement (and possibly even in asm
      statements).  This can be relaxed by using a new temporary but only for
@@ -3908,6 +3909,10 @@ access_precludes_ipa_sra_p (struct access *access)
          || gimple_code (access->stmt) == GIMPLE_ASM))
     return true;
 
+  exp_align = get_object_alignment (access->expr);
+  if (exp_align < req_align)
+    return true;
+
   return false;
 }
 
@@ -3943,7 +3948,7 @@ splice_param_accesses (tree parm, bool *ro_grp)
       tree a1_alias_type;
       access = (*access_vec)[i];
       modification = access->write;
-      if (access_precludes_ipa_sra_p (access))
+      if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
        return NULL;
       a1_alias_type = reference_alias_ptr_type (access->expr);
 
@@ -3966,7 +3971,7 @@ splice_param_accesses (tree parm, bool *ro_grp)
          else if (ac2->size != access->size)
            return NULL;
 
-         if (access_precludes_ipa_sra_p (ac2)
+         if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
              || (ac2->type != access->type
                  && (TREE_ADDRESSABLE (ac2->type)
                      || TREE_ADDRESSABLE (access->type)))