> Woudln't it be better to do this in the series of "conversions", that is
> inside the preceeding if-statement?  (the integral type case using
> convert_modes looks weird enough, so adding this kind-of "less"
> weird one there looks sensible)

Yes, the integral type case is very strange: it was introduced in r103660 as

+      /* If both modes are integral, then we can convert from one to the
+        other.  */
+      else if (SCALAR_INT_MODE_P (GET_MODE (op0))
+              && SCALAR_INT_MODE_P (TYPE_MODE (type)))
+       op0 = convert_modes (TYPE_MODE (type), GET_MODE (op0), op0, 
+                            TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 
0))));

which was very problematic (to say the least), so I've restricted it to 
integral types in r158675.  I don't think that we should touch it here.

Something like the attached patch?  This seems to work fine too.

> Ok with moving it there (before the else if (!MEM_P (op0))).  You
> probably want to guard with INTEGRAL_TYPE_P (type) as well,
> not only GET_MODE (op0) != mode - just to prepare for weird
> stuff like a vector-type where TYPE_PRECISION means sth else.

It's already guarded since reduce_bit_field => INTEGRAL_TYPE_P (type).

-- 
Eric Botcazou
Index: expr.c
===================================================================
--- expr.c	(revision 207796)
+++ expr.c	(working copy)
@@ -10436,6 +10436,11 @@ expand_expr_real_1 (tree exp, rtx target
       else if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (treeop0)))
 	op0 = convert_modes (mode, GET_MODE (op0), op0,
 			     TYPE_UNSIGNED (TREE_TYPE (treeop0)));
+      /* If the output type is a bit-field type, do an extraction.  */
+      else if (reduce_bit_field)
+	return extract_bit_field (op0, TYPE_PRECISION (type), 0,
+				  TYPE_UNSIGNED (type), NULL_RTX,
+				  mode, mode);
       /* As a last resort, spill op0 to memory, and reload it in a
 	 different mode.  */
       else if (!MEM_P (op0))

Reply via email to