public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-2165] cprop_hardreg: fix ORIGINAL_REGNO/REG_ATTRS/REG_POINTER handling
@ 2023-06-28 14:06 Philipp Tomsich
  0 siblings, 0 replies; only message in thread
From: Philipp Tomsich @ 2023-06-28 14:06 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:893883f2f8f56984209c6ed210ee992ff71a14b0

commit r14-2165-g893883f2f8f56984209c6ed210ee992ff71a14b0
Author: Manolis Tsamis <manolis.tsamis@vrull.eu>
Date:   Tue Jun 20 16:23:52 2023 +0200

    cprop_hardreg: fix ORIGINAL_REGNO/REG_ATTRS/REG_POINTER handling
    
    Fixes: 6a2e8dcbbd4bab3
    
    Propagation for the stack pointer in regcprop was enabled in
    6a2e8dcbbd4bab3, but set ORIGINAL_REGNO/REG_ATTRS/REG_POINTER for
    stack_pointer_rtx which caused regression (e.g., PR 110313, PR 110308).
    
    This fix adds special handling for stack_pointer_rtx in the places
    where maybe_mode_change is called. This also adds an check in
    maybe_mode_change to return the stack pointer only when the requested
    mode matches the mode of stack_pointer_rtx.
    
            PR debug/110308
    
    gcc/ChangeLog:
    
            * regcprop.cc (maybe_mode_change): Check stack_pointer_rtx mode.
            (maybe_copy_reg_attrs): New function.
            (find_oldest_value_reg): Use maybe_copy_reg_attrs.
            (copyprop_hardreg_forward_1): Ditto.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/torture/pr110308.C: New test.
    
    Signed-off-by: Manolis Tsamis <manolis.tsamis@vrull.eu>
    Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>

Diff:
---
 gcc/regcprop.cc                         | 52 +++++++++++++++++++++++----------
 gcc/testsuite/g++.dg/torture/pr110308.C | 29 ++++++++++++++++++
 2 files changed, 65 insertions(+), 16 deletions(-)

diff --git a/gcc/regcprop.cc b/gcc/regcprop.cc
index 6cbfadb181f..d28a4d5aca8 100644
--- a/gcc/regcprop.cc
+++ b/gcc/regcprop.cc
@@ -423,7 +423,7 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode,
      It's unclear if we need to do the same for other special registers.  */
   if (regno == STACK_POINTER_REGNUM)
     {
-      if (orig_mode == new_mode)
+      if (orig_mode == new_mode && new_mode == GET_MODE (stack_pointer_rtx))
 	return stack_pointer_rtx;
       else
 	return NULL_RTX;
@@ -451,6 +451,31 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode,
   return NULL_RTX;
 }
 
+/* Helper function to copy attributes when replacing OLD_REG with NEW_REG.
+   If the changes required for NEW_REG are invalid return NULL_RTX, otherwise
+   return NEW_REG.  This is intended to be used with maybe_mode_change.  */
+
+static rtx
+maybe_copy_reg_attrs (rtx new_reg, rtx old_reg)
+{
+  if (new_reg != stack_pointer_rtx)
+    {
+      /* NEW_REG is assumed to be a register copy resulting from
+	 maybe_mode_change.  */
+      ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (old_reg);
+      REG_ATTRS (new_reg) = REG_ATTRS (old_reg);
+      REG_POINTER (new_reg) = REG_POINTER (old_reg);
+    }
+  else if (REG_POINTER (new_reg) != REG_POINTER (old_reg))
+    {
+      /* Only a single instance of STACK_POINTER_RTX must exist and we cannot
+	 modify it.  Allow propagation if REG_POINTER for OLD_REG matches and
+	 don't touch ORIGINAL_REGNO and REG_ATTRS.  */
+      return NULL_RTX;
+    }
+  return new_reg;
+}
+
 /* Find the oldest copy of the value contained in REGNO that is in
    register class CL and has mode MODE.  If found, return an rtx
    of that oldest register, otherwise return NULL.  */
@@ -486,12 +511,7 @@ find_oldest_value_reg (enum reg_class cl, rtx reg, struct value_data *vd)
 
       new_rtx = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i, regno);
       if (new_rtx)
-	{
-	  ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (reg);
-	  REG_ATTRS (new_rtx) = REG_ATTRS (reg);
-	  REG_POINTER (new_rtx) = REG_POINTER (reg);
-	  return new_rtx;
-	}
+	return maybe_copy_reg_attrs (new_rtx, reg);
     }
 
   return NULL_RTX;
@@ -965,15 +985,15 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
 
 		  if (validate_change (insn, &SET_SRC (set), new_rtx, 0))
 		    {
-		      ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (src);
-		      REG_ATTRS (new_rtx) = REG_ATTRS (src);
-		      REG_POINTER (new_rtx) = REG_POINTER (src);
-		      if (dump_file)
-			fprintf (dump_file,
-				 "insn %u: replaced reg %u with %u\n",
-				 INSN_UID (insn), regno, REGNO (new_rtx));
-		      changed = true;
-		      goto did_replacement;
+		      if (maybe_copy_reg_attrs (new_rtx, src))
+			{
+			  if (dump_file)
+			    fprintf (dump_file,
+				     "insn %u: replaced reg %u with %u\n",
+				     INSN_UID (insn), regno, REGNO (new_rtx));
+			  changed = true;
+			  goto did_replacement;
+			}
 		    }
 		  /* We need to re-extract as validate_change clobbers
 		     recog_data.  */
diff --git a/gcc/testsuite/g++.dg/torture/pr110308.C b/gcc/testsuite/g++.dg/torture/pr110308.C
new file mode 100644
index 00000000000..36c6d382121
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr110308.C
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+int channelCount, decodeBlock_outputLength;
+struct BlockCodec {
+  virtual int decodeBlock(const unsigned char *, short *);
+};
+struct ms_adpcm_state {
+  char predictorIndex;
+  int sample1;
+  ms_adpcm_state();
+};
+bool decodeBlock_ok;
+void encodeBlock() { ms_adpcm_state(); }
+struct MSADPCM : BlockCodec {
+  int decodeBlock(const unsigned char *, short *);
+};
+void decodeSample(ms_adpcm_state, bool *);
+int MSADPCM::decodeBlock(const unsigned char *, short *) {
+  ms_adpcm_state decoderState[2];
+  ms_adpcm_state *state[2];
+  state[0] = &decoderState[0];
+  if (channelCount == 2)
+    state[1] = &decoderState[0];
+  short m_coefficients[state[1]->predictorIndex];
+  for (int i = 0; i < channelCount; i++)
+    ++state[i]->sample1;
+  decodeSample(*state[1], &decodeBlock_ok);
+  return decodeBlock_outputLength;
+}
\ No newline at end of file

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-28 14:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-28 14:06 [gcc r14-2165] cprop_hardreg: fix ORIGINAL_REGNO/REG_ATTRS/REG_POINTER handling Philipp Tomsich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).