aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2024-07-22 19:00:39 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2024-07-28 19:05:45 +0200
commit087a28832a28543872386e6e98692e1b9ea93bdf (patch)
tree1b75646bb8434a4012cf6f1ce90f32ae5e2d9973
parent2a3e29507eafc2d5c9119ea138c3d6257e89e459 (diff)
downloadgcc-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.cc3
-rw-r--r--gcc/testsuite/gcc.c-torture/pr111613.c29
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;
+}