===================================================================
@@ -1050,6 +1050,25 @@ disqualify_ops_if_throwing_stmt (gimple
return false;
}
+/* Return true iff type of EXP is not sufficiently aligned. */
+
+static bool
+tree_non_mode_aligned_mem_p (tree exp)
+{
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
+ unsigned int align;
+
+ if (mode == BLKmode
+ || !STRICT_ALIGNMENT)
+ return false;
+
+ align = get_object_alignment (exp, BIGGEST_ALIGNMENT);
+ if (GET_MODE_ALIGNMENT (mode) > align)
+ return true;
+
+ return false;
+}
+
/* Scan expressions occuring in STMT, create access structures for all accesses
to candidates for scalarization and remove those candidates which occur in
statements or expressions that prevent them from being split apart. Return
@@ -1074,7 +1093,10 @@ build_accesses_from_assign (gimple stmt)
lacc = build_access_from_expr_1 (lhs, stmt, true);
if (lacc)
- lacc->grp_assignment_write = 1;
+ {
+ lacc->grp_assignment_write = 1;
+ lacc->grp_unscalarizable_region |= tree_non_mode_aligned_mem_p (rhs);
+ }
if (racc)
{
@@ -1082,6 +1104,7 @@ build_accesses_from_assign (gimple stmt)
if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
&& !is_gimple_reg_type (racc->type))
bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
+ racc->grp_unscalarizable_region |= tree_non_mode_aligned_mem_p (lhs);
}
if (lacc && racc
===================================================================
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+struct in_addr {
+ unsigned int s_addr;
+};
+
+struct ip {
+ unsigned char ip_p;
+ unsigned short ip_sum;
+ struct in_addr ip_src,ip_dst;
+} __attribute__ ((aligned(1), packed));
+
+struct ip ip_fw_fwd_addr;
+
+int test_alignment( char *m )
+{
+ struct ip *ip = (struct ip *) m;
+ struct in_addr pkt_dst;
+ pkt_dst = ip->ip_dst ;
+ if( pkt_dst.s_addr == 0 )
+ return 1;
+ else
+ return 0;
+}
+
+int __attribute__ ((noinline, noclone))
+intermediary (char *p)
+{
+ return test_alignment (p);
+}
+
+int
+main (int argc, char *argv[])
+{
+ ip_fw_fwd_addr.ip_dst.s_addr = 1;
+ return intermediary ((void *) &ip_fw_fwd_addr);
+}