On Mon, 22 Apr 2013, Richard Biener wrote: > > VRP happily propagates SSA names even if they are used in > abnormal PHI nodes which later can lead to coalescing issues. > The following fixes that. > > It also fixes the recursion abnormal edge added for setjmp. > setjmp is leaf (and not longjmp which I already fixed with > the original patch). > > Bootstrap / regtest in progress on x86_64-unknown-linux-gnu.
Committed only the VRP part for now, need to investigate an issue with the rest. Richard. > Richard. > > 2013-04-22 Richard Biener <rguent...@suse.de> > > PR tree-optimization/57026 > * calls.c (special_function_p): setjmp and friends are ECF_LEAF. > * builtins.def (BUILT_IN_SETJMP): Mark ATTR_NOTHROW_LEAF_LIST. > * tree-vrp.c (simplify_conversion_using_ranges): Do not propagate > from SSA names occuring in abnormal PHI nodes. > > * gcc.dg/torture/pr57026.c: New testcase. > > Index: gcc/calls.c > =================================================================== > *** gcc/calls.c (revision 198135) > --- gcc/calls.c (working copy) > *************** special_function_p (const_tree fndecl, i > *** 545,551 **** > && ! strcmp (tname, "sigsetjmp")) > || (tname[1] == 'a' > && ! strcmp (tname, "savectx"))) > ! flags |= ECF_RETURNS_TWICE; > > if (tname[1] == 'i' > && ! strcmp (tname, "siglongjmp")) > --- 545,551 ---- > && ! strcmp (tname, "sigsetjmp")) > || (tname[1] == 'a' > && ! strcmp (tname, "savectx"))) > ! flags |= ECF_RETURNS_TWICE | ECF_LEAF; > > if (tname[1] == 'i' > && ! strcmp (tname, "siglongjmp")) > *************** special_function_p (const_tree fndecl, i > *** 557,563 **** > && ! strcmp (tname, "vfork")) > || (tname[0] == 'g' && tname[1] == 'e' > && !strcmp (tname, "getcontext"))) > ! flags |= ECF_RETURNS_TWICE; > > else if (tname[0] == 'l' && tname[1] == 'o' > && ! strcmp (tname, "longjmp")) > --- 557,563 ---- > && ! strcmp (tname, "vfork")) > || (tname[0] == 'g' && tname[1] == 'e' > && !strcmp (tname, "getcontext"))) > ! flags |= ECF_RETURNS_TWICE | ECF_LEAF; > > else if (tname[0] == 'l' && tname[1] == 'o' > && ! strcmp (tname, "longjmp")) > Index: gcc/builtins.def > =================================================================== > *** gcc/builtins.def (revision 198135) > --- gcc/builtins.def (working copy) > *************** DEF_LIB_BUILTIN (BUILT_IN_REALLOC > *** 732,738 **** > DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, > ATTR_NORETURN_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", > BT_FN_PTR_UINT, ATTR_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, > ATTR_NULL) > ! DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL) > DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", > BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4) > DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", > BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, > ATTR_FORMAT_STRFTIME_NOTHROW_3_0) > DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, > ATTR_NORETURN_NOTHROW_LEAF_LIST) > --- 732,738 ---- > DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, > ATTR_NORETURN_NOTHROW_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", > BT_FN_PTR_UINT, ATTR_LEAF_LIST) > DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, > ATTR_NULL) > ! DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, > ATTR_NOTHROW_LEAF_LIST) > DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", > BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4) > DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", > BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, > ATTR_FORMAT_STRFTIME_NOTHROW_3_0) > DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, > ATTR_NORETURN_NOTHROW_LEAF_LIST) > Index: gcc/tree-vrp.c > =================================================================== > *** gcc/tree-vrp.c (revision 198135) > --- gcc/tree-vrp.c (working copy) > *************** simplify_conversion_using_ranges (gimple > *** 8752,8758 **** > || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))) > return false; > innerop = gimple_assign_rhs1 (def_stmt); > ! if (TREE_CODE (innerop) != SSA_NAME) > return false; > > /* Get the value-range of the inner operand. */ > --- 8752,8759 ---- > || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))) > return false; > innerop = gimple_assign_rhs1 (def_stmt); > ! if (TREE_CODE (innerop) != SSA_NAME > ! || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)) > return false; > > /* Get the value-range of the inner operand. */ > Index: gcc/testsuite/gcc.dg/torture/pr57026.c > =================================================================== > *** gcc/testsuite/gcc.dg/torture/pr57026.c (revision 0) > --- gcc/testsuite/gcc.dg/torture/pr57026.c (working copy) > *************** > *** 0 **** > --- 1,22 ---- > + /* { dg-do compile } */ > + > + typedef struct __jmp_buf_tag { char buf[1024]; } jmp_buf[1]; > + extern int setjmp (jmp_buf); > + extern int bar (unsigned int *); > + extern jmp_buf *baz (void); > + struct C { int c1; unsigned int c2, c3, c4; }; > + > + void > + foo (struct C *x, const int *y, unsigned int *z, unsigned int e, unsigned > int g) > + { > + unsigned int d = 0; > + unsigned long f; > + setjmp (*baz ()); > + f = d; > + if ((x->c1 || x->c2) && g && (!e || d >= 8)) > + d = 16; > + else > + d = 8; > + if ((!x->c3 && !x->c4 || *y == 0) && !e && bar (z)) > + *z = f; > + } > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend