Hi,

The ada bootstrap failure reported in 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72827
occurs because of a latent bug in the powerpc back end.  The immediate cause is 
dead store
elimination removing two stores relative to the frame pointer that are not 
dead; however,
DSE is tricked into doing this because we have temporarily adjusted the frame 
pointer prior
to performing the loads.  DSE relies on the frame pointer remaining constant to 
be able to
infer stack stores that are dead.

The code responsible is in rs6000_split_multireg_move, which wants to form new 
addresses
after reload/lra to use for the individual stores, but has to use only existing 
hard
registers.  Currently that code always modifies the register holding the base 
pointer,
which is a bad idea when the base pointer is a register expected to remain 
fixed.  This
patch identifies those situations and causes the index register to be modified 
instead.
(If the index register number is zero, indicating constant zero, we fall 
through to the
existing code; it's ok to add zero to the fixed registers...)

The diffs are a little munged due to indentation and line length adjustments; 
the change
is just to add the code block labeled with commentary.

We might someday want to rip up this logic and instead change secondary reload 
to allocate
an extra register to be used during expansion.  But to clear the bootstrap 
failure, a
simple patch like this seems best.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with the usual 
languages plus ada,
with no regressions.  Gnattools now builds properly during bootstrap.

Is this ok for trunk, and eventually for backport to the 5 and 6 branches?

Thanks,
Bill


2016-08-30  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        PR target/72827
        * config/rs6000/rs6000.c (rs6000_split_multireg_move): Never
        modify the frame pointer or the stack pointer; instead, use
        the index register for temporary address generation.


Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 239871)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -24506,15 +24506,31 @@ rs6000_split_multireg_move (rtx dst, rtx src)
                              && REG_P (basereg)
                              && REG_P (offsetreg)
                              && REGNO (basereg) != REGNO (offsetreg));
-                 if (REGNO (basereg) == 0)
+                 /* We mustn't modify the stack pointer or frame pointer
+                    as this will confuse dead store elimination.  */
+                 if ((REGNO (basereg) == STACK_POINTER_REGNUM
+                      || REGNO (basereg) == HARD_FRAME_POINTER_REGNUM)
+                     && REGNO (offsetreg) != 0)
                    {
-                     rtx tmp = offsetreg;
-                     offsetreg = basereg;
-                     basereg = tmp;
+                     emit_insn (gen_add3_insn (offsetreg, basereg,
+                                               offsetreg));
+                     restore_basereg = gen_sub3_insn (offsetreg, offsetreg,
+                                                      basereg);
+                     dst = replace_equiv_address (dst, offsetreg);
                    }
-                 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
-                 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
-                 dst = replace_equiv_address (dst, basereg);
+                 else
+                   {
+                     if (REGNO (basereg) == 0)
+                       {
+                         rtx tmp = offsetreg;
+                         offsetreg = basereg;
+                         basereg = tmp;
+                       }
+                     emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
+                     restore_basereg = gen_sub3_insn (basereg, basereg,
+                                                      offsetreg);
+                     dst = replace_equiv_address (dst, basereg);
+                   }
                }
            }
          else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)

Reply via email to