]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: Revise complex hard register clobber elimination
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Fri, 20 Jan 2023 03:33:37 +0000 (12:33 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Tue, 24 Jan 2023 21:23:03 +0000 (13:23 -0800)
In the previously posted patch
"xtensa: Make complex hard register clobber elimination more robust and accurate",
the check code for insns that refer to the [DS]Cmode hard register before
it is overwritten after it is clobbered is incomplete.  Fortunately such
insns are seldom emitted, so it didn't matter.

This patch fixes that for the sake of completeness.

gcc/ChangeLog:

* config/xtensa/xtensa.md:
Fix exit from loops detecting references before overwriting in the
split pattern.

gcc/config/xtensa/xtensa.md

index dd3fc37353b94f69211acbacd19896ad3169f365..d3996b26cb5c1d1e6b6bba8e3a24ab6b8bc3b246 100644 (file)
 {
   auto_sbitmap bmp (FIRST_PSEUDO_REGISTER);
   rtx_insn *insn;
-  rtx reg = gen_rtx_REG (SImode, 0);
+  rtx reg = gen_rtx_REG (SImode, 0), dest;
+  unsigned int regno;
+  sbitmap_iterator iter;
   bitmap_set_range (bmp, REGNO (operands[0]), REG_NREGS (operands[0]));
   for (insn = next_nonnote_nondebug_insn_bb (curr_insn);
        insn; insn = next_nonnote_nondebug_insn_bb (insn))
-    {
-      sbitmap_iterator iter;
-      unsigned int regno;
-      if (NONJUMP_INSN_P (insn))
-       {
-         EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
-           {
-             set_regno_raw (reg, regno, REG_NREGS (reg));
-             if (reg_overlap_mentioned_p (reg, PATTERN (insn)))
-               break;
-           }
-         if (GET_CODE (PATTERN (insn)) == SET)
-           {
-             rtx x = SET_DEST (PATTERN (insn));
-             if (REG_P (x) && HARD_REGISTER_P (x))
-               bitmap_clear_range (bmp, REGNO (x), REG_NREGS (x));
-             else if (SUBREG_P (x) && HARD_REGISTER_P (SUBREG_REG (x)))
-               {
-                 struct subreg_info info;
-                 subreg_get_info (regno = REGNO (SUBREG_REG (x)),
-                                  GET_MODE (SUBREG_REG (x)),
-                                  SUBREG_BYTE (x), GET_MODE (x), &info);
-                 if (!info.representable_p)
-                   break;
-                 bitmap_clear_range (bmp, regno + info.offset, info.nregs);
-               }
-           }
-         if (bitmap_empty_p (bmp))
-           goto FALLTHRU;
-       }
-      else if (CALL_P (insn))
+    if (NONJUMP_INSN_P (insn))
+      {
        EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
-        if (call_used_or_fixed_reg_p (regno))
-          break;
-    }
+         {
+           set_regno_raw (reg, regno, REG_NREGS (reg));
+           if (reg_referenced_p (reg, PATTERN (insn)))
+             goto ABORT;
+         }
+       if (GET_CODE (PATTERN (insn)) == SET
+           || GET_CODE (PATTERN (insn)) == CLOBBER)
+         {
+           dest = SET_DEST (PATTERN (insn));
+           if (REG_P (dest) && HARD_REGISTER_P (dest))
+             bitmap_clear_range (bmp, REGNO (dest), REG_NREGS (dest));
+           else if (SUBREG_P (dest)
+                    && HARD_REGISTER_P (SUBREG_REG (dest)))
+             {
+               struct subreg_info info;
+               subreg_get_info (regno = REGNO (SUBREG_REG (dest)),
+                                GET_MODE (SUBREG_REG (dest)),
+                                SUBREG_BYTE (dest), GET_MODE (dest),
+                                &info);
+               if (!info.representable_p)
+                 break;
+               bitmap_clear_range (bmp, regno + info.offset, info.nregs);
+             }
+         }
+       if (bitmap_empty_p (bmp))
+         goto FALLTHRU;
+      }
+    else if (CALL_P (insn))
+      EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
+       if (call_used_or_fixed_reg_p (regno))
+         goto ABORT;
+ABORT:
   FAIL;
 FALLTHRU:;
 })