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]

Re: [PATCH] Fix PR middle-end/26635


> If it's OK with the other maintainers I'd prefer this to just be a simple
> global variable, like flag_evaluation_order  in flags.h rather than new
> command line option.  It should behave identically, can get for C/C++ in
> the same way, and provides the  same less intrusive workaround for the
> release branches. 

Revised patch attached.


2006-04-02  Eric Botcazou  <ebotcazou@adacore.com>

        PR middle-end/26635
	* flags.h (flag_modv): Declare.
        * c-common.c (c_common_nodes_and_builtins): Set flag_modv to 1.
        * convert.c (convert_to_integer): Don't narrow the type of a
        PLUS_EXPR or MINUS_EXPR if !flag_modv and the unwidened type
        is signed.
	* toplev.c (flag_modv): New global variable.


-- 
Eric Botcazou
Index: flags.h
===================================================================
--- flags.h	(revision 112529)
+++ flags.h	(working copy)
@@ -203,6 +203,10 @@ extern int frame_pointer_needed;
 /* Nonzero if subexpressions must be evaluated from left-to-right.  */
 extern int flag_evaluation_order;
 
+/* Nonzero if conversion-to-signed overflow is reduced
+   using modulo arithmetics.  */
+extern int flag_modv;
+
 /* Value of the -G xx switch, and whether it was passed or not.  */
 extern unsigned HOST_WIDE_INT g_switch_value;
 extern bool g_switch_set;
Index: c-common.c
===================================================================
--- c-common.c	(revision 112529)
+++ c-common.c	(working copy)
@@ -3350,6 +3350,9 @@ c_common_nodes_and_builtins (void)
 
   /* Since builtin_types isn't gc'ed, don't export these nodes.  */
   memset (builtin_types, 0, sizeof (builtin_types));
+
+  /* Result of conversion-to-signed overflow is implementation-defined.  */
+  flag_modv = 1;
 }
 
 /* Look up the function in built_in_decls that corresponds to DECL
Index: convert.c
===================================================================
--- convert.c	(revision 112529)
+++ convert.c	(working copy)
@@ -596,6 +596,17 @@ convert_to_integer (tree type, tree expr
 	    tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
 	    tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
 
+	    /* If we have neither flag_modv nor flag_wrapv, and either
+	       operand is of a signed type, we cannot narrow PLUS_EXPR
+	       or MINUS_EXPR because we would transform an overflow-proof
+	       expression in the wider type into an expression in the
+	       narrower type whose overflow behavior is undefined.  */
+	    if (!flag_modv && !flag_wrapv
+		&& (ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
+		&& (!TYPE_UNSIGNED (TREE_TYPE (arg0))
+		    || !TYPE_UNSIGNED (TREE_TYPE (arg1))))
+	      break;
+
 	    if (outprec >= BITS_PER_WORD
 		|| TRULY_NOOP_TRUNCATION (outprec, inprec)
 		|| inprec > TYPE_PRECISION (TREE_TYPE (arg0))
@@ -625,6 +636,10 @@ convert_to_integer (tree type, tree expr
 		       Exception: the LSHIFT_EXPR case above requires that
 		       we perform this operation unsigned lest we produce
 		       signed-overflow undefinedness.
+		       Exception: if we have flag_modv but !flag_wrapv, and
+		       either operand is of a signed type, we have to do
+		       PLUS_EXPR or MINUS_EXPR in an unsigned type lest we
+		       produce signed-overflow undefinedness.
 		       And we may need to do it as unsigned
 		       if we truncate to the original size.  */
 		    if (TYPE_UNSIGNED (TREE_TYPE (expr))
@@ -635,12 +650,7 @@ convert_to_integer (tree type, tree 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.  */
-			|| (!flag_wrapv
+			|| (flag_modv && !flag_wrapv
 			    && (ex_form == PLUS_EXPR
 				|| ex_form == MINUS_EXPR)
 			    && (!TYPE_UNSIGNED (TREE_TYPE (arg0))
Index: toplev.c
===================================================================
--- toplev.c	(revision 112529)
+++ toplev.c	(working copy)
@@ -372,6 +375,10 @@ lang_independent_options;
 /* Nonzero if subexpressions must be evaluated from left-to-right.  */
 int flag_evaluation_order = 0;
 
+/* Nonzero if conversion-to-signed overflow is reduced
+   using modulo arithmetics.  */
+int flag_modv = 0;
+
 /* The user symbol prefix after having resolved same.  */
 const char *user_label_prefix;
 

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