[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