https://gcc.gnu.org/g:f2e98084792821c3849074867d5b007c49028854

commit r14-10488-gf2e98084792821c3849074867d5b007c49028854
Author: Jan Hubicka <hubi...@ucw.cz>
Date:   Mon Jul 22 18:05:26 2024 +0200

    Fix accounting of offsets in unadjusted_ptr_and_unit_offset
    
    unadjusted_ptr_and_unit_offset accidentally throws away the offset computed 
by
    get_addr_base_and_unit_offset. Instead of passing extra_offset it passes 
offset.
    
            PR ipa/114207
    
    gcc/ChangeLog:
    
            * ipa-prop.cc (unadjusted_ptr_and_unit_offset): Fix accounting of 
offsets in ADDR_EXPR.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.c-torture/execute/pr114207.c: New test.
    
    (cherry picked from commit 391f46f10b0586c074014de82efe76787739bb0c)

Diff:
---
 gcc/ipa-prop.cc                                |  4 ++--
 gcc/testsuite/gcc.c-torture/execute/pr114207.c | 23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 374e998aa64b..99d4c33e8fdc 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -1370,9 +1370,9 @@ unadjusted_ptr_and_unit_offset (tree op, tree *ret, 
poly_int64 *offset_ret)
     {
       if (TREE_CODE (op) == ADDR_EXPR)
        {
-         poly_int64 extra_offset = 0;
+         poly_int64 extra_offset;
          tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
-                                                    &offset);
+                                                    &extra_offset);
          if (!base)
            {
              base = get_base_address (TREE_OPERAND (op, 0));
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr114207.c 
b/gcc/testsuite/gcc.c-torture/execute/pr114207.c
new file mode 100644
index 000000000000..052fa85e9fc6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr114207.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdint.h>
+
+struct S {
+    int a, b;
+};
+
+__attribute__((noinline))
+void foo (struct S *s) {
+    struct S ss = (struct S) {
+        .a = s->b,
+        .b = s->a
+    };
+    *s = ss;
+}
+
+int main() {
+  struct S s = {6, 12};
+  foo(&s);
+  if (s.a != 12 || s.b != 6)
+    __builtin_abort ();
+  return 0;
+}

Reply via email to