[PATCH] Fix PR63419 testcsae

2014-10-15 Thread Richard Biener

Committed.

Richard.

2014-10-15  Richard Biener  rguent...@suse.de

* g++.dg/torture/pr63419.C: Add -Wno-psabi.

Index: gcc/testsuite/g++.dg/torture/pr63419.C
===
--- gcc/testsuite/g++.dg/torture/pr63419.C  (revision 216239)
+++ gcc/testsuite/g++.dg/torture/pr63419.C  (working copy)
@@ -1,4 +1,5 @@
 // { dg-do compile }
+// { dg-additional-options -Wno-psabi }
 
 typedef float __m128 __attribute__ ((__vector_size__ (16)));
 const int a = 0;


[PATCH] Fix PR63419

2014-10-10 Thread Richard Biener

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  rguent...@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.  */