tree-ssa-loop-ivopts.c (may_be_unaligned_p): Check the alignment of the variable...
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 30 Apr 2010 21:10:53 +0000 (21:10 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 30 Apr 2010 21:10:53 +0000 (21:10 +0000)
* tree-ssa-loop-ivopts.c (may_be_unaligned_p): Check the alignment of
the variable part of the offset as well.  Use highest_pow2_factor for
all alignment checks.

From-SVN: r158948

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20100430-1.c [new file with mode: 0644]
gcc/tree-ssa-loop-ivopts.c

index 4d7ece9..9829562 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-30  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree-ssa-loop-ivopts.c (may_be_unaligned_p): Check the alignment of
+       the variable part of the offset as well.  Use highest_pow2_factor for
+       all alignment checks.
+
 2010-04-30  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/43879
index 5a02637..0fa5ee7 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-30  DJ Delorie  <dj@redhat.com>
+
+       * gcc.c-torture/execute/20100430-1.c: New test.
+
 2010-04-30  Jason Merrill  <jason@redhat.com>
 
        PR c++/43868
diff --git a/gcc/testsuite/gcc.c-torture/execute/20100430-1.c b/gcc/testsuite/gcc.c-torture/execute/20100430-1.c
new file mode 100644 (file)
index 0000000..d29c6fa
--- /dev/null
@@ -0,0 +1,51 @@
+/* This used to generate unaligned accesses at -O2 because of IVOPTS.  */
+
+struct packed_struct
+{
+  struct packed_struct1
+  {
+    unsigned char cc11;
+    unsigned char cc12;
+  } __attribute__ ((packed)) pst1;
+  struct packed_struct2
+  {
+    unsigned char cc21;
+    unsigned char cc22;
+    unsigned short ss[104];
+    unsigned char cc23[13];
+  } __attribute__ ((packed)) pst2[4];
+} __attribute__ ((packed));
+
+typedef struct
+{
+  int ii;
+  struct packed_struct buf;
+} info_t;
+
+static unsigned short g;
+
+static void __attribute__((noinline))
+dummy (unsigned short s)
+{
+  g = s;
+}
+
+static int
+foo (info_t *info)
+{
+  int i, j;
+
+  for (i = 0; i < info->buf.pst1.cc11; i++)
+    for (j = 0; j < info->buf.pst2[i].cc22; j++)
+      dummy (info->buf.pst2[i].ss[j]);
+
+  return 0;
+}
+
+int main(void)
+{
+  info_t info;
+  info.buf.pst1.cc11 = 2;
+  info.buf.pst2[0].cc22 = info.buf.pst2[1].cc22 = 8;
+  return foo (&info);
+}
index a1fdfa4..8662f4c 100644 (file)
@@ -1536,16 +1536,18 @@ may_be_unaligned_p (tree ref, tree step)
 
   if (mode != BLKmode)
     {
-      double_int mul;
-      tree al = build_int_cst (TREE_TYPE (step),
-                              GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT);
+      unsigned mode_align = GET_MODE_ALIGNMENT (mode);
 
-      if (base_align < GET_MODE_ALIGNMENT (mode)
-         || bitpos % GET_MODE_ALIGNMENT (mode) != 0
-         || bitpos % BITS_PER_UNIT != 0)
+      if (base_align < mode_align
+         || (bitpos % mode_align) != 0
+         || (bitpos % BITS_PER_UNIT) != 0)
        return true;
 
-      if (!constant_multiple_of (step, al, &mul))
+      if (toffset
+         && (highest_pow2_factor (toffset) * BITS_PER_UNIT) < mode_align)
+       return true;
+
+      if ((highest_pow2_factor (step) * BITS_PER_UNIT) < mode_align)
        return true;
     }