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