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?
2013-09-13 Eric Botcazou <ebotca...@adacore.com>
* tree-ssa-loop-ivopts.c (may_be_unaligned_p): Deal with BLKmode as
the access mode.
2013-09-13 Eric Botcazou <ebotca...@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;
}
-- { dg-do run }
-- { dg-options "-O" }
with Loop_Optimization17_Pkg; use Loop_Optimization17_Pkg;
procedure Loop_Optimization17 is
Data : Arr;
begin
Data := (others => (I => 0,
V1 => (others => 0.0),
V2 => (others => 0.0),
S => 0.0));
for I in Index_T'Range loop
Object (I).V1 := F (Data (I).V1);
Object (I).V2 := F (Data (I).V2);
end loop;
end;
package body Loop_Optimization17_Pkg is
function F (V : Vector) return Vector is begin return V; end;
end Loop_Optimization17_Pkg;
package Loop_Optimization17_Pkg is
type vector is array (1..3) of Long_Float;
type Rec is
record
I : Integer;
V1, V2 : Vector;
S : Long_Float;
end record;
for Rec use
record
I at 0 range 0 .. 31;
V1 at 4 range 0 .. 191;
V2 at 28 range 0 .. 191;
S at 52 range 0 .. 63;
end record;
for Rec'Alignment use 4;
for Rec'Size use 480;
type Index_T is range 1 .. 5;
type Arr is array (Index_T) of Rec;
Object : Arr;
function F (V : Vector) return Vector;
end Loop_Optimization17_Pkg;