Fix PR tree-optimization/86034

Message ID 14983703.7c19u95Jvh@polaris
State New
Headers show
Series
  • Fix PR tree-optimization/86034
Related show

Commit Message

Eric Botcazou June 3, 2018, 11:47 a.m.
This fixes an oversight in my GIMPLE store-merging patch, whereby masking out 
the bits of a signed type obviously fails to turn it into an unsigned type...
And since output_merged_store will now convert to the unsigned bitfield type, 
an existing conversion from a smaller type can be bypassed in process_store.

Tested on x86-64/Linux, applied on the mainline as obvious.


2018-06-03  Eric Botcazou  <ebotcazou@adacore.com>

	PR tree-optimization/86034
	* gimple-ssa-store-merging.c (output_merged_store): Convert the RHS to
	the unsigned bitfield type in a bit insertion sequence if it does not
	have a larger precision than the bitfield size.
	(process_store): Also bypass widening conversions for BIT_INSERT_EXPR.


2018-06-03  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.dg/torture/pr86034.c: New test.

-- 
Eric Botcazou

Patch

Index: gimple-ssa-store-merging.c
===================================================================
--- gimple-ssa-store-merging.c	(revision 261101)
+++ gimple-ssa-store-merging.c	(working copy)
@@ -3778,7 +3778,14 @@  imm_store_chain_info::output_merged_stor
 		  const HOST_WIDE_INT end_gap
 		    = (try_bitpos + try_size) - (info->bitpos + info->bitsize);
 		  tree tem = info->ops[0].val;
-		  if ((BYTES_BIG_ENDIAN ? start_gap : end_gap) > 0)
+		  if (TYPE_PRECISION (TREE_TYPE (tem)) <= info->bitsize)
+		    {
+		      tree bitfield_type
+			= build_nonstandard_integer_type (info->bitsize,
+							  UNSIGNED);
+		      tem = gimple_convert (&seq, loc, bitfield_type, tem);
+		    }
+		  else if ((BYTES_BIG_ENDIAN ? start_gap : end_gap) > 0)
 		    {
 		      const unsigned HOST_WIDE_INT imask
 			= (HOST_WIDE_INT_1U << info->bitsize) - 1;
@@ -4270,13 +4277,12 @@  pass_store_merging::process_store (gimpl
 	      || !multiple_p (bitpos, BITS_PER_UNIT))
 	  && const_bitsize <= 64)
 	{
-	  /* Bypass a truncating conversion to the bit-field type.  */
+	  /* Bypass a conversion to the bit-field type.  */
 	  if (is_gimple_assign (def_stmt) && CONVERT_EXPR_CODE_P (rhs_code))
 	    {
 	      tree rhs1 = gimple_assign_rhs1 (def_stmt);
 	      if (TREE_CODE (rhs1) == SSA_NAME
-		  && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
-		  && const_bitsize <= TYPE_PRECISION (TREE_TYPE (rhs1)))
+		  && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
 		rhs = rhs1;
 	    }
 	  rhs_code = BIT_INSERT_EXPR;