aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2005-04-10 04:00:53 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2005-04-10 04:00:53 +0000
commit46382283d57b72ccb117f1b2f3735c7e0c252870 (patch)
tree24485e56e8b36a8e92b4e868e76b61bc02192114 /gcc/recog.c
parentf7d7d3b779b8ade7cef279492981705ee9b5a577 (diff)
downloadgcc-46382283d57b72ccb117f1b2f3735c7e0c252870.zip
gcc-46382283d57b72ccb117f1b2f3735c7e0c252870.tar.gz
gcc-46382283d57b72ccb117f1b2f3735c7e0c252870.tar.bz2
re PR target/20126 (Inlined memcmp makes one argument null on entry)
gcc/ChangeLog: PR target/20126 * loop.c (loop_givs_rescan): If replacement of DEST_ADDR failed, set the original address pseudo to the correct value before the original insn, if possible, and leave the insn alone, otherwise create a new pseudo, set it and replace it in the insn. * recog.c (validate_change_maybe_volatile): New. * recog.h (validate_change_maybe_volatile): Declare. gcc/testsuite/ChangeLog: * gcc.dg/pr20126.c: New. From-SVN: r97939
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index d81ae5b..836ebb3 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -235,6 +235,46 @@ validate_change (rtx object, rtx *loc, rtx new, int in_group)
return apply_change_group ();
}
+
+/* Function to be passed to for_each_rtx to test whether a piece of
+ RTL contains any mem/v. */
+static int
+volatile_mem_p (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+ return (MEM_P (*x) && MEM_VOLATILE_P (*x));
+}
+
+/* Same as validate_change, but doesn't support groups, and it accepts
+ volatile mems if they're already present in the original insn. */
+
+int
+validate_change_maybe_volatile (rtx object, rtx *loc, rtx new)
+{
+ int result;
+
+ if (validate_change (object, loc, new, 0))
+ return 1;
+
+ if (volatile_ok
+ /* If there isn't a volatile MEM, there's nothing we can do. */
+ || !for_each_rtx (&PATTERN (object), volatile_mem_p, 0)
+ /* Make sure we're not adding or removing volatile MEMs. */
+ || for_each_rtx (loc, volatile_mem_p, 0)
+ || for_each_rtx (&new, volatile_mem_p, 0)
+ || !insn_invalid_p (object))
+ return 0;
+
+ volatile_ok = 1;
+
+ gcc_assert (!insn_invalid_p (object));
+
+ result = validate_change (object, loc, new, 0);
+
+ volatile_ok = 0;
+
+ return result;
+}
+
/* This subroutine of apply_change_group verifies whether the changes to INSN
were valid; i.e. whether INSN can still be recognized. */