This split is disabled for power7 and up, so we don't often see its
bad effects.  However, on a powerpc-linux compiler (which defaults
to PPC750 judging from rs6000/sysv4.h) we see

        long double ld1 (void) { return 1.0L; }

compiled with -msoft-float -O2 -S resulting in

        ld1:
                li 3,0
                li 4,0
                mr 6,4
                mr 5,3
                li 4,0
                lis 3,0x3ff0
                blr

Things go awry in init-regs, with the TFmode reg being initialized to
zero on seeing the subreg from the split.  (And that initialization
itself is split by rs6000_emit_move!)  Later passes apparently don't
clean up the rubbish.

Since the split was added for Darwin (as the comment says), let's get
rid of it on other targets.

Bootstrapped etc. powerpc64le-linux and powerpc64-linux.

        * config/rs6000/rs6000.c (rs6000_emit_move): Disable long
        double split for targets other than Darwin.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 212e9facb3a..c339368be29 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -10010,8 +10010,8 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode 
mode)
   /* 128-bit constant floating-point values on Darwin should really be loaded
      as two parts.  However, this premature splitting is a problem when DFmode
      values can go into Altivec registers.  */
-  if (FLOAT128_IBM_P (mode) && !reg_addr[DFmode].scalar_in_vmx_p
-      && GET_CODE (operands[1]) == CONST_DOUBLE)
+  if (TARGET_MACHO && CONST_DOUBLE_P (operands[1]) && FLOAT128_IBM_P (mode)
+      && !reg_addr[DFmode].scalar_in_vmx_p)
     {
       rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode, 0),
                        simplify_gen_subreg (DFmode, operands[1], mode, 0),

-- 
Alan Modra
Australia Development Lab, IBM

Reply via email to