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 PR63419


force_gimple_operand doesn't really do a "deep" verification
on its input when we ask for a non-simple result here.  Instead
it trusts that the CONSTRUCTOR PRE feeds it is valid GIMPLE.
Unfortunately that isn't so if its elements required a conversion.

The following fixes it by merging gimple_convert and its use
in PRE from match-and-simplify (which avoids force_gimple_operand
entirely in PRE).  The implementation of gimple_convert is of
course still using fold here.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2014-10-10  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/63419
	* gimple-fold.h (gimple_convert): New function.
	* gimple-fold.c (gimple_convert): Likewise.
	* tree-ssa-pre.c (create_expression_by_pieces): Use gimple_convert
	to split out required conversions early.

	* g++.dg/torture/pr63419.C: New testcase.

Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c	(revision 216069)
--- gcc/gimple-fold.c	(working copy)
*************** rewrite_to_defined_overflow (gimple stmt
*** 5282,5284 ****
--- 5282,5301 ----
  
    return stmts;
  }
+ 
+ /* Return OP converted to TYPE by emitting a conversion statement on SEQ
+    if required using location LOC.  Note that OP will be returned
+    unmodified if GIMPLE does not require an explicit conversion between
+    its type and TYPE.  */
+ 
+ tree
+ gimple_convert (gimple_seq *seq, location_t loc, tree type, tree op)
+ {
+   if (useless_type_conversion_p (type, TREE_TYPE (op)))
+     return op;
+   op = fold_convert_loc (loc, type, op);
+   gimple_seq stmts = NULL;
+   op = force_gimple_operand (op, &stmts, true, NULL_TREE);
+   gimple_seq_add_seq_without_update (seq, stmts);
+   return op;
+ }
Index: gcc/gimple-fold.h
===================================================================
*** gcc/gimple-fold.h	(revision 216069)
--- gcc/gimple-fold.h	(working copy)
*************** extern tree gimple_fold_indirect_ref (tr
*** 45,48 ****
--- 45,55 ----
  extern bool arith_code_with_undefined_signed_overflow (tree_code);
  extern gimple_seq rewrite_to_defined_overflow (gimple);
  
+ extern tree gimple_convert (gimple_seq *, location_t, tree, tree);
+ inline tree
+ gimple_convert (gimple_seq *seq, tree type, tree op)
+ {
+   return gimple_convert (seq, UNKNOWN_LOCATION, type, op);
+ }
+ 
  #endif  /* GCC_GIMPLE_FOLD_H */
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 216069)
--- gcc/tree-ssa-pre.c	(working copy)
*************** create_expression_by_pieces (basic_block
*** 2819,2830 ****
  	    if (nary->opcode == POINTER_PLUS_EXPR)
  	      {
  		if (i == 0)
! 		  genop[i] = fold_convert (nary->type, genop[i]);
  		else if (i == 1)
! 		  genop[i] = convert_to_ptrofftype (genop[i]);
  	      }
  	    else
! 	      genop[i] = fold_convert (TREE_TYPE (nary->op[i]), genop[i]);
  	  }
  	if (nary->opcode == CONSTRUCTOR)
  	  {
--- 2819,2833 ----
  	    if (nary->opcode == POINTER_PLUS_EXPR)
  	      {
  		if (i == 0)
! 		  genop[i] = gimple_convert (&forced_stmts,
! 					     nary->type, genop[i]);
  		else if (i == 1)
! 		  genop[i] = gimple_convert (&forced_stmts,
! 					     sizetype, genop[i]);
  	      }
  	    else
! 	      genop[i] = gimple_convert (&forced_stmts,
! 					 TREE_TYPE (nary->op[i]), genop[i]);
  	  }
  	if (nary->opcode == CONSTRUCTOR)
  	  {
*************** create_expression_by_pieces (basic_block
*** 2866,2873 ****
       statements.
       We have to call unshare_expr because force_gimple_operand may
       modify the tree we pass to it.  */
!   folded = force_gimple_operand (unshare_expr (folded), &forced_stmts,
  				 false, NULL);
  
    /* If we have any intermediate expressions to the value sets, add them
       to the value sets and chain them in the instruction stream.  */
--- 2869,2878 ----
       statements.
       We have to call unshare_expr because force_gimple_operand may
       modify the tree we pass to it.  */
!   gimple_seq tem = NULL;
!   folded = force_gimple_operand (unshare_expr (folded), &tem,
  				 false, NULL);
+   gimple_seq_add_seq_without_update (&forced_stmts, tem);
  
    /* If we have any intermediate expressions to the value sets, add them
       to the value sets and chain them in the instruction stream.  */


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