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][1/2] Basic middle-end support


It took me quite a while to dissect my work-in progress patch back
to a state that still bootstraps ...

So here is the initial enabling middle-end part.  It introduces
NEGATENV_EXPR, PLUSNV_EXPR, MINUSNV_EXPR, MULTNV_EXPR and
POINTER_PLUSNV_EXPR and updates places to support constant-folding
and expansion.  It also makes the middle-end macros
TYPE_OVERFLOW_WRAPS, TYPE_OVERFLOW_UNDEFINED and
POINTER_TYPE_OVERFLOW_UNDEFINED to always true, false, false
according to the general plan of no-undefined-overflow branch.

Bootstrapped and tested on x86_64-unknown-linux-gnu (C only) together
with patch [2/2] that enables C frontend support.

Some fun in the testresults, we have some vectorizer miscompiles
because of missed memory-reference re-construction...  that'll go
away with re-instantiating the foldings.

Branched and applied there (branches/no-undefined-overflow).

Richard.

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

	* expr.c (expand_expr_real_1): Handle POINTER_PLUSNV_EXPR,
	PLUSNV_EXPR, MINUSNV_EXPR, MULTNV_EXPR and NEGATENV_EXPR.
	* flags.h (TYPE_OVERFLOW_WRAPS): Define to always true.
	(TYPE_OVERFLOW_UNDEFINED): Define to always false.
	(POINTER_TYPE_OVERFLOW_UNDEFINED): Define to always false.
	* optabs.c (optab_for_tree_code): Handle *NV_EXPR.
	* tree-cfg.c (verify_gimple_assign_unary): Likewise.
	(verify_gimple_assign_binary): Likewise.
	* tree-inline.c (estimate_operator_cost): Likewise.
	* tree-pretty-print.c (dump_generic_node): Likewise.
	(op_code_prio): Likewise.
	(op_symbol_code): Likewise.
	* tree-ssa-structalias.c (find_func_aliases): Handle
	POINTER_PLUSNV_EXPR.
	* tree.c (build2_stat): Adjust checks.
	(associative_tree_code): Add PLUSNV_EXPR and MULTNV_EXPR.
	(commutative_tree_code): Add PLUSNV_EXPR and MULTNV_EXPR.
	(undefined_overflow_used_p_1): New function.
	* tree.def (PLUSNV_EXPR, MINUSNV_EXPR, MULTNV_EXPR,
	POINTER_PLUSNV_EXPR, NEGATENV_EXPR): New tree codes for
	operations that are known to not overflow.
	* tree.h (NEGATE_EXPR_CODE_P, PLUS_EXPR_CODE_P,
	POINTER_PLUS_EXPR_CODE_P, MINUS_EXPR_CODE_P, MULT_EXPR_CODE_P): New.
	(NEGATE_EXPR_P, PLUS_EXPR_P, POINTER_PLUS_EXPR_P, MINUS_EXPR_P,
	MULT_EXPR_P): Likewise.
	(strip_nv): New inline function.
	(undefined_overflow_used_p_1): Declare.
	(undefined_overflow_used_p): New inline function.
	* varasm.c (narrowing_initializer_constant_valid_p): Handle
	MINUSNV_EXPR.
	(initializer_constant_valid_p): Handle *NV_EXPR.
	* omp-low.c (omp_reduction_init): Likewise.
	* gimple-pretty-print.c (dump_unary_rhs): Handle NEGATENV_EXPR.
	* fold-const.c (fold_negate_expr): Likewise.
	(int_const_binop): Handle *NV_EXPR.
	(fold_unary): Handle NEGATENV_EXPR.
	(tree_binary_nonzero_warnv_p): The type argument is unused.
	(fold_binary): Handle simple cases for POINTER_PLUSNV_EXPR,
	PLUSNV_EXPR, MINUSNV_EXPR and MULTNV_EXPR.

