Hi,
this patch adds logic to handle POINTER_PLUS_EXPR in compute_parm_map
that I originally did not since I tought that all such adjustments are
done by ancestor function.

Bootstrapped/regtested x86_64-linux, will commit it shortly.
Honza

gcc/ChangeLog:

2020-10-14  Jan Hubicka  <hubi...@ucw.cz>

        * ipa-modref.c (compute_parm_map): Handle POINTER_PLUS_EXPR in
        PASSTHROUGH.

gcc/testsuite/ChangeLog:

2020-10-14  Jan Hubicka  <hubi...@ucw.cz>

        * gcc.dg/ipa/modref-1.c: New test.
        * gcc.dg/tree-ssa/modref-4.c: New test.

diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index a6dfe1fc401..8e6a87643ec 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -1682,9 +1682,18 @@ compute_parm_map (cgraph_edge *callee_edge, 
vec<modref_parm_map> *parm_map)
            {
              (*parm_map)[i].parm_index
                = ipa_get_jf_pass_through_formal_id (jf);
-             (*parm_map)[i].parm_offset_known
-               = ipa_get_jf_pass_through_operation (jf) == NOP_EXPR;
-             (*parm_map)[i].parm_offset = 0;
+             if (ipa_get_jf_pass_through_operation (jf) == NOP_EXPR)
+               {
+                 (*parm_map)[i].parm_offset_known = true;
+                 (*parm_map)[i].parm_offset = 0;
+               }
+             else if (ipa_get_jf_pass_through_operation (jf)
+                      == POINTER_PLUS_EXPR
+                      && ptrdiff_tree_p (ipa_get_jf_pass_through_operand (jf),
+                                         &(*parm_map)[i].parm_offset))
+               (*parm_map)[i].parm_offset_known = true;
+             else
+               (*parm_map)[i].parm_offset_known = false;
              continue;
            }
          if (jf && jf->type == IPA_JF_ANCESTOR)
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-1.c 
b/gcc/testsuite/gcc.dg/ipa/modref-1.c
new file mode 100644
index 00000000000..46eb78ccebf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/modref-1.c
@@ -0,0 +1,23 @@
+/* { dg-options "-O2 -fdump-ipa-modref"  } */
+/* { dg-do compile } */
+__attribute__((noinline))
+void a(char *ptr, char *ptr2)
+{
+  (*ptr)++;
+  (*ptr2)++;
+}
+
+__attribute__((noinline))
+b(char *ptr)
+{
+  a(ptr+1,&ptr[2]);
+}
+main()
+{
+  char c[2]={0,1,0};
+  b(c);
+  return c[0]+c[2];
+}
+/* Check that both param offsets are determined correctly.  */
+/* { dg-final { scan-ipa-dump "param offset: 1" "modref"  } } */
+/* { dg-final { scan-ipa-dump "param offset: 2" "modref"  } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c 
b/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c
new file mode 100644
index 00000000000..776f46ed687
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c
@@ -0,0 +1,25 @@
+/* { dg-options "-O2 -fdump-tree-modref1"  } */
+/* { dg-do compile } */
+__attribute__((noinline))
+void a(char *ptr, char *ptr2)
+{
+  (*ptr)++;
+  (*ptr2)++;
+}
+
+__attribute__((noinline))
+b(char *ptr)
+{
+  a(ptr+1,&ptr[2]);
+}
+main()
+{
+  char c[2]={0,1,0};
+  b(c);
+  return c[0]+c[2];
+}
+/* Check that both param offsets are determined correctly and the computation
+   is optimized out.  */
+/* { dg-final { scan-tree-dump "param offset: 1" "modref1"  } } */
+/* { dg-final { scan-tree-dump "param offset: 2" "modref2"  } } */
+/* { dg-final { scan-tree-dump "return 0" "modref2"  } } */

Reply via email to