[PATCH] Fix PR27529, a step towards fixing PR27039
Richard Guenther
rguenther@suse.de
Wed May 10 20:32:00 GMT 2006
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@suse.de>
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" } } */
More information about the Gcc-patches
mailing list