From 5c8ef8c3944ede38b7b4bfa36c9c2697c050d999 Mon Sep 17 00:00:00 2001 From: sayle Date: Tue, 16 Dec 2003 02:22:59 +0000 Subject: PR middle-end/13400 * ifcvt.c (noce_process_if_block): Disable unconditional write optimizations if we could introduce a store to trapping memory that wasn't present previously. * gcc.c-torture/execute/20031215-1.c: New test case. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74663 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++ gcc/ifcvt.c | 19 ++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.c-torture/execute/20031215-1.c | 38 ++++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20031215-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc3def4ec09..950083c2712 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-12-15 Roger Sayle + + PR middle-end/13400 + * ifcvt.c (noce_process_if_block): Disable unconditional write + optimizations if we could introduce a store to trapping memory + that wasn't present previously. + 2003-12-15 Kazu Hirata * system.h (DEFAULT_CALLER_SAVES): Poison. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 4a13ba2a45b..8aba0d50efc 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1965,6 +1965,25 @@ noce_process_if_block (struct ce_if_block * ce_info) goto success; } + /* Disallow the "if (...) x = a;" form (with an implicit "else x = x;") + for most optimizations if writing to x may trap, i.e. its a memory + other than a static var or a stack slot. */ + if (! set_b + && GET_CODE (orig_x) == MEM + && ! MEM_NOTRAP_P (orig_x) + && rtx_addr_can_trap_p (XEXP (orig_x, 0))) + { + if (HAVE_conditional_move) + { + if (noce_try_cmove (&if_info)) + goto success; + if (! HAVE_conditional_execution + && noce_try_cmove_arith (&if_info)) + goto success; + } + return FALSE; + } + if (noce_try_move (&if_info)) goto success; if (noce_try_store_flag (&if_info)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8862f109ff2..96c0ee8a93e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-12-15 Roger Sayle + + PR middle-end/13400 + * gcc.c-torture/execute/20031215-1.c: New test case. + 2003-12-15 Mark Mitchell PR c++/13269 diff --git a/gcc/testsuite/gcc.c-torture/execute/20031215-1.c b/gcc/testsuite/gcc.c-torture/execute/20031215-1.c new file mode 100644 index 00000000000..d62177b2618 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20031215-1.c @@ -0,0 +1,38 @@ +/* PR middle-end/13400 */ +/* The following test used to fail at run-time with a write to read-only + memory, caused by if-conversion converting a conditional write into an + unconditional write. */ + +typedef struct {int c, l; char ch[3];} pstr; +const pstr ao = {2, 2, "OK"}; +const pstr * const a = &ao; + +void test1(void) +{ + if (a->ch[a->l]) { + ((char *)a->ch)[a->l] = 0; + } +} + +void test2(void) +{ + if (a->ch[a->l]) { + ((char *)a->ch)[a->l] = -1; + } +} + +void test3(void) +{ + if (a->ch[a->l]) { + ((char *)a->ch)[a->l] = 1; + } +} + +int main(void) +{ + test1(); + test2(); + test3(); + return 0; +} + -- cgit v1.2.1