]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
amdgcn: Fix register size bug
authorAndrew Stubbs <ams@codesourcery.com>
Fri, 17 Mar 2023 11:04:12 +0000 (11:04 +0000)
committerAndrew Stubbs <ams@codesourcery.com>
Fri, 17 Mar 2023 13:03:03 +0000 (13:03 +0000)
Fix an issue in which "vectors" of duplicate entries placed in scalar
registers caused the following 63 registers to be marked live, for the
purpose of prologue generation, which resulted in stack corruption.

gcc/ChangeLog:

* config/gcn/gcn.cc (gcn_class_max_nregs): Handle vectors in SGPRs.
(move_callee_saved_registers): Detect the bug condition early.

gcc/ChangeLog.omp
gcc/config/gcn/gcn.cc

index fdccdabf72b1bf0a715a543face2720f6a086885..c724308eba9b1a86cc6bbadfce07e366d04cba17 100644 (file)
@@ -1,3 +1,8 @@
+2023-03-17  Andrew Stubbs  <ams@codesourcery.com>
+
+       * config/gcn/gcn.cc (gcn_class_max_nregs): Handle vectors in SGPRs.
+       (move_callee_saved_registers): Detect the bug condition early.
+
 2023-03-17  Andrew Stubbs  <ams@codesourcery.com>
 
        Backport from mainline:
index 7403dfebcea0c12ffe6941faedd50f56b60b190d..2f48405f06f0645f2d94e48eb23cebdd17e5fac4 100644 (file)
@@ -503,6 +503,15 @@ gcn_class_max_nregs (reg_class_t rclass, machine_mode mode)
     }
   else if (rclass == VCC_CONDITIONAL_REG && mode == BImode)
     return 2;
+
+  /* Vector modes in SGPRs are not supposed to happen (disallowed by
+     gcn_hard_regno_mode_ok), but there are some patterns that have an "Sv"
+     constraint and are used by splitters, post-reload.
+     This ensures that we don't accidentally mark the following 63 scalar
+     registers as "live".  */
+  if (rclass == SGPR_REGS && VECTOR_MODE_P (mode))
+    return CEIL (GET_MODE_SIZE (GET_MODE_INNER (mode)), 4);
+
   return CEIL (GET_MODE_SIZE (mode), 4);
 }
 
@@ -3270,6 +3279,10 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
       emit_insn (move_vectors);
       emit_insn (move_scalars);
     }
+
+  /* This happens when a new register becomes "live" after reload.
+     Check your splitters!  */
+  gcc_assert (offset <= offsets->callee_saves);
 }
 
 /* Generate prologue.  Called from gen_prologue during pro_and_epilogue pass.