On Tue, 4 Nov 2014, Richard Biener wrote: > > 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)
I removed it - it fails very early in stage2 with a warning about an always-true comparison. No time to sort that out at this point. So consider this a c-common.c change only. Thanks, Richard. > 2014-11-04 Richard Biener <rguent...@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)) > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendoerffer, HRB 21284 (AG Nuernberg) Maxfeldstrasse 5, 90409 Nuernberg, Germany