https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71698

Peter Bergner <bergner at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|segher at gcc dot gnu.org          |bergner at gcc dot 
gnu.org

--- Comment #5 from Peter Bergner <bergner at gcc dot gnu.org> ---
The vararg thing is just a red herring, it just introduced a copy between a
FP/VSX reg to/from a GPR reg which exposes the problem.  The problem is that
when we see a copy like that, we normally will try to emit a direct move
instruction, but we can't do that for TDmode, for endian reasons.  See the
rs6000.md commentary for the *mov<mode>_64bit_dm and *movtd_64bit_nodm patterns
for why not.

That said, rs6000_secondary_reload_simple_move() is not checking for mode ==
TDmode when determining whether a copy between VSX regs and GPR regs is ok.

I'm currently testing the following patch.

Index: rs6000.c
===================================================================
--- rs6000.c    (revision 237873)
+++ rs6000.c    (working copy)
@@ -19169,7 +19169,8 @@ rs6000_secondary_reload_simple_move (enu
      simple move insns are issued.  At present, 32-bit integers are not
allowed
      in FPR/VSX registers.  Single precision binary floating is not a simple
      move because we need to convert to the single precision memory layout.
-     The 4-byte SDmode can be moved.  */
+     The 4-byte SDmode can be moved.  TDmode values cannot be moved due to
+     endian issues.  */
   size = GET_MODE_SIZE (mode);
   if (TARGET_DIRECT_MOVE
       && ((mode == SDmode) || (TARGET_POWERPC64 && size == 8))
@@ -19177,7 +19178,7 @@ rs6000_secondary_reload_simple_move (enu
          || (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE)))
     return true;

-  else if (TARGET_DIRECT_MOVE_128 && size == 16
+  else if (TARGET_DIRECT_MOVE_128 && size == 16 && mode != TDmode
           && ((to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE)
               || (to_type == GPR_REG_TYPE && from_type == VSX_REG_TYPE)))
     return true;

Reply via email to