This is a reduced version of the testcase that shows the bug that was fixed. However it is odd, in that the code that triggered the bug is setting hard register FR3 to 0 as a DImode value just before the call to __gcc_qmul to multiply the two long double values, so it needs some more looking into.
2011-03-15 Michael Meissner <[email protected]> * gcc.target/powerpc/pr48053-3.c: New file, add test case for split problem of 0 being loaded in a VSX register. Index: gcc/testsuite/gcc.target/powerpc/pr48053-3.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr48053-3.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/pr48053-3.c (revision 0) @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O3 -mcpu=power7" } */ + +/* Cut down example from s_scalbnl that aborted on 32-bit when the fix for + 48053 went in to allow creating DImode 0's in VSX registers. */ + +typedef union +{ + long double value; + struct + { + unsigned long long msw; + unsigned long long lsw; + } parts64; + struct + { + unsigned int w0, w1, w2, w3; + } parts32; +} ieee854_long_double_shape_type; + +static const long double twolm54 = 5.55111512312578270212e-17; + +long double foo (long double x, int n) +{ + long long k, hx, lx; + ieee854_long_double_shape_type qw_u; + + qw_u.value = x; + hx = qw_u.parts64.msw; + lx = qw_u.parts64.lsw; + + k = ((hx >> 52) & 0x7ff) + n + 54; + + qw_u.parts64.msw = ((hx & 0x800fffffffffffffULL) | (k << 52)); + qw_u.parts64.lsw = lx; + x = qw_u.value; + + return x*twolm54; +} -- Michael Meissner, IBM 5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA [email protected] fax +1 (978) 399-6899
