> 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))