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.
{
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));
--- /dev/null
+#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;
+}