diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2024-07-22 19:00:39 +0200 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2024-07-28 19:05:45 +0200 |
commit | 087a28832a28543872386e6e98692e1b9ea93bdf (patch) | |
tree | 1b75646bb8434a4012cf6f1ce90f32ae5e2d9973 | |
parent | 2a3e29507eafc2d5c9119ea138c3d6257e89e459 (diff) | |
download | gcc-087a28832a28543872386e6e98692e1b9ea93bdf.zip gcc-087a28832a28543872386e6e98692e1b9ea93bdf.tar.gz gcc-087a28832a28543872386e6e98692e1b9ea93bdf.tar.bz2 |
Fix modref's iteraction with store merging
Hi,
this patch fixes wrong code in case store-merging introduces load of function
parameter that was previously write-only (which happens for bitfields).
Without this, the whole store-merged area is consdered to be killed.
PR ipa/111613
gcc/ChangeLog:
* ipa-modref.cc (analyze_parms): Do not preserve EAF_NO_DIRECT_READ and
EAF_NO_INDIRECT_READ from past flags.
gcc/testsuite/ChangeLog:
* gcc.c-torture/pr111613.c: New test.
-rw-r--r-- | gcc/ipa-modref.cc | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/pr111613.c | 29 |
2 files changed, 32 insertions, 0 deletions
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc index f994388..53a2e35 100644 --- a/gcc/ipa-modref.cc +++ b/gcc/ipa-modref.cc @@ -3004,6 +3004,9 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto, (past, ecf_flags, VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))); + /* Store merging can produce reads when combining together multiple + bitfields. See PR111613. */ + past &= ~(EAF_NO_DIRECT_READ | EAF_NO_INDIRECT_READ); if (dump_file && (flags | past) != flags && !(flags & EAF_UNUSED)) { fprintf (dump_file, diff --git a/gcc/testsuite/gcc.c-torture/pr111613.c b/gcc/testsuite/gcc.c-torture/pr111613.c new file mode 100644 index 0000000..1ea1c4d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/pr111613.c @@ -0,0 +1,29 @@ +#include <stdio.h> +#include <stdlib.h> + +struct bitfield { + unsigned int field1 : 1; + unsigned int field2 : 1; + unsigned int field3 : 1; +}; + +__attribute__((noinline)) static void +set_field1_and_field2(struct bitfield *b) { + b->field1 = 1; + b->field2 = 1; +} + +__attribute__((noinline)) static struct bitfield * +new_bitfield(void) { + struct bitfield *b = (struct bitfield *)malloc(sizeof(*b)); + b->field3 = 1; + set_field1_and_field2(b); + return b; +} + +int main(void) { + struct bitfield *b = new_bitfield(); + if (b->field3 != 1) + __builtin_abort (); + return 0; +} |