diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2005-04-10 04:00:53 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2005-04-10 04:00:53 +0000 |
commit | 46382283d57b72ccb117f1b2f3735c7e0c252870 (patch) | |
tree | 24485e56e8b36a8e92b4e868e76b61bc02192114 /gcc/recog.c | |
parent | f7d7d3b779b8ade7cef279492981705ee9b5a577 (diff) | |
download | gcc-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.c | 40 |
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. */ |