On Wed, Jun 23, 2021 at 10:01 AM Jakub Jelinek <ja...@redhat.com> wrote: > > On Wed, Jun 23, 2021 at 09:53:27AM +0200, Richard Biener via Gcc-patches > wrote: > > On Wed, Jun 23, 2021 at 9:19 AM Hongtao Liu via Gcc-patches > > <gcc-patches@gcc.gnu.org> wrote: > > > > > > Here's the patch I'm going to check in. > > > > > > The patch will regress pr91838.C with extra options: -march=cascadelake > > > > > > using T = unsigned char; // or ushort, or uint > > > using V [[gnu::vector_size(8)]] = T; > > > V f(V x) { return x >> 8 * sizeof(T); } > > > > > > Basically, the testcase is UB with logic right shift more than 8 bits > > > > I don't see any UB here, it's just x >> 8 but we indeed fail to constant > > fold this. For scalars bit CCP does this, but we seem to lack a > > For scalar T y = ...; y >> 8 is not UB because of integral promotion to > int, but we do not perform such integral promotions for vector types, > so arguably x >> 8 is UB.
But this vector shift is a GCC extension and we dont document this UB which means the natural reading would be that the shift is applied to the promoted element and then the result truncated? We document: It is possible to use shifting operators @code{<<}, @code{>>} on integer-type vectors. The operation is defined as following: @code{@{a0, a1, @dots{}, an@} >> @{b0, b1, @dots{}, bn@} == @{a0 >> b0, a1 >> b1, @dots{}, an >> bn@}}@. Vector operands must have the same number of elements. so IMHO it's not UB and nothing optimizes it since VRP and bit CCP only operate on scalars, not vectors. Of course it would take quite some work in those passes to also fold sth like __builtin_convertvector (v4qi, v4si) >> 8 thus where a unsigned char vector is widened to int and the int vector shifted. Richard. > Jakub >