amdgcn: Fix exec register live-on-entry to BB in md-reorg
authorJulian Brown <julian@codesourcery.com>
Fri, 6 Nov 2020 22:53:29 +0000 (14:53 -0800)
committerJulian Brown <julian@codesourcery.com>
Wed, 13 Jan 2021 00:46:02 +0000 (16:46 -0800)
This patch fixes a corner case in the AMD GCN md-reorg pass when the
EXEC register is live on entry to a BB, and could be clobbered by code
inserted by the pass before a use in (e.g.) a different BB.

2021-01-13  Julian Brown  <julian@codesourcery.com>

gcc/
* config/gcn/gcn.c (gcn_md_reorg): Fix case where EXEC reg is live
on entry to a BB.

gcc/config/gcn/gcn.c

index 0fb9bd26727c256ba13eabed47d4b639e4fc70fb..630ce4eebc700ff596f08b2f31637d7e1d437a57 100644 (file)
@@ -4501,6 +4501,8 @@ gcn_md_reorg (void)
       df_insn_rescan_all ();
     }
 
+  df_live_add_problem ();
+  df_live_set_all_dirty ();
   df_analyze ();
 
   /* This pass ensures that the EXEC register is set correctly, according
@@ -4522,6 +4524,17 @@ gcn_md_reorg (void)
       int64_t curr_exec = 0;   /* 0 here means 'the value is that of EXEC
                                   after last_exec_def is executed'.  */
 
+      bitmap live_in = DF_LR_IN (bb);
+      bool exec_live_on_entry = false;
+      if (bitmap_bit_p (live_in, EXEC_LO_REG)
+         || bitmap_bit_p (live_in, EXEC_HI_REG))
+       {
+         if (dump_file)
+           fprintf (dump_file, "EXEC reg is live on entry to block %d\n",
+                    (int) bb->index);
+         exec_live_on_entry = true;
+       }
+
       FOR_BB_INSNS_SAFE (bb, insn, curr)
        {
          if (!NONDEBUG_INSN_P (insn))
@@ -4660,6 +4673,8 @@ gcn_md_reorg (void)
                         exec_lo_def_p == exec_hi_def_p ? "full" : "partial",
                         INSN_UID (insn));
            }
+
+         exec_live_on_entry = false;
        }
 
       COPY_REG_SET (&live, DF_LR_OUT (bb));
@@ -4669,7 +4684,7 @@ gcn_md_reorg (void)
         at the end of the block.  */
       if ((REGNO_REG_SET_P (&live, EXEC_LO_REG)
           || REGNO_REG_SET_P (&live, EXEC_HI_REG))
-         && (!curr_exec_known || !curr_exec_explicit))
+         && (!curr_exec_known || !curr_exec_explicit || exec_live_on_entry))
        {
          rtx_insn *end_insn = BB_END (bb);