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 PR38885


I'm testing a pair of patches to fix PR38885 (for constants)
and PR38884 (for non-constants) stores to complex/vector memory
and CSE of component accesses from SCCVN.

This is the piece that handles stores from constants and partial
reads of it.  We can conveniently re-use fold-const native
encode/interpret code for this.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2011-10-05  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/38885
	* tree-ssa-sccvn.c (vn_reference_lookup_3): Handle partial reads
	from constants.

	* gcc.dg/tree-ssa/ssa-fre-33.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 179549)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** vn_reference_lookup_3 (ao_ref *ref, tree
*** 1442,1448 ****
  	}
      }
  
!   /* 3) For aggregate copies translate the reference through them if
       the copy kills ref.  */
    else if (vn_walk_kind == VN_WALKREWRITE
  	   && gimple_assign_single_p (def_stmt)
--- 1442,1495 ----
  	}
      }
  
!   /* 3) Assignment from a constant.  We can use folds native encode/interpret
!      routines to extract the assigned bits.  */
!   else if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
! 	   && ref->size == maxsize
! 	   && maxsize % BITS_PER_UNIT == 0
! 	   && offset % BITS_PER_UNIT == 0
! 	   && is_gimple_reg_type (vr->type)
! 	   && gimple_assign_single_p (def_stmt)
! 	   && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
!     {
!       tree base2;
!       HOST_WIDE_INT offset2, size2, maxsize2;
!       base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
! 				       &offset2, &size2, &maxsize2);
!       if (maxsize2 != -1
! 	  && maxsize2 == size2
! 	  && size2 % BITS_PER_UNIT == 0
! 	  && offset2 % BITS_PER_UNIT == 0
! 	  && operand_equal_p (base, base2, 0)
! 	  && offset2 <= offset
! 	  && offset2 + size2 >= offset + maxsize)
! 	{
! 	  /* We support up to 512-bit values (for V8DFmode).  */
! 	  unsigned char buffer[64];
! 	  int len;
! 
! 	  len = native_encode_expr (gimple_assign_rhs1 (def_stmt),
! 				    buffer, sizeof (buffer));
! 	  if (len > 0)
! 	    {
! 	      tree val = native_interpret_expr (vr->type,
! 						buffer
! 						+ ((offset - offset2)
! 						   / BITS_PER_UNIT),
! 						ref->size / BITS_PER_UNIT);
! 	      if (val)
! 		{
! 		  unsigned int value_id = get_or_alloc_constant_value_id (val);
! 		  return vn_reference_insert_pieces
! 		           (vuse, vr->set, vr->type,
! 			    VEC_copy (vn_reference_op_s, heap, vr->operands),
! 			    val, value_id);
! 		}
! 	    }
! 	}
!     }
! 
!   /* 4) For aggregate copies translate the reference through them if
       the copy kills ref.  */
    else if (vn_walk_kind == VN_WALKREWRITE
  	   && gimple_assign_single_p (def_stmt)
*************** vn_reference_lookup_3 (ao_ref *ref, tree
*** 1540,1546 ****
        return NULL;
      }
  
!   /* 4) For memcpy copies translate the reference through them if
       the copy kills ref.  */
    else if (vn_walk_kind == VN_WALKREWRITE
  	   && is_gimple_reg_type (vr->type)
--- 1587,1593 ----
        return NULL;
      }
  
!   /* 5) For memcpy copies translate the reference through them if
       the copy kills ref.  */
    else if (vn_walk_kind == VN_WALKREWRITE
  	   && is_gimple_reg_type (vr->type)
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-33.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-33.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-33.c	(revision 0)
***************
*** 0 ****
--- 1,21 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-fre1-details" } */
+ 
+ #define vector __attribute__((vector_size(16) ))
+ 
+ struct {
+     float i;
+     vector float global_res;
+ } s;
+ float x;
+ int main(int argc)
+ {
+   vector float res = (vector float){0.0f,0.0f,0.0f,1.0f};
+   res += (vector float){1.0f,2.0f,3.0f,4.0f};
+   s.global_res = res;
+   x = *((float*)&s.global_res + 1);
+   return 0;
+ }
+ 
+ /* { dg-final { scan-tree-dump "Replaced BIT_FIELD_REF.*with 2" "fre1" } } */
+ /* { dg-final { cleanup-tree-dump "fre1" } } */


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