This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][no-undefined-overflow] Fix compile torture


This fixes the compile torture and most of the OMP ICEs.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the 
branch.

Richard.

2009-03-06  Richard Guenther  <rguenther@suse.de>

	* fold-const.c (fold_binary): Enable pointer re-association
	for POINTER_PLUSNV_EXPR.
	* gimplify.c (gimplify_expr): Handle POINTER_PLUSNV_EXPR.
	(gimplify_omp_for): Handle *NV_EXPR.
	* convert.c (convert_to_integer): Handle PLUSNV_EXPR and
	MINUSNV_EXPR in narrowing properly.  Remove use of
	TYPE_OVERFLOW_WRAPS.
	* omp-low.c (extract_omp_for_data): Handle *NV_EXPR.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c.orig	2009-03-05 17:30:39.000000000 +0100
--- gcc/fold-const.c	2009-03-05 17:30:41.000000000 +0100
*************** fold_binary (enum tree_code code, tree t
*** 10333,10348 ****
  	    return non_lvalue (fold_convert (type, arg0));
  	}
  
-       /* ???  Auditing required.  */
-       if (code == MINUSNV_EXPR)
- 	return NULL_TREE;
- 
        /* Pointer simplifications for subtraction, simple reassociations. */
        if (POINTER_TYPE_P (TREE_TYPE (arg1)) && POINTER_TYPE_P (TREE_TYPE (arg0)))
  	{
  	  /* (PTR0 p+ A) - (PTR1 p+ B) -> (PTR0 - PTR1) + (A - B) */
! 	  if (TREE_CODE (arg0) == POINTER_PLUS_EXPR
! 	      && TREE_CODE (arg1) == POINTER_PLUS_EXPR)
  	    {
  	      tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
  	      tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
--- 10333,10344 ----
  	    return non_lvalue (fold_convert (type, arg0));
  	}
  
        /* Pointer simplifications for subtraction, simple reassociations. */
        if (POINTER_TYPE_P (TREE_TYPE (arg1)) && POINTER_TYPE_P (TREE_TYPE (arg0)))
  	{
  	  /* (PTR0 p+ A) - (PTR1 p+ B) -> (PTR0 - PTR1) + (A - B) */
! 	  if (POINTER_PLUS_EXPR_P (arg0)
! 	      && POINTER_PLUS_EXPR_P (arg1))
  	    {
  	      tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
  	      tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
*************** fold_binary (enum tree_code code, tree t
*** 10352,10367 ****
  				  fold_build2 (MINUS_EXPR, type, arg00, arg10),
  				  fold_build2 (MINUS_EXPR, type, arg01, arg11));
  	    }
! 	  /* (PTR0 p+ A) - PTR1 -> (PTR0 - PTR1) + A, assuming PTR0 - PTR1 simplifies. */
! 	  else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
  	    {
  	      tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
  	      tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
! 	      tree tmp = fold_binary (MINUS_EXPR, type, arg00, fold_convert (type, arg1));
  	      if (tmp)
  	        return fold_build2 (PLUS_EXPR, type, tmp, arg01);
  	    }
  	}
        /* A - (-B) -> A + B */
        if (TREE_CODE (arg1) == NEGATE_EXPR)
  	return fold_build2 (PLUS_EXPR, type, op0,
--- 10348,10370 ----
  				  fold_build2 (MINUS_EXPR, type, arg00, arg10),
  				  fold_build2 (MINUS_EXPR, type, arg01, arg11));
  	    }
! 	  /* (PTR0 p+ A) - PTR1 -> (PTR0 - PTR1) + A, assuming
! 	     PTR0 - PTR1 simplifies. */
! 	  else if (POINTER_PLUS_EXPR_P (arg0))
  	    {
  	      tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
  	      tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
! 	      tree tmp = fold_binary (MINUS_EXPR, type, arg00,
! 				      fold_convert (type, arg1));
  	      if (tmp)
  	        return fold_build2 (PLUS_EXPR, type, tmp, arg01);
  	    }
  	}
