Referencing a register in different modes
Stefan Schulze Frielinghaus
stefansf@linux.ibm.com
Fri Aug 9 07:49:02 GMT 2024
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
-------------- next part --------------
>From 0199088d2877c9c840ce984f61365816879818bc Mon Sep 17 00:00:00 2001
From: Stefan Schulze Frielinghaus <stefansf@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
More information about the Gcc
mailing list