gcc-patches@gcc.gnu.org
[Top] [All Lists]

[PATCH] Fix PR27529, a step towards fixing PR27039

Subject: [PATCH] Fix PR27529, a step towards fixing PR27039
From: Richard Guenther
Date: Wed, 10 May 2006 21:54:13 +0200 CEST
This fixes a missing folding opportunity in the presence of casts of
pointers with intermediate cast to integer and vice versa.  This is needed
to not regress in the testsuite if fixing PR27039 by always folding of
pointer comparisons in signed size type.

Bootstrapped and tested on x86_64-unknown-linux-gnu.
Ok for mainline?

Thanks,
Richard.

:ADDPATCH middle-end:

2006-05-10  Richard Guenther  <rguenther@xxxxxxx>

        PR middle-end/27529
        * fold-const.c (fold_unary): Handle intermediate conversion
        to a pointer type like intermediate conversion to an integer
        type in folding of (T1)(T2)var to var.
        Match the code to the comment in the final conversion for
        (T1)(T2)var to (T1)var regarding to type precision.  Rather
        than disallow T1 being of pointer type, assert that both T1
        and var are of pointer type or not.  Make sure not to fall
        over the frontends lazyness wrt array to pointer decay though.

        * gcc.dg/tree-ssa/foldcast-1.c: New testcase.

Index: fold-const.c
===================================================================
*** fold-const.c        (revision 113669)
--- fold-const.c        (working copy)
*************** fold_unary (enum tree_code code, tree ty
*** 7307,7313 ****
             type via an object of identical or wider precision, neither
             conversion is needed.  */
          if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
!             && ((inter_int && final_int) || (inter_float && final_float))
              && inter_prec >= final_prec)
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
  
--- 7323,7330 ----
             type via an object of identical or wider precision, neither
             conversion is needed.  */
          if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
!             && (((inter_int || inter_ptr) && final_int)
!                 || (inter_float && final_float))
              && inter_prec >= final_prec)
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
  
*************** fold_unary (enum tree_code code, tree ty
*** 7346,7355 ****
             - the initial type is a pointer type and the precisions of the
               intermediate and final types differ, or
             - the final type is a pointer type and the precisions of the
!              initial and intermediate types differ.  */
          if (! inside_float && ! inter_float && ! final_float
              && ! inside_vec && ! inter_vec && ! final_vec
!             && (inter_prec > inside_prec || inter_prec > final_prec)
              && ! (inside_int && inter_int
                    && inter_unsignedp != inside_unsignedp
                    && inter_prec < final_prec)
--- 7363,7375 ----
             - the initial type is a pointer type and the precisions of the
               intermediate and final types differ, or
             - the final type is a pointer type and the precisions of the
!              initial and intermediate types differ.
!            - the final type is a pointer type and the initial type not
!            - the initial type is a pointer to an array and the final type
!              not.  */
          if (! inside_float && ! inter_float && ! final_float
              && ! inside_vec && ! inter_vec && ! final_vec
!             && (inter_prec >= inside_prec || inter_prec >= final_prec)
              && ! (inside_int && inter_int
                    && inter_unsignedp != inside_unsignedp
                    && inter_prec < final_prec)
*************** fold_unary (enum tree_code code, tree ty
*** 7359,7365 ****
              && ! (final_ptr && inside_prec != inter_prec)
              && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
                    && TYPE_MODE (type) == TYPE_MODE (inter_type))
!             && ! final_ptr)
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
        }
  
--- 7379,7388 ----
              && ! (final_ptr && inside_prec != inter_prec)
              && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
                    && TYPE_MODE (type) == TYPE_MODE (inter_type))
!             && final_ptr == inside_ptr
!             && ! (inside_ptr
!                   && TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE
!                   && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
        }
  
Index: testsuite/gcc.dg/tree-ssa/foldcast-1.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/foldcast-1.c      (revision 0)
--- testsuite/gcc.dg/tree-ssa/foldcast-1.c      (revision 0)
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do "compile" } */
+ /* { dg-options "-fdump-tree-original" } */
+ 
+ typedef int ssize_t __attribute__((mode(pointer)));
+ ssize_t foo (ssize_t x)
+ {
+   return (ssize_t)(char *)x;
+ }
+ 
+ char *bar (char *x)
+ {
+   return (char *)(ssize_t)x;
+ }
+ 
+ /* { dg-final { scan-tree-dump-times "return x;" 2 "original" } } */
+ /* { dg-final { cleanup-tree-dump "original" } } */


<Prev in Thread] Current Thread [Next in Thread>