This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix unaligned access generated by IVOPTS


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  <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;
 }
-- { 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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]