From: Andrew Pinski Date: Fri, 21 Nov 2025 06:39:48 +0000 (-0800) Subject: phiprop: Allow non-trapping loads to be proped back into the loop X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=952e145796da0f4dc96c42fdcabd75c8293d516c;p=thirdparty%2Fgcc.git phiprop: Allow non-trapping loads to be proped back into the loop First the testcase for PR60183 is no longer testing that we don't prop into the loops for possible trapping cases. This adds phiprop-4.c that tests that. Second we can prop back into loops if we know the load will not trap. This adds that check. phiprop-3.c tests that. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/60183 gcc/ChangeLog: * tree-ssa-phiprop.cc (propagate_with_phi): Allow known non-trapping loads to happen back into the loop. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/phiprop-3.c: New test. * gcc.dg/tree-ssa/phiprop-4.c: New test. Signed-off-by: Andrew Pinski --- diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c new file mode 100644 index 00000000000..59e95613c8c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-3.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-phiprop1-details" } */ + +/* PR tree-optimization/60183 */ + +unsigned char c; +extern unsigned char d; +int j = 2; + +unsigned long +foo (void) +{ + unsigned char *y = &c; + int i; + unsigned w = 0; + for (i = 0; i < j; i++) + { + w = *y; + y = &d; + } + return w; +} +/* the load from c/d does not trap so we should able to remove the phi. */ +/* { dg-final { scan-tree-dump "Removing dead stmt:" "phiprop1"} } */ +/* { dg-final { scan-tree-dump "Inserting PHI for result of load" "phiprop1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.c b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.c new file mode 100644 index 00000000000..ceb03edac74 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-4.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target { weak_undefined } } } */ +/* { dg-options "-O1 -fdump-tree-phiprop1-details" } */ +/* { dg-add-options weak_undefined } */ + +/* PR tree-optimization/60183 */ + +unsigned char c; +extern unsigned char d __attribute__((weak)); +int j = 2; + +unsigned long +foo (void) +{ + unsigned char *y = &c; + int i; + unsigned w = 0; + for (i = 0; i < j; i++) + { + w = *y; + y = &d; + } + return w; +} +/* the load from d can trap so this should not cause a phiprop. */ +/* { dg-final { scan-tree-dump-not "Removing dead stmt:" "phiprop1"} } */ +/* { dg-final { scan-tree-dump-not "Inserting PHI for result of load" "phiprop1"} } */ diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc index 897bd583ea7..124d06c8191 100644 --- a/gcc/tree-ssa-phiprop.cc +++ b/gcc/tree-ssa-phiprop.cc @@ -271,6 +271,7 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, return false; tree up_vuse = NULL_TREE; + bool canpossible_trap = false; /* Check if we can "cheaply" dereference all phi arguments. */ FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE) { @@ -289,7 +290,11 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, arg = gimple_assign_rhs1 (def_stmt); } if (TREE_CODE (arg) == ADDR_EXPR) - ; + { + tree decl = TREE_OPERAND (arg, 0); + if (!canpossible_trap) + canpossible_trap = tree_could_trap_p (decl); + } /* When we have an SSA name see if we previously encountered a dereference of it. */ else if (TREE_CODE (arg) == SSA_NAME @@ -335,9 +340,10 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, calculate_dominance_info (CDI_POST_DOMINATORS); /* Only replace loads in blocks that post-dominate the PHI node. That - makes sure we don't end up speculating loads. */ - if (!dominated_by_p (CDI_POST_DOMINATORS, - bb, gimple_bb (use_stmt))) + makes sure we don't end up speculating trapping loads. */ + if (canpossible_trap + && !dominated_by_p (CDI_POST_DOMINATORS, + bb, gimple_bb (use_stmt))) continue; /* Check whether this is a load of *ptr. */