Index: trunk/gcc/expr.c
===================================================================
*** trunk.orig/gcc/expr.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/expr.c	2009-03-05 12:34:00.000000000 +0100
*************** expand_expr_real_1 (tree exp, rtx target
*** 8331,8337 ****
  
        return op0;
  
!     case POINTER_PLUS_EXPR: 
        /* Even though the sizetype mode and the pointer's mode can be different
           expand is able to handle this correctly and get the correct result out 
           of the PLUS_EXPR code.  */
--- 8331,8338 ----
  
        return op0;
  
!     case POINTER_PLUS_EXPR:
!     case POINTER_PLUSNV_EXPR:
        /* Even though the sizetype mode and the pointer's mode can be different
           expand is able to handle this correctly and get the correct result out 
           of the PLUS_EXPR code.  */
*************** expand_expr_real_1 (tree exp, rtx target
*** 8344,8354 ****
  				    fold_convert (ssizetype,
  						  TREE_OPERAND (exp, 1))));
      case PLUS_EXPR:
  
        /* Check if this is a case for multiplication and addition.  */
        if ((TREE_CODE (type) == INTEGER_TYPE
  	   || TREE_CODE (type) == FIXED_POINT_TYPE)
! 	  && TREE_CODE (TREE_OPERAND (exp, 0)) == MULT_EXPR)
  	{
  	  tree subsubexp0, subsubexp1;
  	  enum tree_code code0, code1, this_code;
--- 8345,8356 ----
  				    fold_convert (ssizetype,
  						  TREE_OPERAND (exp, 1))));
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
  
        /* Check if this is a case for multiplication and addition.  */
        if ((TREE_CODE (type) == INTEGER_TYPE
  	   || TREE_CODE (type) == FIXED_POINT_TYPE)
! 	  && MULT_EXPR_P (TREE_OPERAND (exp, 0)))
  	{
  	  tree subsubexp0, subsubexp1;
  	  enum tree_code code0, code1, this_code;
*************** expand_expr_real_1 (tree exp, rtx target
*** 8405,8411 ****
  	 sp, ap, or fp is our second argument, in which case we must swap
  	 the innermost first argument and our second argument.  */
  
!       if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
  	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 1)) == INTEGER_CST
  	  && TREE_CODE (TREE_OPERAND (exp, 1)) == VAR_DECL
  	  && (DECL_RTL (TREE_OPERAND (exp, 1)) == frame_pointer_rtx
--- 8407,8413 ----
  	 sp, ap, or fp is our second argument, in which case we must swap
  	 the innermost first argument and our second argument.  */
  
!       if (PLUS_EXPR_P (TREE_OPERAND (exp, 0))
  	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 1)) == INTEGER_CST
  	  && TREE_CODE (TREE_OPERAND (exp, 1)) == VAR_DECL
  	  && (DECL_RTL (TREE_OPERAND (exp, 1)) == frame_pointer_rtx
*************** expand_expr_real_1 (tree exp, rtx target
*** 8508,8513 ****
--- 8510,8516 ----
        return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
  
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        /* Check if this is a case for multiplication and subtraction.  */
        if ((TREE_CODE (type) == INTEGER_TYPE
  	   || TREE_CODE (type) == FIXED_POINT_TYPE)
*************** expand_expr_real_1 (tree exp, rtx target
*** 8598,8603 ****
--- 8601,8607 ----
        goto binop2;
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
        /* If this is a fixed-point operation, then we cannot use the code
  	 below because "expand_mult" doesn't support sat/no-sat fixed-point
           multiplications.   */
*************** expand_expr_real_1 (tree exp, rtx target
*** 8818,8823 ****
--- 8822,8828 ----
        return target;
  
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
        op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget,
  			 VOIDmode, EXPAND_NORMAL);
        if (modifier == EXPAND_STACK_PARM)
Index: trunk/gcc/flags.h
===================================================================
*** trunk.orig/gcc/flags.h	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/flags.h	2009-03-05 12:34:00.000000000 +0100
*************** extern bool warn_disallowed_functions;
*** 345,352 ****
  
  /* True if overflow wraps around for the given integral type.  That
     is, TYPE_MAX + 1 == TYPE_MIN.  */
! #define TYPE_OVERFLOW_WRAPS(TYPE) \
!   (TYPE_UNSIGNED (TYPE) || flag_wrapv)
  
  /* True if overflow is undefined for the given integral type.  We may
     optimize on the assumption that values in the type never overflow.
--- 345,351 ----
  
  /* True if overflow wraps around for the given integral type.  That
     is, TYPE_MAX + 1 == TYPE_MIN.  */
! #define TYPE_OVERFLOW_WRAPS(TYPE) true
  
  /* True if overflow is undefined for the given integral type.  We may
     optimize on the assumption that values in the type never overflow.
*************** extern bool warn_disallowed_functions;
*** 356,363 ****
     it will be appropriate to issue the warning immediately, and in
     other cases it will be appropriate to simply set a flag and let the
     caller decide whether a warning is appropriate or not.  */
! #define TYPE_OVERFLOW_UNDEFINED(TYPE) \
!   (!TYPE_UNSIGNED (TYPE) && !flag_wrapv && !flag_trapv && flag_strict_overflow)
  
  /* True if overflow for the given integral type should issue a
     trap.  */
--- 355,361 ----
     it will be appropriate to issue the warning immediately, and in
     other cases it will be appropriate to simply set a flag and let the
     caller decide whether a warning is appropriate or not.  */
! #define TYPE_OVERFLOW_UNDEFINED(TYPE) false
  
  /* True if overflow for the given integral type should issue a
     trap.  */
*************** extern bool warn_disallowed_functions;
*** 365,371 ****
    (!TYPE_UNSIGNED (TYPE) && flag_trapv)
  
  /* True if pointer types have undefined overflow.  */
! #define POINTER_TYPE_OVERFLOW_UNDEFINED (flag_strict_overflow)
  
  /* Names for the different levels of -Wstrict-overflow=N.  The numeric
     values here correspond to N.  */
--- 363,369 ----
    (!TYPE_UNSIGNED (TYPE) && flag_trapv)
  
  /* True if pointer types have undefined overflow.  */
! #define POINTER_TYPE_OVERFLOW_UNDEFINED false
  
  /* Names for the different levels of -Wstrict-overflow=N.  The numeric
     values here correspond to N.  */
Index: trunk/gcc/optabs.c
===================================================================
*** trunk.orig/gcc/optabs.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/optabs.c	2009-03-05 12:34:00.000000000 +0100
*************** optab_for_tree_code (enum tree_code code
*** 490,511 ****
--- 490,516 ----
    switch (code)
      {
      case POINTER_PLUS_EXPR:
+     case POINTER_PLUSNV_EXPR:
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
        if (TYPE_SATURATING(type))
  	return TYPE_UNSIGNED(type) ? usadd_optab : ssadd_optab;
        return trapv ? addv_optab : add_optab;
  
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        if (TYPE_SATURATING(type))
  	return TYPE_UNSIGNED(type) ? ussub_optab : sssub_optab;
        return trapv ? subv_optab : sub_optab;
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
        if (TYPE_SATURATING(type))
  	return TYPE_UNSIGNED(type) ? usmul_optab : ssmul_optab;
        return trapv ? smulv_optab : smul_optab;
  
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
        if (TYPE_SATURATING(type))
  	return TYPE_UNSIGNED(type) ? usneg_optab : ssneg_optab;
        return trapv ? negv_optab : neg_optab;
Index: trunk/gcc/tree-cfg.c
===================================================================
*** trunk.orig/gcc/tree-cfg.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/tree-cfg.c	2009-03-05 12:34:00.000000000 +0100
*************** verify_gimple_assign_unary (gimple stmt)
*** 3397,3402 ****
--- 3397,3403 ----
        }
  
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
      case ABS_EXPR:
      case BIT_NOT_EXPR:
      case PAREN_EXPR:
*************** verify_gimple_assign_binary (gimple stmt
*** 3524,3529 ****
--- 3525,3531 ----
        }
  
      case POINTER_PLUS_EXPR:
+     case POINTER_PLUSNV_EXPR:
        {
  	if (!POINTER_TYPE_P (rhs1_type)
  	    || !useless_type_conversion_p (lhs_type, rhs1_type)
*************** verify_gimple_assign_binary (gimple stmt
*** 3581,3587 ****
--- 3583,3591 ----
        return verify_gimple_comparison (lhs_type, rhs1, rhs2);
  
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        {
  	if (POINTER_TYPE_P (lhs_type)
  	    || POINTER_TYPE_P (rhs1_type)
*************** verify_gimple_assign_binary (gimple stmt
*** 3596,3601 ****
--- 3600,3606 ----
        }
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
      case TRUNC_DIV_EXPR:
      case CEIL_DIV_EXPR:
      case FLOOR_DIV_EXPR:
Index: trunk/gcc/tree-inline.c
===================================================================
*** trunk.orig/gcc/tree-inline.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/tree-inline.c	2009-03-05 12:34:00.000000000 +0100
*************** estimate_operator_cost (enum tree_code c
*** 2753,2766 ****
--- 2753,2771 ----
      case VEC_COND_EXPR:
  
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
      case POINTER_PLUS_EXPR:
+     case POINTER_PLUSNV_EXPR:
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
      case MULT_EXPR:
+     case MULTNV_EXPR:
  
      case FIXED_CONVERT_EXPR:
      case FIX_TRUNC_EXPR:
  
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
      case FLOAT_EXPR:
      case MIN_EXPR:
      case MAX_EXPR:
Index: trunk/gcc/tree-pretty-print.c
===================================================================
*** trunk.orig/gcc/tree-pretty-print.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/tree-pretty-print.c	2009-03-05 12:34:00.000000000 +0100
*************** dump_generic_node (pretty_printer *buffe
*** 1261,1269 ****
--- 1261,1273 ----
      case WIDEN_SUM_EXPR:
      case WIDEN_MULT_EXPR:
      case MULT_EXPR:
+     case MULTNV_EXPR:
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
      case POINTER_PLUS_EXPR:
+     case POINTER_PLUSNV_EXPR:
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
      case TRUNC_DIV_EXPR:
      case CEIL_DIV_EXPR:
      case FLOOR_DIV_EXPR:
*************** dump_generic_node (pretty_printer *buffe
*** 1337,1342 ****
--- 1341,1347 ----
  
        /* Unary arithmetic and logic expressions.  */
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
      case BIT_NOT_EXPR:
      case TRUTH_NOT_EXPR:
      case ADDR_EXPR:
*************** op_code_prio (enum tree_code code)
*** 2332,2339 ****
--- 2337,2347 ----
  
      case WIDEN_SUM_EXPR:
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
      case POINTER_PLUS_EXPR:
+     case POINTER_PLUSNV_EXPR:
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        return 12;
  
      case VEC_WIDEN_MULT_HI_EXPR:
*************** op_code_prio (enum tree_code code)
*** 2341,2346 ****
--- 2349,2355 ----
      case WIDEN_MULT_EXPR:
      case DOT_PROD_EXPR:
      case MULT_EXPR:
+     case MULTNV_EXPR:
      case TRUNC_DIV_EXPR:
      case CEIL_DIV_EXPR:
      case FLOOR_DIV_EXPR:
*************** op_code_prio (enum tree_code code)
*** 2360,2365 ****
--- 2369,2375 ----
      case PREINCREMENT_EXPR:
      case PREDECREMENT_EXPR:
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
      case ALIGN_INDIRECT_REF:
      case MISALIGNED_INDIRECT_REF:
      case INDIRECT_REF:
*************** op_symbol_code (enum tree_code code)
*** 2504,2513 ****
--- 2514,2529 ----
  
      case POINTER_PLUS_EXPR:
        return "+";
+ 
+     case POINTER_PLUSNV_EXPR:
+       return "+/nv";
   
      case PLUS_EXPR:
        return "+";
  
+     case PLUSNV_EXPR:
+       return "+/nv";
+ 
      case REDUC_PLUS_EXPR:
        return "r+";
  
*************** op_symbol_code (enum tree_code code)
*** 2521,2526 ****
--- 2537,2546 ----
      case MINUS_EXPR:
        return "-";
  
+     case NEGATENV_EXPR:
+     case MINUSNV_EXPR:
+       return "-/nv";
+ 
      case BIT_NOT_EXPR:
        return "~";
  
*************** op_symbol_code (enum tree_code code)
*** 2531,2536 ****
--- 2551,2559 ----
      case INDIRECT_REF:
        return "*";
  
+     case MULTNV_EXPR:
+       return "*/nv";
+ 
      case ALIGN_INDIRECT_REF:
        return "A*";
  
Index: trunk/gcc/tree-ssa-structalias.c
===================================================================
*** trunk.orig/gcc/tree-ssa-structalias.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/tree-ssa-structalias.c	2009-03-05 12:34:00.000000000 +0100
*************** find_func_aliases (gimple origt)
*** 3866,3872 ****
  	  struct constraint_expr temp;
  	  get_constraint_for (lhsop, &lhsc);
  
! 	  if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR)
  	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
  					   gimple_assign_rhs2 (t), &rhsc);
  	  else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
--- 3866,3872 ----
  	  struct constraint_expr temp;
  	  get_constraint_for (lhsop, &lhsc);
  
! 	  if (POINTER_PLUS_EXPR_CODE_P (gimple_assign_rhs_code (t)))
  	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
  					   gimple_assign_rhs2 (t), &rhsc);
  	  else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/tree.c	2009-03-05 12:48:13.000000000 +0100
*************** build2_stat (enum tree_code code, tree t
*** 3288,3294 ****
  
    gcc_assert (TREE_CODE_LENGTH (code) == 2);
  
!   if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR)
        && arg0 && arg1 && tt && POINTER_TYPE_P (tt)
        /* When sizetype precision doesn't match that of pointers
           we need to be able to build explicit extensions or truncations
--- 3288,3296 ----
  
    gcc_assert (TREE_CODE_LENGTH (code) == 2);
  
!   if ((MINUS_EXPR_CODE_P (code)
!        || PLUS_EXPR_CODE_P (code)
!        || MULT_EXPR_CODE_P (code))
        && arg0 && arg1 && tt && POINTER_TYPE_P (tt)
        /* When sizetype precision doesn't match that of pointers
           we need to be able to build explicit extensions or truncations
*************** build2_stat (enum tree_code code, tree t
*** 3297,3303 ****
      gcc_assert (TREE_CODE (arg0) == INTEGER_CST
  		&& TREE_CODE (arg1) == INTEGER_CST);
  
!   if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
      gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
  		&& INTEGRAL_TYPE_P (TREE_TYPE (arg1))
  		&& useless_type_conversion_p (sizetype, TREE_TYPE (arg1)));
--- 3299,3305 ----
      gcc_assert (TREE_CODE (arg0) == INTEGER_CST
  		&& TREE_CODE (arg1) == INTEGER_CST);
  
!   if (POINTER_PLUS_EXPR_CODE_P (code) && arg0 && arg1 && tt)
      gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
  		&& INTEGRAL_TYPE_P (TREE_TYPE (arg1))
  		&& useless_type_conversion_p (sizetype, TREE_TYPE (arg1)));
*************** associative_tree_code (enum tree_code co
*** 5284,5290 ****
--- 5286,5294 ----
      case BIT_AND_EXPR:
      case BIT_XOR_EXPR:
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
      case MULT_EXPR:
+     case MULTNV_EXPR:
      case MIN_EXPR:
      case MAX_EXPR:
        return true;
*************** commutative_tree_code (enum tree_code co
*** 5303,5309 ****
--- 5307,5315 ----
    switch (code)
      {
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
      case MULT_EXPR:
+     case MULTNV_EXPR:
      case MIN_EXPR:
      case MAX_EXPR:
      case BIT_IOR_EXPR:
*************** block_ultimate_origin (const_tree block)
*** 9280,9283 ****
--- 9286,9316 ----
      }
  }
  
+ 
+ /* Returns true if operation CODE on type TYPE does not overflow because
+    overflow might have been undefined.  */
+ 
+ bool
+ undefined_overflow_used_p_1 (enum tree_code code, tree type)
+ {
+   if (flag_strict_overflow
+       && ((!flag_wrapv
+ 	   && INTEGRAL_TYPE_P (type)
+ 	   && !TYPE_UNSIGNED (type))
+ 	  || POINTER_TYPE_P (type)))
+     {
+       switch (code)
+ 	{
+ 	case NEGATENV_EXPR:
+ 	case PLUSNV_EXPR:
+ 	case MINUSNV_EXPR:
+ 	case MULTNV_EXPR:
+ 	  return true;
+ 	default:
+ 	  return false;
+ 	}
+     }
+   return false;
+ }
+ 
  #include "gt-tree.h"
Index: trunk/gcc/tree.def
===================================================================
*** trunk.orig/gcc/tree.def	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/tree.def	2009-03-05 12:34:00.000000000 +0100
*************** DEFTREECODE (PLACEHOLDER_EXPR, "placehol
*** 632,643 ****
--- 632,647 ----
  
  /* Simple arithmetic.  */
  DEFTREECODE (PLUS_EXPR, "plus_expr", tcc_binary, 2)
+ DEFTREECODE (PLUSNV_EXPR, "plusv_expr", tcc_binary, 2)
  DEFTREECODE (MINUS_EXPR, "minus_expr", tcc_binary, 2)
+ DEFTREECODE (MINUSNV_EXPR, "minusv_expr", tcc_binary, 2)
  DEFTREECODE (MULT_EXPR, "mult_expr", tcc_binary, 2)
+ DEFTREECODE (MULTNV_EXPR, "multv_expr", tcc_binary, 2)
  
  /* Pointer addition.  The first operand is always a pointer and the
     second operand is an integer of type sizetype.  */
  DEFTREECODE (POINTER_PLUS_EXPR, "pointer_plus_expr", tcc_binary, 2)
+ DEFTREECODE (POINTER_PLUSNV_EXPR, "pointer_plusv_expr", tcc_binary, 2)
  
  /* Division for integer result that rounds the quotient toward zero.  */
  DEFTREECODE (TRUNC_DIV_EXPR, "trunc_div_expr", tcc_binary, 2)
*************** DEFTREECODE (FLOAT_EXPR, "float_expr", t
*** 672,677 ****
--- 676,682 ----
  
  /* Unary negation.  */
  DEFTREECODE (NEGATE_EXPR, "negate_expr", tcc_unary, 1)
+ DEFTREECODE (NEGATENV_EXPR, "negatev_expr", tcc_unary, 1)
  
  /* Minimum and maximum values.  When used with floating point, if both
     operands are zeros, or if either operand is NaN, then it is unspecified
Index: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/tree.h	2009-03-05 12:48:42.000000000 +0100
*************** extern const enum tree_code_class tree_c
*** 177,182 ****
--- 177,223 ----
  
  #define EXPR_P(NODE) IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE)))
  
+ /* Returns true if the tree code is of a plain or non-overflowing kind.  */
+ 
+ #define NEGATE_EXPR_CODE_P(CODE) \
+     ((CODE) == NEGATE_EXPR || (CODE) == NEGATENV_EXPR)
+ #define PLUS_EXPR_CODE_P(CODE) \
+     ((CODE) == PLUS_EXPR || (CODE) == PLUSNV_EXPR)
+ #define POINTER_PLUS_EXPR_CODE_P(CODE) \
+     ((CODE) == POINTER_PLUS_EXPR \
+      || (CODE) == POINTER_PLUSNV_EXPR)
+ #define MINUS_EXPR_CODE_P(CODE) \
+     ((CODE) == MINUS_EXPR || (CODE) == MINUSNV_EXPR)
+ #define MULT_EXPR_CODE_P(CODE) \
+     ((CODE) == MULT_EXPR || (CODE) == MULTNV_EXPR)
+ 
+ /* Returns true if the expression is of a plain or non-overflowing kind.  */
+ 
+ #define NEGATE_EXPR_P(NODE) NEGATE_EXPR_CODE_P (TREE_CODE (NODE))
+ #define PLUS_EXPR_P(NODE) PLUS_EXPR_CODE_P (TREE_CODE (NODE))
+ #define POINTER_PLUS_EXPR_P(NODE) POINTER_PLUS_EXPR_CODE_P (TREE_CODE (NODE))
+ #define MINUS_EXPR_P(NODE) MINUS_EXPR_CODE_P (TREE_CODE (NODE))
+ #define MULT_EXPR_P(NODE) MULT_EXPR_CODE_P (TREE_CODE (NODE))
+ 
+ /* Returns an equivalent non-NV tree code for CODE.  */
+ static inline enum tree_code
+ strip_nv (enum tree_code code)
+ {
+   switch (code)
+     {
+     case NEGATENV_EXPR:
+       return NEGATE_EXPR;
+     case PLUSNV_EXPR:
+       return PLUS_EXPR;
+     case MINUSNV_EXPR:
+       return MINUS_EXPR;
+     case MULTNV_EXPR:
+       return MULT_EXPR;
+     default:
+       return code;
+     }
+ }
+ 
  /* Number of argument-words in each kind of tree-node.  */
  
  extern const unsigned char tree_code_length[];
*************** more_const_call_expr_args_p (const const
*** 5371,5374 ****
--- 5412,5425 ----
    for ((arg) = first_const_call_expr_arg ((call), &(iter)); (arg);	\
         (arg) = next_const_call_expr_arg (&(iter)))
  
+ bool undefined_overflow_used_p_1 (enum tree_code, tree);
+ 
+ /* Returns true if EXP does not overflow because overflow is undefined.  */
+ static inline bool
+ undefined_overflow_used_p (tree exp)
+ {
+   return (!TREE_NO_WARNING (exp)
+ 	  && undefined_overflow_used_p_1 (TREE_CODE (exp), TREE_TYPE (exp)));
+ }
+ 
  #endif  /* GCC_TREE_H  */
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/varasm.c	2009-03-05 12:34:00.000000000 +0100
*************** narrowing_initializer_constant_valid_p (
*** 4126,4132 ****
      {
        if (op0 == op1
  	  && (op0 == null_pointer_node
! 	      || TREE_CODE (value) == MINUS_EXPR))
  	return null_pointer_node;
  
        /* Support differences between labels.  */
--- 4126,4132 ----
      {
        if (op0 == op1
  	  && (op0 == null_pointer_node
! 	      || MINUS_EXPR_P (value)))
  	return null_pointer_node;
  
        /* Support differences between labels.  */
*************** initializer_constant_valid_p (tree value
*** 4301,4307 ****
--- 4301,4309 ----
        break;
  
      case POINTER_PLUS_EXPR:
+     case POINTER_PLUSNV_EXPR:
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
        if (! INTEGRAL_TYPE_P (endtype)
  	  || TYPE_PRECISION (endtype) >= POINTER_SIZE)
  	{
*************** initializer_constant_valid_p (tree value
*** 4324,4329 ****
--- 4326,4332 ----
        break;
  
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        if (! INTEGRAL_TYPE_P (endtype)
  	  || TYPE_PRECISION (endtype) >= POINTER_SIZE)
  	{
Index: trunk/gcc/omp-low.c
===================================================================
*** trunk.orig/gcc/omp-low.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/omp-low.c	2009-03-05 12:34:00.000000000 +0100
*************** omp_reduction_init (tree clause, tree ty
*** 2130,2136 ****
--- 2130,2138 ----
    switch (OMP_CLAUSE_REDUCTION_CODE (clause))
      {
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
      case BIT_IOR_EXPR:
      case BIT_XOR_EXPR:
      case TRUTH_OR_EXPR:
*************** omp_reduction_init (tree clause, tree ty
*** 2140,2145 ****
--- 2142,2148 ----
        return fold_convert (type, integer_zero_node);
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
      case TRUTH_AND_EXPR:
      case TRUTH_ANDIF_EXPR:
      case EQ_EXPR:
Index: trunk/gcc/gimple-pretty-print.c
===================================================================
*** trunk.orig/gcc/gimple-pretty-print.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/gimple-pretty-print.c	2009-03-05 12:34:00.000000000 +0100
*************** dump_unary_rhs (pretty_printer *buffer,
*** 299,304 ****
--- 299,306 ----
  	pp_character (buffer, '!');
        else if (rhs_code == NEGATE_EXPR)
  	pp_character (buffer, '-');
+       else if (rhs_code == NEGATENV_EXPR)
+ 	pp_string (buffer, "-/nv");
        else
  	{
  	  pp_character (buffer, '[');
Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c	2009-03-05 12:28:32.000000000 +0100
--- trunk/gcc/fold-const.c	2009-03-05 13:48:19.000000000 +0100
*************** fold_negate_expr (tree t)
*** 1292,1297 ****
--- 1292,1298 ----
        break;
  
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
        return TREE_OPERAND (t, 0);
  
      case PLUS_EXPR:
*************** int_const_binop (enum tree_code code, co
*** 1684,1699 ****
--- 1685,1703 ----
        break;
  
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
        overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
        break;
  
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        neg_double (int2l, int2h, &low, &hi);
        add_double (int1l, int1h, low, hi, &low, &hi);
        overflow = OVERFLOW_SUM_SIGN (hi, int2h, int1h);
        break;
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
        overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
        break;
  
*************** fold_unary (enum tree_code code, tree ty
*** 8412,8417 ****
--- 8416,8422 ----
        return fold_view_convert_expr (type, op0);
  
      case NEGATE_EXPR:
+     case NEGATENV_EXPR:
        tem = fold_negate_expr (arg0);
        if (tem)
  	return fold_convert (type, tem);
*************** tree_unary_nonzero_warnv_p (enum tree_co
*** 14887,14893 ****
  
  bool
  tree_binary_nonzero_warnv_p (enum tree_code code,
! 			     tree type,
  			     tree op0,
  			     tree op1, bool *strict_overflow_p)
  {
--- 14892,14898 ----
  
  bool
  tree_binary_nonzero_warnv_p (enum tree_code code,
! 			     tree type ATTRIBUTE_UNUSED,
  			     tree op0,
  			     tree op1, bool *strict_overflow_p)
  {


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