On Wed, Aug 27, 2014 at 12:25 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Wed, Aug 27, 2014 at 12:07 PM, Richard Biener
> <richard.guent...@gmail.com> wrote:
>>> 2014-08-07  Kugan Vivekanandarajah  <kug...@linaro.org>
>>>>
>>>> * calls.c (precompute_arguments): Check
>>>> promoted_for_signed_and_unsigned_p and set the promoted mode.
>>>> (promoted_for_signed_and_unsigned_p): New function.
>>>> (expand_expr_real_1): Check promoted_for_signed_and_unsigned_p
>>>> and set the promoted mode.
>>>> * expr.h (promoted_for_signed_and_unsigned_p): New function definition.
>>>> * cfgexpand.c (expand_gimple_stmt_1): Call emit_move_insn if
>>>> SUBREG is promoted with SRP_SIGNED_AND_UNSIGNED.
>>>
>>> This patch regresses:
>>>
>>> Running target unix
>>> FAIL: libgomp.fortran/simd7.f90   -O2  execution test
>>> FAIL: libgomp.fortran/simd7.f90   -Os  execution test
>>>
>>> on alphaev6-linux-gnu.
>>>
>>> So, the code assumes that it is possible to copy (reg:DI 540) directly
>>> to (reg:DI 154). However, this is not the case, since we still have
>>> garbage in the top 32bits.
>>>
>>> Reverting the part above fixes the runtime failure, since (insn 599) is now:
>>>
>>> (insn 599 598 0 (set (reg:DI 145 [ D.1694 ])
>>>         (zero_extend:DI (subreg:SI (reg:DI 540) 0))) -1
>>>      (nil))
>>>
>>> It looks to me that we have also to check the temp with SUBREG_PROMOTED_*.
>>
>> Yeah, that makes sense.
>
> Something like following (untested) patch that also fixes the testcase 
> perhaps?

Yes (though I'm not really familiar with the RTL side here and the
comment before SUBREG_PROMOTED_VAR_P looks odd)

Richard.

> -- cut here--
> Index: cfgexpand.c
> ===================================================================
> --- cfgexpand.c (revision 214445)
> +++ cfgexpand.c (working copy)
> @@ -3322,6 +3322,7 @@ expand_gimple_stmt_1 (gimple stmt)
>
>                 if ((SUBREG_PROMOTED_GET (target) == SRP_SIGNED_AND_UNSIGNED)
>                     && (GET_CODE (temp) == SUBREG)
> +                   && SUBREG_PROMOTED_VAR_P (temp)
>                     && (GET_MODE (target) == GET_MODE (temp))
>                     && (GET_MODE (SUBREG_REG (target)) == GET_MODE
> (SUBREG_REG (temp))))
>                   emit_move_insn (SUBREG_REG (target), SUBREG_REG (temp));
> -- cut here
>
> Uros.

Reply via email to