Message ID | 4055194.c4aClY8qGv@polaris |
---|---|
State | New |
Headers | show |
On Fri, Sep 13, 2013 at 4:56 PM, Eric Botcazou <ebotcazou@adacore.com> wrote: > Hi, > > in Ada we can have misaligned array components in record types, that is to say > object with BLKmode whose alignment is lower than that of their type. In this > case IVOPTS can generate misaligned TARGET_MEM_REFs, which will lead to an > unaligned access on strict-alignment platforms. > > Tested on SPARC/Solaris, OK for the mainline? I think that may_be_unaligned_p is just seriously out-dated ... shouldn't it be sth like get_object_alignment_1 (ref, &align, &bitpos); if step * BITS_PER_UNIT + bitpos is misaligned ... or rather all this may_be_unaligned_p stuff should be dropped and IVOPTs should finally generate proper [TARGET_]MEM_REFs instead? That is, we already handle aliasing fine: ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff, reference_alias_ptr_type (*use->op_p), iv, base_hint, data->speed); so just also handle alignment properly by passing down get_object_alignment (*use->op_p) and in create_mem_ref_raw do at the end do the if (TYPE_MODE (type) != BLKmode && GET_MODE_ALIGNMENT (TYPE_MODE (type)) > align) type = build_aligned_type (type, align); for BLKmode we already look at TYPE_ALIGN and as we do not change the access type(?) either the previous code was already wrong or it was fine, so there is nothing to do. So - if you want to give it a try...? Thanks, Richard. > 2013-09-13 Eric Botcazou <ebotcazou@adacore.com> > > * tree-ssa-loop-ivopts.c (may_be_unaligned_p): Deal with BLKmode as > the access mode. > > > 2013-09-13 Eric Botcazou <ebotcazou@adacore.com> > > * gnat.dg/loop_optimization17.adb: New test. > * gnat.dg/loop_optimization17_pkg.ad[sb]: New helper. > > > -- > Eric Botcazou
Index: tree-ssa-loop-ivopts.c =================================================================== --- tree-ssa-loop-ivopts.c (revision 202431) +++ tree-ssa-loop-ivopts.c (working copy) @@ -1658,7 +1658,7 @@ may_be_unaligned_p (tree ref, tree step) tree toffset; enum machine_mode mode; int unsignedp, volatilep; - unsigned base_align; + unsigned base_align, align; /* TARGET_MEM_REFs are translated directly to valid MEMs on the target, thus they are not misaligned. */ @@ -1674,22 +1674,23 @@ may_be_unaligned_p (tree ref, tree step) base_align = get_object_alignment (base); base_align = MAX (base_align, TYPE_ALIGN (base_type)); - 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; - - if ((highest_pow2_factor (step) * BITS_PER_UNIT) < mode_align) - return true; - } + /* If the mode is BLKmode, then a block move will be used with the + alignment of the object's type. */ + if (mode == BLKmode) + align = TYPE_ALIGN (TREE_TYPE (ref)); + else + align = GET_MODE_ALIGNMENT (mode); + + if (base_align < align + || (bitpos % align) != 0 + || (bitpos % BITS_PER_UNIT) != 0) + return true; + + if (toffset && (highest_pow2_factor (toffset) * BITS_PER_UNIT) < align) + return true; + + if ((highest_pow2_factor (step) * BITS_PER_UNIT) < align) + return true; return false; }