public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [commit, spu] Fix aliasing violation in SPU libgcc
@ 2011-04-27 14:15 Ulrich Weigand
  0 siblings, 0 replies; only message in thread
From: Ulrich Weigand @ 2011-04-27 14:15 UTC (permalink / raw)
  To: gcc-patches

Hello,

the SPU __multi3 and __udivmodti4 routines were using code that violates
the aliasing rules for type-punning between TImode and vector types.

This now causes errors when building those files.  The patch below
replaces this code by type-punning via unions.

Tested on spu-elf, committed to mainline.

Bye,
Ulrich


ChangeLog:

	* config/spu/divmovti4.c (union qword_UTItype): New data type.
	(si_from_UTItype, si_to_UTItype): New functions.
	(__udivmodti4): Use them to implement type-punning.
	* config/spu/multi3.c (union qword_TItype): New data type.
	(si_from_TItype, si_to_TItype): New functions.
	(__multi3): Use them to implement type-punning.

Index: gcc/config/spu/divmodti4.c
===================================================================
*** gcc/config/spu/divmodti4.c	(revision 172953)
--- gcc/config/spu/divmodti4.c	(working copy)
*************** UTItype __udivti3 (UTItype u, UTItype v)
*** 29,34 ****
--- 29,56 ----
  UTItype __umodti3 (UTItype u, UTItype v);
  UTItype __udivmodti4 (UTItype u, UTItype v, UTItype *w);
  
+ union qword_UTItype
+   {
+     qword q;
+     UTItype t;
+   };
+   
+ inline static qword
+ si_from_UTItype (UTItype t)
+ { 
+   union qword_UTItype u;
+   u.t = t;
+   return u.q;
+ }
+ 
+ inline static UTItype
+ si_to_UTItype (qword q)
+ { 
+   union qword_UTItype u;
+   u.q = q;
+   return u.t;
+ }
+ 
  inline static unsigned int
  count_leading_zeros (UTItype x)
  {
*************** __udivmodti4 (UTItype num, UTItype den, 
*** 67,74 ****
  {
    qword shift =
      si_from_uint (count_leading_zeros (den) - count_leading_zeros (num));
!   qword n0 = *(qword *) & num;
!   qword d0 = *(qword *) & den;
    qword bit = si_andi (si_fsmbi (1), 1);
    qword r0 = si_il (0);
    qword m1 = si_fsmbi (0x000f);
--- 89,96 ----
  {
    qword shift =
      si_from_uint (count_leading_zeros (den) - count_leading_zeros (num));
!   qword n0 = si_from_UTItype (num);
!   qword d0 = si_from_UTItype (den);
    qword bit = si_andi (si_fsmbi (1), 1);
    qword r0 = si_il (0);
    qword m1 = si_fsmbi (0x000f);
*************** __udivmodti4 (UTItype num, UTItype den, 
*** 101,108 ****
      }
    while (si_to_uint (si_orx (bit)));
    if (rp)
!     *rp = *(UTItype *) & n0;
!   return *(UTItype *) & r0;
  }
  
  UTItype
--- 123,130 ----
      }
    while (si_to_uint (si_orx (bit)));
    if (rp)
!     *rp = si_to_UTItype (n0);
!   return si_to_UTItype (r0);
  }
  
  UTItype
Index: gcc/config/spu/multi3.c
===================================================================
*** gcc/config/spu/multi3.c	(revision 172953)
--- gcc/config/spu/multi3.c	(working copy)
***************
*** 23,28 ****
--- 23,50 ----
  
  typedef int TItype __attribute__ ((mode (TI)));
  
+ union qword_TItype
+   {
+     qword q;
+     TItype t;
+   };
+   
+ inline static qword
+ si_from_TItype (TItype t)
+ { 
+   union qword_TItype u;
+   u.t = t;
+   return u.q;
+ }
+ 
+ inline static TItype
+ si_to_TItype (qword q)
+ { 
+   union qword_TItype u;
+   u.q = q;
+   return u.t;
+ }
+ 
  /* A straight forward vectorization and unrolling of
   *   short l[8], r[8];
   *   TItype total = 0;
*************** typedef int TItype __attribute__ ((mode 
*** 33,40 ****
  TItype
  __multi3 (TItype l, TItype r)
  {
!   qword u = *(qword *) & l;
!   qword v = *(qword *) & r;
    qword splat0 = si_shufb (v, v, si_ilh (0x0001));
    qword splat1 = si_shufb (v, v, si_ilh (0x0203));
    qword splat2 = si_shufb (v, v, si_ilh (0x0405));
--- 55,62 ----
  TItype
  __multi3 (TItype l, TItype r)
  {
!   qword u = si_from_TItype (l);
!   qword v = si_from_TItype (r);
    qword splat0 = si_shufb (v, v, si_ilh (0x0001));
    qword splat1 = si_shufb (v, v, si_ilh (0x0203));
    qword splat2 = si_shufb (v, v, si_ilh (0x0405));
*************** __multi3 (TItype l, TItype r)
*** 93,97 ****
    total = si_cgx (total10, carry, total);
    total = si_shlqbyi (total, 4);
    total = si_addx (total10, carry, total);
!   return *(TItype *) & total;
  }
--- 115,119 ----
    total = si_cgx (total10, carry, total);
    total = si_shlqbyi (total, 4);
    total = si_addx (total10, carry, total);
!   return si_to_TItype (total);
  }
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-04-27 13:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-27 14:15 [commit, spu] Fix aliasing violation in SPU libgcc Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).