diff mbox

[rs6000] Fix PR78556 - left shift of negative values

Message ID 20161128135819.GE427@x4
State New
Headers show

Commit Message

Markus Trippelsdorf Nov. 28, 2016, 1:58 p.m. UTC
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.

OK for trunk?

Thanks.

        PR target/78556
	* config/rs6000/rs6000.h (vspltis_constant): Add casts to avoid
	left shifting of negative values.


--
Markus

Comments

Segher Boessenkool Nov. 28, 2016, 6:02 p.m. UTC | #1
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?


Segher
diff mbox

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 6c28e6a..dfb5dc8 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -6214,7 +6214,9 @@  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 != ((HOST_WIDE_INT)
+          ((unsigned HOST_WIDE_INT) small_val << bitsize)
+          | (small_val & mask)))
 	return false;
       splat_val = small_val;
     }