Handle POINTER_PLUS_EXPR in jump functions in ipa-modref.
authorJan Hubicka <jh@suse.cz>
Wed, 14 Oct 2020 14:01:39 +0000 (16:01 +0200)
committerJan Hubicka <jh@suse.cz>
Wed, 14 Oct 2020 14:01:39 +0000 (16:01 +0200)
gcc/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

gcc/ipa-modref.c
gcc/testsuite/gcc.dg/ipa/modref-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/modref-4.c [new file with mode: 0644]

index a6dfe1fc40128bb8245b3958de5169e6d73eae08..8e6a87643ecce490a682b179850759c069abc66b 100644 (file)
@@ -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 (file)
index 0000000..46eb78c
--- /dev/null
@@ -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 (file)
index 0000000..776f46e
--- /dev/null
@@ -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"  } } */