Patchwork Avoid uninitialized padding bits in REAL_CST/CONST_DOUBLE (PR middle-end/47903)

login
register
mail settings
Submitter Jakub Jelinek
Date Feb. 27, 2011, 12:13 p.m.
Message ID <20110227121351.GC30899@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/84686/
State New
Headers show

Comments

Jakub Jelinek - Feb. 27, 2011, 12:13 p.m.
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.

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.


	Jakub
Richard Guenther - Feb. 27, 2011, 2:51 p.m.
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
>

Patch

--- 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.  */