On Thu, Sep 10, 2020 at 09:31:33PM +0200, Tom de Vries wrote:
> Currently, for this code from c-c++-common/spec-barrier-1.c:
> ...
> __int128 g = 9;
> ...
> we generate:
> ...
> // BEGIN GLOBAL VAR DEF: g
> .visible .global .align 8 .u64 g[2] = { 9, 9 };
> ...
> and consequently the test-case fails in execution.
> 
> The problem is caused by a shift in nvptx_assemble_value:
> ...
>       val >>= part * BITS_PER_UNIT;
> ...
> where the shift amount is equal to the number of bits in val, which is
> undefined behaviour.
> 
> Fix this by detecting the situation and setting val to 0.

Actually, looking more at it, is nvptx_assemble_value called from
nvptx_assemble_integer with the CONST_INT and size of 16?
Then
  val &= ((unsigned  HOST_WIDE_INT)2 << (size * BITS_PER_UNIT - 1)) - 1;
will invoke UB too (perhaps it can just do:
  if (size * BITS_PER_UNIT < HOST_BITS_PER_WIDE_INT)
    val &= HOST_WIDE_INT_1U << (size * BITS_PER_UNIT);
?), and also, TImode CONST_INTs are considered signed, i.e.
you want value of -1 rather than 0 if the MSB (of the original value before
any shifting) is set.
And, will it only ever trigger == equality of the part, or could it e.g.
emit it even in more fragments and have the shift count >
HOST_BITS_PER_WIDE_INT?
So check what you get for
__int128 h = -9;

        Jakub

Reply via email to