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][C-Family] Disable bogus shortening of DFP vs FP compare


On the match-and-simplify branch we expose an issue in shorten_compare
which happily transforms (double) float-var != (double) dfp-float-var
to (float) float-var != (float) dfp-float-var which is wrong
and causes

FAIL: c-c++-common/dfp/convert-bfp-12.c  -std=c++11 execution test
FAIL: c-c++-common/dfp/convert-bfp-12.c  -std=c++1y execution test
FAIL: c-c++-common/dfp/convert-bfp-12.c  -std=c++98 execution test

you can expose this latent bug by making get_narrower also
treat CONVERT_EXPRs as conversions - on trunk the DFP value
happens to be converted to double using that.

You then also run into the issue that the C frontend rejects
the compare via its common_type implementation which complains
about a mixed FP - DFP compare.

So the following patch which I am testing right now disables
the (premature) shorten-compare optimization on mixed
FP - DFP operands.  It also exposes the issue on trunk by
improving get_narrower.

Ok for trunk either with or without the tree.c hunk?  (I'm
going to remove that if it exposes more issues elsewhere
revealed by testing)

Thanks,
Richard.

2014-11-04  Richard Biener  <rguenther@suse.de>

	* tree.c (get_narrower): Also look through CONVERT_EXPRs.

	c-family/
	* c-common.c (shorten_compare): Do not shorten mixed
	DFP and non-DFP compares.

Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 217049)
+++ gcc/tree.c	(working copy)
@@ -8494,7 +8494,7 @@ get_narrower (tree op, int *unsignedp_pt
   tree win = op;
   bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
 
-  while (TREE_CODE (op) == NOP_EXPR)
+  while (CONVERT_EXPR_P (op))
     {
       int bitschange
 	= (TYPE_PRECISION (TREE_TYPE (op))
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 217049)
+++ gcc/c-family/c-common.c	(working copy)
@@ -4314,9 +4314,15 @@ shorten_compare (location_t loc, tree *o
   /* If either arg is decimal float and the other is float, find the
      proper common type to use for comparison.  */
   else if (real1 && real2
+	   && DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop0)))
+	   && DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop1))))
+    type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
+
+  /* If either arg is decimal float and the other is float, fail.  */
+  else if (real1 && real2
 	   && (DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop0)))
 	       || DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop1)))))
-    type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
+    return 0;
 
   else if (real1 && real2
 	   && (TYPE_PRECISION (TREE_TYPE (primop0))


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