From: Jan Hubicka Date: Mon, 22 Jul 2024 17:00:39 +0000 (+0200) Subject: Fix modref's iteraction with store merging X-Git-Tag: basepoints/gcc-16~7348 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14074773350ffed7efdebbc553adf0f23b572e87;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc index f994388a96a..53a2e35133d 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 00000000000..1ea1c4dec07 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/pr111613.c @@ -0,0 +1,29 @@ +#include +#include + +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; +}