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]

Re: RFA: Fix SRA bug on big-endian targets


"Richard Guenther" <richard.guenther@gmail.com> writes:
> Ok if you make
>
>> +         vpos = (BYTES_BIG_ENDIAN
>> +                 ? size_binop (MINUS_EXPR, TYPE_SIZE (type), blen)
>> +                 : bitsize_int (0));
>
> a regular if () and add a comment before it (in both places).

OK, thanks, here's what I committed after making sure that the testcase
still worked on both targets.

Richard


gcc/
	* tree-sra.c (scalarize_use): Adjust the vpos argument to
	sra_explode_bitfield_assignment in cases where the type is
	wider than the bitfield.

Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c	(revision 130407)
+++ gcc/tree-sra.c	(working copy)
@@ -3147,7 +3147,7 @@ scalarize_use (struct sra_elt *elt, tree
       if (!elt->use_block_copy)
 	{
 	  tree type = TREE_TYPE (bfexpr);
-	  tree var = make_rename_temp (type, "SR"), tmp, st;
+	  tree var = make_rename_temp (type, "SR"), tmp, st, vpos;
 
 	  GIMPLE_STMT_OPERAND (stmt, 0) = var;
 	  update = true;
@@ -3162,8 +3162,16 @@ scalarize_use (struct sra_elt *elt, tree
 	      var = tmp;
 	    }
 
+	  /* If VAR is wider than BLEN bits, it is padded at the
+	     most-significant end.  We want to set VPOS such that
+	     <BIT_FIELD_REF VAR BLEN VPOS> would refer to the
+	     least-significant BLEN bits of VAR.  */
+	  if (BYTES_BIG_ENDIAN)
+	    vpos = size_binop (MINUS_EXPR, TYPE_SIZE (type), blen);
+	  else
+	    vpos = bitsize_int (0);
 	  sra_explode_bitfield_assignment
-	    (var, bitsize_int (0), false, &listafter, blen, bpos, elt);
+	    (var, vpos, false, &listafter, blen, bpos, elt);
 	}
       else
 	sra_sync_for_bitfield_assignment
@@ -3199,7 +3207,7 @@ scalarize_use (struct sra_elt *elt, tree
       if (!elt->use_block_copy)
 	{
 	  tree type = TREE_TYPE (bfexpr);
-	  tree var;
+	  tree var, vpos;
 
 	  if (!TYPE_UNSIGNED (type))
 	    type = unsigned_type_for (type);
@@ -3210,8 +3218,16 @@ scalarize_use (struct sra_elt *elt, tree
 				    (var, build_int_cst_wide (type, 0, 0)),
 				    &list);
 
+	  /* If VAR is wider than BLEN bits, it is padded at the
+	     most-significant end.  We want to set VPOS such that
+	     <BIT_FIELD_REF VAR BLEN VPOS> would refer to the
+	     least-significant BLEN bits of VAR.  */
+	  if (BYTES_BIG_ENDIAN)
+	    vpos = size_binop (MINUS_EXPR, TYPE_SIZE (type), blen);
+	  else
+	    vpos = bitsize_int (0);
 	  sra_explode_bitfield_assignment
-	    (var, bitsize_int (0), true, &list, blen, bpos, elt);
+	    (var, vpos, true, &list, blen, bpos, elt);
 
 	  GIMPLE_STMT_OPERAND (stmt, 1) = var;
 	  update = true;


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