]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
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:24:57 +0000 (21:24 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 30 Apr 2010 21:24:57 +0000 (21:24 +0000)
* tree-ssa-loop-ivopts.c (may_be_unaligned_p): Check the alignment of
the variable part of the offset as well.

From-SVN: r158953

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 f1c2d133d9b8c45982720c65db1bf584a372dc65..2d1003ecb85c854b05d73720335f495202376f67 100644 (file)
@@ -1,3 +1,8 @@
+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.
+
 2010-04-27  Richard Guenther  <rguenther@suse.de>
 
        PR c++/40561
index b43e4b20997c161e1f1106c72b8362559788d1b1..93a89110b605a22ee5b2c8ed61b87d2592dde64c 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-27  Richard Guenther  <rguenther@suse.de>
 
        PR c++/40561
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 78b440906929d1c13955a554f3b1f7fa2c1990e5..4f38266e9b05a4cf673251ff226886425933ff62 100644 (file)
@@ -1418,11 +1418,19 @@ may_be_unaligned_p (tree ref)
   base_type = TREE_TYPE (base);
   base_align = TYPE_ALIGN (base_type);
 
-  if (mode != BLKmode
-      && (base_align < GET_MODE_ALIGNMENT (mode)
-         || bitpos % GET_MODE_ALIGNMENT (mode) != 0
-         || bitpos % BITS_PER_UNIT != 0))
-    return true;
+  if (mode != BLKmode)
+    {
+      unsigned mode_align = GET_MODE_ALIGNMENT (mode);
+
+      if (base_align < mode_align
+         || (bitpos % mode_align) != 0
+         || (bitpos % BITS_PER_UNIT) != 0)
+       return true;
+
+      if (toffset
+         && (highest_pow2_factor (toffset) * BITS_PER_UNIT) < mode_align)
+       return true;
+    }
 
   return false;
 }