On 2016.11.28 at 12:02 -0600, Segher Boessenkool wrote: > Hi Markus, > > On Mon, Nov 28, 2016 at 02:58:19PM +0100, Markus Trippelsdorf wrote: > > Running bootstrap-ubsan on ppc64le shows many instances of e.g.: > > config/rs6000/rs6000.c:6217:36: runtime error: left shift of negative > > value -12301 > > > > The attached patch fixes the issue and was tested on ppc64le. > > Thanks for the patch. > > > for (i = 2; i <= copies; i *= 2) > { > HOST_WIDE_INT small_val; > bitsize /= 2; > small_val = splat_val >> bitsize; > > > bitsize /= 2; > > small_val = splat_val >> bitsize; > > mask >>= bitsize; > > - if (splat_val != ((small_val << bitsize) | (small_val & mask))) > > + if (splat_val != ((HOST_WIDE_INT) > > + ((unsigned HOST_WIDE_INT) small_val << bitsize) > > + | (small_val & mask))) > > return false; > > splat_val = small_val; > > } > > Can't you just make small_val an unsigned WIDE_INT, instead?
No, it doesn't work. First of all you'll get -Wsign-compare warnings. And gcc.target/powerpc/altivec-11.c also starts failing. An alternative might be: diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6c28e6a..295bcb0 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -6214,7 +6214,7 @@ vspltis_constant (rtx op, unsigned step, unsigned copies) bitsize /= 2; small_val = splat_val >> bitsize; mask >>= bitsize; - if (splat_val != ((small_val << bitsize) | (small_val & mask))) + if (splat_val != (small_val * (1 << bitsize) | (small_val & mask))) return false; splat_val = small_val; } -- Markus