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.
This commit is contained in:
Jan Hubicka 2024-07-22 19:00:39 +02:00
parent 05f0e9eec9
commit 1407477335
2 changed files with 32 additions and 0 deletions

View File

@ -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,

View File

@ -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;
}