diff mbox series

Fix PR92280

Message ID nycvar.YFH.7.76.1911051424580.5566@zhemvz.fhfr.qr
State New
Headers show
Series Fix PR92280 | expand

Commit Message

Richard Biener Nov. 5, 2019, 1:28 p.m. UTC
This avoids folding

_1 = { _2, _3, _4, _5 };
_2 = BIT_FIELD_REF <_1, ..>;

to

_1 = { _2, _3, _4, _5 };
_2 = { _4, _5 };

when the first CTOR doesn't become dead.  This in turn makes FRE
handle partial loads from 

mem = _1;

by inserting BIT_FIELD_REFs on _1 (instead of CTORs which FRE refuses
to insert).  For gcc.target/i386/pr83008.c this means eliding the
memory and producing quite optimal code.

simplify_bitfield_ref used to need GENERIC folding for
BIT_FIELD_REF of CTOR but we since moved the folding to match.pd
and leaving the GENERIC call in defeats the single_use check.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2019-11-05  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/92280
	* match.pd (BIT_FIELD_REF of CTOR): Unless the original CTOR
	had a single use do not create a new CTOR.
	* tree-ssa-forwprop.c (simplify_bitfield_ref): Do not re-fold
	BIT_FIELD_REF of a CTOR via GENERIC.
diff mbox series

Patch

Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 277813)
+++ gcc/match.pd	(working copy)
@@ -5565,15 +5565,19 @@  (define_operator_list COND_TERNARY
 	 (if (elt < CONSTRUCTOR_NELTS (ctor))
 	  (view_convert { CONSTRUCTOR_ELT (ctor, elt)->value; })
 	  { build_zero_cst (type); })
-	 {
-	   vec<constructor_elt, va_gc> *vals;
-	   vec_alloc (vals, count);
-	   for (unsigned i = 0;
-		i < count && elt + i < CONSTRUCTOR_NELTS (ctor); ++i)
-	     CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
-				     CONSTRUCTOR_ELT (ctor, elt + i)->value);
-	   build_constructor (type, vals);
-	 })))
+	 /* We don't want to emit new CTORs unless the old one goes away.
+	    ???  Eventually allow this if the CTOR ends up constant or
+	    uniform.  */
+	 (if (single_use (@0))
+	  {
+	    vec<constructor_elt, va_gc> *vals;
+	    vec_alloc (vals, count);
+	    for (unsigned i = 0;
+		 i < count && elt + i < CONSTRUCTOR_NELTS (ctor); ++i)
+	      CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
+				      CONSTRUCTOR_ELT (ctor, elt + i)->value);
+	    build_constructor (type, vals);
+	  }))))
       /* The bitfield references a single constructor element.  */
       (if (k.is_constant (&const_k)
 	   && idx + n <= (idx / const_k + 1) * const_k)
Index: gcc/tree-ssa-forwprop.c
===================================================================
--- gcc/tree-ssa-forwprop.c	(revision 277813)
+++ gcc/tree-ssa-forwprop.c	(working copy)
@@ -1786,7 +1786,7 @@  simplify_bitfield_ref (gimple_stmt_itera
 {
   gimple *stmt = gsi_stmt (*gsi);
   gimple *def_stmt;
-  tree op, op0, op1, op2;
+  tree op, op0, op1;
   tree elem_type;
   unsigned idx, size;
   enum tree_code code;
@@ -1804,20 +1804,7 @@  simplify_bitfield_ref (gimple_stmt_itera
     return false;
 
   op1 = TREE_OPERAND (op, 1);
-  op2 = TREE_OPERAND (op, 2);
   code = gimple_assign_rhs_code (def_stmt);
-
-  if (code == CONSTRUCTOR)
-    {
-      tree tem = fold_ternary (BIT_FIELD_REF, TREE_TYPE (op),
-			       gimple_assign_rhs1 (def_stmt), op1, op2);
-      if (!tem || !valid_gimple_rhs_p (tem))
-	return false;
-      gimple_assign_set_rhs_from_tree (gsi, tem);
-      update_stmt (gsi_stmt (*gsi));
-      return true;
-    }
-
   elem_type = TREE_TYPE (TREE_TYPE (op0));
   if (TREE_TYPE (op) != elem_type)
     return false;