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" } } */