This fixes an oversight with the (p + o1) + o2 association with respect to abnormal-used SSA names. I've also added a single-use test so we don't add extra computations.
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2014-01-30 Richard Biener <rguent...@suse.de> PR tree-optimization/59993 * tree-ssa-forwprop.c (associate_pointerplus): Check we can propagate form the earlier stmt and avoid the transform when the intermediate result is needed. * gcc.dg/torture/pr59993.c: New testcase. Index: gcc/tree-ssa-forwprop.c =================================================================== *** gcc/tree-ssa-forwprop.c (revision 207299) --- gcc/tree-ssa-forwprop.c (working copy) *************** associate_pointerplus (gimple_stmt_itera *** 2926,2936 **** /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */ ptr = gimple_assign_rhs1 (stmt); off1 = gimple_assign_rhs2 (stmt); ! if (TREE_CODE (ptr) != SSA_NAME) return false; def_stmt = SSA_NAME_DEF_STMT (ptr); if (!is_gimple_assign (def_stmt) ! || gimple_assign_rhs_code (def_stmt) != POINTER_PLUS_EXPR) return false; ptr = gimple_assign_rhs1 (def_stmt); off2 = gimple_assign_rhs2 (def_stmt); --- 2926,2938 ---- /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */ ptr = gimple_assign_rhs1 (stmt); off1 = gimple_assign_rhs2 (stmt); ! if (TREE_CODE (ptr) != SSA_NAME ! || !has_single_use (ptr)) return false; def_stmt = SSA_NAME_DEF_STMT (ptr); if (!is_gimple_assign (def_stmt) ! || gimple_assign_rhs_code (def_stmt) != POINTER_PLUS_EXPR ! || !can_propagate_from (def_stmt)) return false; ptr = gimple_assign_rhs1 (def_stmt); off2 = gimple_assign_rhs2 (def_stmt); Index: gcc/testsuite/gcc.dg/torture/pr59993.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr59993.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr59993.c (working copy) *************** *** 0 **** --- 1,13 ---- + /* { dg-do compile } */ + + #include <setjmp.h> + + extern int optind; + jmp_buf jump_buf; + int + main (int argc, char **argv) + { + foo (jump_buf, setjmp(jump_buf)); + argv += optind; + bar(argv[1]); + }