Bug 38756 - 107t.ivopts introduces pointer truncation
107t.ivopts introduces pointer truncation
Status: UNCONFIRMED
Product: gcc
Classification: Unclassified
Component: middle-end
4.4.0
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-01-07 17:37 UTC by DJ Delorie
Modified: 2012-06-21 12:24 UTC (History)
4 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: m32c-elf
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description DJ Delorie 2009-01-07 17:37:30 UTC
When building gcc.c-torture/execute/20000412-6.c with -mcpu=m32c (pointers are 24 bits), ivopts introduces a truncation to "unsigned short" (sizetype, which is 16 bits) - truncating needed bits off the pointer.  107t.ivopts shows this:

 tmp_9 = tmp_16 + 2;
 D.1229_1 = (unsigned int) tmp_9;
 tmp_13 = (short unsigned int *) D.1229_1;
 if (bufend_6(D) > tmp_13)

which ends up being a PSI -> HI -> PSI conversion (PSI-SI-HI-SI-PSI in 128r.expand)
Comment 1 Peter A. Bigot 2012-06-21 11:34:15 UTC
I confirm this in 4.7.0.  It's due to rewrite_use_nonlinear_expr() not checking whether TYPE_PRECISION(ctype) < TYPE_PRECISION(utype) before doing the pointer adjustment in ctype and converting back to utype.

Something like this fixes it in my case:

      if (TYPE_PRECISION (ctype) < TYPE_PRECISION (utype))
	{
	  ctype = generic_type_for (utype);
	  step = fold_convert (ctype, unshare_expr (step));
	}
Comment 2 Richard Biener 2012-06-21 12:01:14 UTC
I can't see where you would place this change from looking at the function.
Comment 3 Peter A. Bigot 2012-06-21 12:04:34 UTC
commit af66de00843896ad5d2980952994b31cadbf8421
Author: Peter A. Bigot <pabigot@users.sourceforge.net>
Date:   Thu Jun 21 06:35:44 2012 -0500

    Anticipatory patch for PR middle-end/38756
    
    Do not truncate to size_type when adding the step factor to a pointer.

diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 0693c21..f8372fd 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -6199,6 +6199,11 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
       step = cand->iv->step;
       ctype = TREE_TYPE (step);
       utype = TREE_TYPE (cand->var_after);
+      if (TYPE_PRECISION (ctype) < TYPE_PRECISION (utype))
+       {
+         ctype = generic_type_for (utype);
+         step = fold_convert (ctype, unshare_expr (step));
+       }
       if (TREE_CODE (step) == NEGATE_EXPR)
        {
          incr_code = MINUS_EXPR;
Comment 4 rguenther@suse.de 2012-06-21 12:12:24 UTC
On Thu, 21 Jun 2012, bigotp at acm dot org wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38756
> 
> --- Comment #3 from Peter A. Bigot <bigotp at acm dot org> 2012-06-21 12:04:34 UTC ---
> commit af66de00843896ad5d2980952994b31cadbf8421
> Author: Peter A. Bigot <pabigot@users.sourceforge.net>
> Date:   Thu Jun 21 06:35:44 2012 -0500
> 
>     Anticipatory patch for PR middle-end/38756
> 
>     Do not truncate to size_type when adding the step factor to a pointer.
> 
> diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
> index 0693c21..f8372fd 100644
> --- a/gcc/tree-ssa-loop-ivopts.c
> +++ b/gcc/tree-ssa-loop-ivopts.c
> @@ -6199,6 +6199,11 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
>        step = cand->iv->step;
>        ctype = TREE_TYPE (step);
>        utype = TREE_TYPE (cand->var_after);
> +      if (TYPE_PRECISION (ctype) < TYPE_PRECISION (utype))
> +       {
> +         ctype = generic_type_for (utype);
> +         step = fold_convert (ctype, unshare_expr (step));
> +       }
>        if (TREE_CODE (step) == NEGATE_EXPR)
>         {
>           incr_code = MINUS_EXPR;

So the truncation happens here?

      /* Otherwise, add the necessary computations to express
         the iv.  */
      op = fold_convert (ctype, cand->var_before);
      comp = fold_convert (utype,
                           build2 (incr_code, ctype, op,
                                   unshare_expr (step)));

I think it makes sense to do the computation in
generic_type_for (utype) anyways - even if that truncates the
step.  Because we truncate to utype anyways.

Thus

      type = generic_type_for (utype);
      op = fold_convert (type, cand->var_before);
      comp = fold_convert (utype,
                           fold_build2 (incr_code, type, op,
					fold_convert (type, unshare_expr 
(step))));

unconditionally.
Comment 5 Peter A. Bigot 2012-06-21 12:24:38 UTC
Yes, that's where it happens.  Your proposal makes sense; I've just been trying to avoid changing existing behavior on "normal" platforms.

I'll give the unconditional solution a try on the next regression suite run.