+ 
+       /* ???  Auditing required.  */
+       if (code == MINUSNV_EXPR)
+ 	return NULL_TREE;
+ 
        /* A - (-B) -> A + B */
        if (TREE_CODE (arg1) == NEGATE_EXPR)
  	return fold_build2 (PLUS_EXPR, type, op0,
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2009-03-05 17:30:39.000000000 +0100
--- gcc/gimplify.c	2009-03-05 18:00:28.000000000 +0100
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 5885,5890 ****
--- 5885,5891 ----
  	  switch (TREE_CODE (t))
  	    {
  	    case PLUS_EXPR:
+ 	    case PLUSNV_EXPR:
  	      if (TREE_OPERAND (t, 1) == decl)
  		{
  		  TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 5894,5900 ****
--- 5895,5903 ----
  
  	      /* Fallthru.  */
  	    case MINUS_EXPR:
+ 	    case MINUSNV_EXPR:
  	    case POINTER_PLUS_EXPR:
+ 	    case POINTER_PLUSNV_EXPR:
  	      gcc_assert (TREE_OPERAND (t, 0) == decl);
  	      TREE_OPERAND (t, 0) = var;
  	      break;
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 5922,5930 ****
  		gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
  		gcc_assert (TREE_OPERAND (t, 0) == var);
  		t = TREE_OPERAND (t, 1);
! 		gcc_assert (TREE_CODE (t) == PLUS_EXPR
! 			    || TREE_CODE (t) == MINUS_EXPR
! 			    || TREE_CODE (t) == POINTER_PLUS_EXPR);
  		gcc_assert (TREE_OPERAND (t, 0) == var);
  		t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl,
  			    TREE_OPERAND (t, 1));
--- 5925,5933 ----
  		gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
  		gcc_assert (TREE_OPERAND (t, 0) == var);
  		t = TREE_OPERAND (t, 1);
! 		gcc_assert (PLUS_EXPR_P (t)
! 			    || MINUS_EXPR_P (t)
! 			    || POINTER_PLUS_EXPR_P (t));
  		gcc_assert (TREE_OPERAND (t, 0) == var);
  		t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl,
  			    TREE_OPERAND (t, 1));
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 6766,6771 ****
--- 6769,6775 ----
  	  break;
  
  	case POINTER_PLUS_EXPR:
+ 	case POINTER_PLUSNV_EXPR:
            /* Convert ((type *)A)+offset into &A->field_of_type_and_offset.
  	     The second is gimple immediate saving a need for extra statement.
  	   */
Index: gcc/convert.c
===================================================================
*** gcc/convert.c.orig	2009-03-05 17:30:39.000000000 +0100
--- gcc/convert.c	2009-03-05 17:30:41.000000000 +0100
*************** convert_to_integer (tree type, tree expr
*** 639,645 ****
--- 639,647 ----
  	  }
  
  	case PLUS_EXPR:
+ 	case PLUSNV_EXPR:
  	case MINUS_EXPR:
+ 	case MINUSNV_EXPR:
  	case BIT_AND_EXPR:
  	case BIT_IOR_EXPR:
  	case BIT_XOR_EXPR:
*************** convert_to_integer (tree type, tree expr
*** 686,704 ****
  				|| ex_form == RSHIFT_EXPR
  				|| ex_form == LROTATE_EXPR
  				|| ex_form == RROTATE_EXPR))
! 			|| ex_form == LSHIFT_EXPR
! 			/* If we have !flag_wrapv, and either ARG0 or
! 			   ARG1 is of a signed type, we have to do
! 			   PLUS_EXPR or MINUS_EXPR in an unsigned
! 			   type.  Otherwise, we would introduce
! 			   signed-overflow undefinedness.  */
! 			|| ((!TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0))
! 			     || !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
! 			    && (ex_form == PLUS_EXPR
! 				|| ex_form == MINUS_EXPR)))
  		      typex = unsigned_type_for (typex);
  		    else
  		      typex = signed_type_for (typex);
  		    return convert (type,
  				    fold_build2 (ex_form, typex,
  						 convert (typex, arg0),
--- 688,701 ----
  				|| ex_form == RSHIFT_EXPR
  				|| ex_form == LROTATE_EXPR
  				|| ex_form == RROTATE_EXPR))
! 			|| ex_form == LSHIFT_EXPR)
  		      typex = unsigned_type_for (typex);
  		    else
  		      typex = signed_type_for (typex);
+ 		    /* Even if the original expression didn't overflow
+ 		       the one in a different type might, so strip nv
+ 		       qualification here.  */
+ 		    ex_form = strip_nv (ex_form);
  		    return convert (type,
  				    fold_build2 (ex_form, typex,
  						 convert (typex, arg0),
Index: gcc/omp-low.c
===================================================================
*** gcc/omp-low.c.orig	2009-03-05 16:12:02.000000000 +0100
--- gcc/omp-low.c	2009-03-05 18:02:21.000000000 +0100
*************** extract_omp_for_data (gimple for_stmt, s
*** 334,343 ****
--- 334,346 ----
        switch (TREE_CODE (t))
  	{
  	case PLUS_EXPR:
+ 	case PLUSNV_EXPR:
  	case POINTER_PLUS_EXPR:
+ 	case POINTER_PLUSNV_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  break;
  	case MINUS_EXPR:
+ 	case MINUSNV_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  loop->step = fold_build1 (NEGATE_EXPR, TREE_TYPE (loop->step),
  				    loop->step);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]