Message ID | 20110227121351.GC30899@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Sun, Feb 27, 2011 at 1:13 PM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > In some places CONST_DOUBLE bits are compared as the HWIs, thus it is > undesirable to have uninitialized bits among them. At least on LP64 hosts > there are 32 bits of padding between uexp and sign fields. > Most of the places in gcc that work with REAL_VALUE_TYPE seem to actually > either clear the whole REAL_VALUE_TYPE by memset, or start by copying > to result one of the arguments. The exception seems to be real_arithmetic > for PLUS/MINUS/MULT/RDIV, where the result might be the same as either > of the operands, or might be completely different. Either real_arithmetic > in those 4 cases could compare result ptr with both operands and if it is > not equal to either of them, clear it, or the following patch adjusts > the callers where they do it. Hm, it seems fishy to compare CONST_DOUBLEs as HWIs if they have padding. But well - I guess it was always that way. That said, I still would prefer the clearing to be done in real_arithmetic. Just patching the existing callers won't save us from introducing more cases like this. Thanks, Richard. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2011-02-27 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/47903 > * fold-const.c (const_binop): Clear value first before > doing real_arithmetic into it. > * simplify-rtx.c (simplify_const_binary_operation): Likewise. > * builtins.c (fold_builtin_cbrt): Clear dconstroot first > before doing real_arithmetic into it. > (fold_builtin_modf): Clear frac first before doing real_arithmetic > into it. > > --- gcc/fold-const.c.jj 2011-02-15 15:25:53.000000000 +0100 > +++ gcc/fold-const.c 2011-02-26 16:03:22.000000000 +0100 > @@ -1163,6 +1163,8 @@ const_binop (enum tree_code code, tree a > else if (REAL_VALUE_ISNAN (d2)) > return arg2; > > + /* Make sure to clear any padding. */ > + memset (&value, '\0', sizeof (value)); > inexact = real_arithmetic (&value, code, &d1, &d2); > real_convert (&result, mode, &value); > > --- gcc/simplify-rtx.c.jj 2010-12-02 11:51:31.000000000 +0100 > +++ gcc/simplify-rtx.c 2011-02-26 16:06:38.000000000 +0100 > @@ -3310,6 +3310,8 @@ simplify_const_binary_operation (enum rt > /* Inf * 0 = NaN plus exception. */ > return 0; > > + /* Make sure to clear any padding. */ > + memset (&value, '\0', sizeof (value)); > inexact = real_arithmetic (&value, rtx_to_tree_code (code), > &f0, &f1); > real_convert (&result, mode, &value); > --- gcc/builtins.c.jj 2011-02-02 16:30:55.000000000 +0100 > +++ gcc/builtins.c 2011-02-26 16:02:49.000000000 +0100 > @@ -7335,6 +7335,8 @@ fold_builtin_cbrt (location_t loc, tree > tree tree_root; > REAL_VALUE_TYPE dconstroot; > > + /* Make sure to clear any padding. */ > + memset (&dconstroot, '\0', sizeof (dconstroot)); > real_arithmetic (&dconstroot, MULT_EXPR, > dconst_third_ptr (), dconst_third_ptr ()); > dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); > @@ -9576,6 +9578,8 @@ fold_builtin_modf (location_t loc, tree > case rvc_normal: > /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */ > real_trunc (&trunc, VOIDmode, value); > + /* Make sure to clear any padding. */ > + memset (&frac, '\0', sizeof (frac)); > real_arithmetic (&frac, MINUS_EXPR, value, &trunc); > /* If the original number was negative and already > integral, then the fractional part is -0.0. */ > > Jakub >
--- gcc/fold-const.c.jj 2011-02-15 15:25:53.000000000 +0100 +++ gcc/fold-const.c 2011-02-26 16:03:22.000000000 +0100 @@ -1163,6 +1163,8 @@ const_binop (enum tree_code code, tree a else if (REAL_VALUE_ISNAN (d2)) return arg2; + /* Make sure to clear any padding. */ + memset (&value, '\0', sizeof (value)); inexact = real_arithmetic (&value, code, &d1, &d2); real_convert (&result, mode, &value); --- gcc/simplify-rtx.c.jj 2010-12-02 11:51:31.000000000 +0100 +++ gcc/simplify-rtx.c 2011-02-26 16:06:38.000000000 +0100 @@ -3310,6 +3310,8 @@ simplify_const_binary_operation (enum rt /* Inf * 0 = NaN plus exception. */ return 0; + /* Make sure to clear any padding. */ + memset (&value, '\0', sizeof (value)); inexact = real_arithmetic (&value, rtx_to_tree_code (code), &f0, &f1); real_convert (&result, mode, &value); --- gcc/builtins.c.jj 2011-02-02 16:30:55.000000000 +0100 +++ gcc/builtins.c 2011-02-26 16:02:49.000000000 +0100 @@ -7335,6 +7335,8 @@ fold_builtin_cbrt (location_t loc, tree tree tree_root; REAL_VALUE_TYPE dconstroot; + /* Make sure to clear any padding. */ + memset (&dconstroot, '\0', sizeof (dconstroot)); real_arithmetic (&dconstroot, MULT_EXPR, dconst_third_ptr (), dconst_third_ptr ()); dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); @@ -9576,6 +9578,8 @@ fold_builtin_modf (location_t loc, tree case rvc_normal: /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */ real_trunc (&trunc, VOIDmode, value); + /* Make sure to clear any padding. */ + memset (&frac, '\0', sizeof (frac)); real_arithmetic (&frac, MINUS_EXPR, value, &trunc); /* If the original number was negative and already integral, then the fractional part is -0.0. */