[PATCH] Fix PR57026
Richard Biener
rguenther@suse.de
Tue Apr 23 09:41:00 GMT 2013
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 <rguenther@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 <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend
More information about the Gcc-patches
mailing list