On Thu, Aug 08, 2024 at 01:56:48PM -0600, Jeff Law wrote:
> > I haven't tested it extensively but it triggers at least for the current 
> > case.
> > I would have loved to also print the insn but couldn't figure out how to ICE
> > and stringify an insn.  I will have a look at this tomorrow.  Did you have 
> > any
> > place in mind where to put/call something like this?
> I didn't have anywhere specific in mind.   As I suspected the
> verify_rtl_sharing isn't a great fit from an implementation standpoint, but
> it seems right conceptually.

Right and since we are walking over all insns there anyway we could also
check pseudos on the go.  I didn't want to rename verify_rtl_sharing()
since this is publicly visible but renamed verify_insn_sharing() into
verify_insn_sharing_and_pseudo_references() to reflect the additional
work---although the name is bit of a mouthful.

> If you want to throw a patch over the wall for testing, happy to put it into
> my tester and see what comes out the other side.  I wouldn't be at all
> surprised if it tripped on other targets.

Having more testing would be great.  I've attached a new patch.

Cheers,
Stefan
>From 0199088d2877c9c840ce984f61365816879818bc Mon Sep 17 00:00:00 2001
From: Stefan Schulze Frielinghaus <stefa...@gcc.gnu.org>
Date: Fri, 9 Aug 2024 09:45:57 +0200
Subject: [PATCH] rtl: Verify pseudo register references

Ensure that each pseudo register referenced in an insn equals its
definition.  In particular this means that we error out if a pseudo
register is referenced in a different mode.
---
 gcc/emit-rtl.cc | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index cb04aa1a8c6..00af73ca219 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -3122,16 +3122,45 @@ reset_all_used_flags (void)
       }
 }
 
-/* Verify sharing in INSN.  */
+/* Verify that each pseudo register referenced in INSN equals its definition.
+   For example, error out if modes do not coincide. */
 
 static void
-verify_insn_sharing (rtx insn)
+verify_rtl_pseudo_references (rtx insn)
+{
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
+    {
+      const_rtx reg = *iter;
+      if (!reg || !REG_P (reg))
+       continue;
+      int regno = REGNO (reg);
+      /* Hard registers may be referenced in different modes.  */
+      if (HARD_REGISTER_NUM_P (regno))
+       continue;
+      const_rtx orig_reg = regno_reg_rtx[regno];
+      if (!rtx_equal_p (reg, orig_reg))
+       {
+         error ("pseudo register");
+         debug_rtx (orig_reg);
+         error ("does not coincide with its reference in insn");
+         debug_rtx (insn);
+         internal_error ("internal consistency failure");
+       }
+    }
+}
+
+/* Verify sharing and pseudo references in INSN.  */
+
+static void
+verify_insn_sharing_and_pseudo_references (rtx insn)
 {
   gcc_assert (INSN_P (insn));
   verify_rtx_sharing (PATTERN (insn), insn);
   verify_rtx_sharing (REG_NOTES (insn), insn);
   if (CALL_P (insn))
     verify_rtx_sharing (CALL_INSN_FUNCTION_USAGE (insn), insn);
+  verify_rtl_pseudo_references (insn);
 }
 
 /* Go through all the RTL insn bodies and check that there is no unexpected
@@ -3151,13 +3180,13 @@ verify_rtl_sharing (void)
       {
        rtx pat = PATTERN (p);
        if (GET_CODE (pat) != SEQUENCE)
-         verify_insn_sharing (p);
+         verify_insn_sharing_and_pseudo_references (p);
        else
          for (int i = 0; i < XVECLEN (pat, 0); i++)
              {
                rtx insn = XVECEXP (pat, 0, i);
                if (INSN_P (insn))
-                 verify_insn_sharing (insn);
+                 verify_insn_sharing_and_pseudo_references (insn);
              }
       }
 
-- 
2.45.2

Reply via email to