This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR27529, a step towards fixing PR27039


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" } } */



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]