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]

Properly handle VIEW_CONVERT_EXPR in LHS (fixes 4.5 ACATS tests)


This fixes four ACATS tests (c45273a, ca11005, cc3019a, and cxaa010) and
changes c330001 from an ICE into an execution failure.

Testing is in progress on x86_64-linux-gnu.

There are two issues here.  First, if a VIEW_CONVERT_EXPR is on the LHS of
MODIFY_EXPR, you can't automatically assume that this will be a V_MUST_DEF.
Whether it's V_MUST_DEF or V_MAY_DEF still depends on whether there's a
component (or array, ...) reference on the LHS.  So we need to strip it off
before doing the test.

Second, in CCP, when you store a value, if the LHS had a VIEW_CONVERT_EXPR,
the value being stored is the wrong type and needs to be view-converted to
the proper type.

Do these patches look OK to you?

(The reason we need a VIEW_CONVERT_EXPR on the LHS is for the common case
where the thing being assigned is an indirect reference of a pointer to an
unconstrained record.  However, the value being assigned always has a
non-self-referential size (is constrained) and is often of constant size.  If
we put the V_C_E on the RHS, the MODIFY_EXPR will have self-referential size,
which involves a size computation and the use of memcpy.  Even if the RHS
isn't of fixed size, we avoid the size computation.  And if it is of fixed
size (even better, of *small* fixed size), we avoid the memcpy completely.)

2004-11-28  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* tree-ssa-operands.c (build_ssa_operands, case MODIFY_EXPR):
	Ignore a VIEW_CONVERT_EXPR on LHS when deciding if must or may def.
	* tree-ssa-ccp.c (visit_assignment): If LHS is a VIEW_CONVERT_EXPR,
	add an inverse VIEW_CONVERT_EXPR to const_val.

*** tree-ssa-operands.c	26 Nov 2004 15:42:36 -0000	2.58
--- tree-ssa-operands.c	28 Nov 2004 21:22:29 -0000
*************** build_ssa_operands (tree stmt, stmt_ann_
*** 894,911 ****
      {
      case MODIFY_EXPR:
!       get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none);
!       if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF 
! 	  || TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_RANGE_REF
! 	  || TREE_CODE (TREE_OPERAND (stmt, 0)) == COMPONENT_REF
! 	  || TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
! 	  || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR
! 	  /* Use a V_MAY_DEF if the RHS might throw, as the LHS won't be
! 	     modified in that case.  FIXME we should represent somehow
! 	     that it is killed on the fallthrough path.  */
! 	  || tree_could_throw_p (TREE_OPERAND (stmt, 1)))
!         get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def);
!       else
!         get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), 
! 	                   opf_is_def | opf_kill_def);
        break;
  
--- 894,924 ----
      {
      case MODIFY_EXPR:
!       /* First get operands from the RHS.  For the LHS, we use a V_MAY_DEF if
! 	 either only part of LHS is modified or if the RHS might throw,
! 	 otherwise, use V_MUST_DEF.
! 
! 	 ??? If it might throw, we should represent somehow that it is killed
! 	 on the fallthrough path.  */
!       {
! 	tree lhs = TREE_OPERAND (stmt, 0);
! 	int lhs_flags = opf_is_def;
! 
! 	get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none);
! 
! 	/* If the LHS is a VIEW_CONVERT_EXPR, it isn't changing whether
! 	   or not the entire LHS is modified; that depends on what's
! 	   inside the VIEW_CONVERT_EXPR.  */
! 	if (TREE_CODE (lhs) == VIEW_CONVERT_EXPR)
! 	  lhs = TREE_OPERAND (lhs, 0);
! 
! 	if (TREE_CODE (lhs) != ARRAY_REF && TREE_CODE (lhs) != ARRAY_RANGE_REF
! 	    && TREE_CODE (lhs) != COMPONENT_REF
! 	    && TREE_CODE (lhs) != BIT_FIELD_REF
! 	    && TREE_CODE (lhs) != REALPART_EXPR
! 	    && TREE_CODE (lhs) != IMAGPART_EXPR)
! 	  lhs_flags |= opf_kill_def;
! 
!         get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), lhs_flags);
!       }
        break;
  
*** tree-ssa-ccp.c	23 Nov 2004 01:27:41 -0000	2.51
--- tree-ssa-ccp.c	28 Nov 2004 21:22:30 -0000
*************** visit_assignment (tree stmt, tree *outpu
*** 1054,1072 ****
      }
    else
!     {
!       /* Evaluate the statement.  */
        val = evaluate_stmt (stmt);
-     }
  
!   /* FIXME: Hack.  If this was a definition of a bitfield, we need to widen
       the constant value into the type of the destination variable.  This
       should not be necessary if GCC represented bitfields properly.  */
    {
!     tree lhs = TREE_OPERAND (stmt, 0);
      if (val.lattice_val == CONSTANT
! 	&& TREE_CODE (lhs) == COMPONENT_REF
! 	&& DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
        {
! 	tree w = widen_bitfield (val.const_val, TREE_OPERAND (lhs, 1), lhs);
  
  	if (w && is_gimple_min_invariant (w))
--- 1052,1084 ----
      }
    else
!     /* Evaluate the statement.  */
        val = evaluate_stmt (stmt);
  
!   /* If the original LHS was a VIEW_CONVERT_EXPR, modify the constant
!      value to be a VIEW_CONVERT_EXPR of the old constant value.  This is
!      valid because a VIEW_CONVERT_EXPR is valid everywhere an operand of
!      aggregate type is valid.
! 
!      ??? Also, if this was a definition of a bitfield, we need to widen
       the constant value into the type of the destination variable.  This
       should not be necessary if GCC represented bitfields properly.  */
    {
!     tree orig_lhs = TREE_OPERAND (stmt, 0);
! 
!     if (TREE_CODE (orig_lhs) == VIEW_CONVERT_EXPR
! 	&& val.lattice_val == CONSTANT)
!       {
! 	val.const_val = build1 (VIEW_CONVERT_EXPR,
! 				TREE_TYPE (TREE_OPERAND (orig_lhs, 0)),
! 				val.const_val);
! 	orig_lhs = TREE_OPERAND (orig_lhs, 1);
!       }
! 
      if (val.lattice_val == CONSTANT
! 	&& TREE_CODE (orig_lhs) == COMPONENT_REF
! 	&& DECL_BIT_FIELD (TREE_OPERAND (orig_lhs, 1)))
        {
! 	tree w = widen_bitfield (val.const_val, TREE_OPERAND (orig_lhs, 1),
! 				 orig_lhs);
  
  	if (w && is_gimple_min_invariant (w))


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