Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >Before the PR58956 fix find_replaceable_in_bb only gave up TER if >stmt was gimple_assign_single_p that was storing something that >could alias with TERed load, but now it also punts on calls (a lot of >them >apparently) and inline asm (all of them, because stmt_may_clobber_ref_p >always returns true for GIMPLE_ASM). I believe we can restore TERing >most of the cases for calls and inline asm though, because for calls >all arguments are necessarily evaluated before the call and the only >memory side effects of the call are the call itself and perhaps storing >of non-SSA_NAME return value afterwards. And for inline asm again >all input operands have to be evaluated before the inline asm, and the >only storing side-effects are again inside of the inline asm and >perhaps >storing of the output operands. > >Thus, this patch will only stop TERing if USE is used somewhere in >lhs of a call for calls or somewhere in output arguments of inline asm.
Can you please simply use walk_stmt_load_store_ops to get at the stmt outputs? Thanks, Richard. >Bootstrapped/regtested on x86_64-linux and i686-linux (both on trunk >and 4.8 >branch), ok for trunk/4.8? > >The reason I'd like to see this for 4.8 is to decrease the amount of >code >generation changes from pre-r205709 to minimum, as it can uncover other >latent bugs than just PR59470. > >2013-12-12 Jakub Jelinek <ja...@redhat.com> > > PR middle-end/58956 > PR middle-end/59470 > * tree-ssa-ter.c (find_ssa_name): New helper function. > (find_replaceable_in_bb): For calls, only set same_root_var > if USE is used somewhere in gimple_call_lhs, for GIMPLE_ASM, > only set same_root_var if USE is used somewhere in output operand > trees. > > * gcc.target/i386/pr59470.c: New test. > >--- gcc/tree-ssa-ter.c.jj 2013-12-10 08:52:13.000000000 +0100 >+++ gcc/tree-ssa-ter.c 2013-12-12 10:43:26.177866960 +0100 >@@ -554,6 +554,20 @@ mark_replaceable (temp_expr_table_p tab, > } > > >+/* Helper function for find_replaceable_in_bb. Called via walk_tree >to >+ find a SSA_NAME DATA somewhere in *TP. */ >+ >+static tree >+find_ssa_name (tree *tp, int *walk_subtrees, void *data) >+{ >+ tree var = (tree) data; >+ if (*tp == var) >+ return var; >+ else if (IS_TYPE_OR_DECL_P (*tp)) >+ *walk_subtrees = 0; >+ return NULL_TREE; >+} >+ >/* This function processes basic block BB, and looks for variables >which can >be replaced by their expressions. Results are stored in the table TAB. > */ > >@@ -618,7 +632,42 @@ find_replaceable_in_bb (temp_expr_table_ > && gimple_assign_single_p (def_stmt) > && stmt_may_clobber_ref_p (stmt, > gimple_assign_rhs1 (def_stmt))) >- same_root_var = true; >+ { >+ if (is_gimple_call (stmt)) >+ { >+ /* For calls, it is not a problem if USE is among >+ call's arguments or say OBJ_TYPE_REF argument, >+ all those necessarily need to be evaluated before >+ the call that may clobber the memory. But if >+ LHS of the call refers to USE, expansion might >+ evaluate it after the call, prevent TER in that >+ case. */ >+ if (gimple_call_lhs (stmt) >+ && TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME >+ && walk_tree (gimple_call_lhs_ptr (stmt), >+ find_ssa_name, use, NULL)) >+ same_root_var = true; >+ } >+ else if (gimple_code (stmt) == GIMPLE_ASM) >+ { >+ /* For inline asm, allow TER of loads into input >+ arguments, but disallow TER for USEs that occur >+ somewhere in outputs. */ >+ unsigned int i; >+ for (i = 0; i < gimple_asm_noutputs (stmt); i++) >+ if (TREE_CODE (gimple_asm_output_op (stmt, i)) >+ != SSA_NAME >+ && walk_tree (gimple_asm_output_op_ptr (stmt, >+ i), >+ find_ssa_name, use, NULL)) >+ { >+ same_root_var = true; >+ break; >+ } >+ } >+ else >+ same_root_var = true; >+ } > } > > /* Mark expression as replaceable unless stmt is volatile, or >the >--- gcc/testsuite/gcc.target/i386/pr59470.c.jj 2013-12-12 >10:31:54.746517544 +0100 >+++ gcc/testsuite/gcc.target/i386/pr59470.c 2013-12-12 >10:32:42.045273313 +0100 >@@ -0,0 +1,17 @@ >+/* PR middle-end/58956 */ >+/* PR middle-end/59470 */ >+/* { dg-do run } */ >+/* { dg-options "-O2" } */ >+ >+int a, b, d[1024]; >+ >+int >+main () >+{ >+ int c = a; >+ asm ("{movl $6, (%2); movl $1, %0|mov dword ptr [%2], 6; mov %0, 1}" >+ : "=r" (d[c]) : "rm" (b), "r" (&a) : "memory"); >+ if (d[0] != 1 || d[6] != 0) >+ __builtin_abort (); >+ return 0; >+} > > Jakub