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.weig...@de.ibm.com