You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.8 KiB
48 lines
1.8 KiB
2015-09-03 Bill Schmidt <wschmidt@linux.vnet.ibm.com> |
|
|
|
* optabs.c (expand_binop): Don't create a broadcast vector with a |
|
source element wider than the inner mode. |
|
|
|
* gcc.target/powerpc/vec-shift.c: New test. |
|
|
|
--- gcc/optabs.c |
|
+++ gcc/optabs.c |
|
@@ -1608,6 +1608,15 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, |
|
|
|
if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing) |
|
{ |
|
+ /* The scalar may have been extended to be too wide. Truncate |
|
+ it back to the proper size to fit in the broadcast vector. */ |
|
+ machine_mode inner_mode = GET_MODE_INNER (mode); |
|
+ if (!CONST_INT_P (op1) |
|
+ && (GET_MODE_BITSIZE (inner_mode) |
|
+ < GET_MODE_BITSIZE (GET_MODE (op1)))) |
|
+ op1 = force_reg (inner_mode, |
|
+ simplify_gen_unary (TRUNCATE, inner_mode, op1, |
|
+ GET_MODE (op1))); |
|
rtx vop1 = expand_vector_broadcast (mode, op1); |
|
if (vop1) |
|
{ |
|
--- /dev/null |
|
+++ gcc/testsuite/gcc.target/powerpc/vec-shift.c |
|
@@ -0,0 +1,20 @@ |
|
+/* { dg-do compile { target { powerpc*-*-* } } } */ |
|
+/* { dg-require-effective-target powerpc_altivec_ok } */ |
|
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ |
|
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ |
|
+/* { dg-options "-mcpu=power7 -O2" } */ |
|
+ |
|
+/* This used to ICE. During gimplification, "i" is widened to an unsigned |
|
+ int. We used to fail at expand time as we tried to cram an SImode item |
|
+ into a QImode memory slot. This has been fixed to properly truncate the |
|
+ shift amount when splatting it into a vector. */ |
|
+ |
|
+typedef unsigned char v16ui __attribute__((vector_size(16))); |
|
+ |
|
+v16ui vslb(v16ui v, unsigned char i) |
|
+{ |
|
+ return v << i; |
|
+} |
|
+ |
|
+/* { dg-final { scan-assembler "vspltb" } } */ |
|
+/* { dg-final { scan-assembler "vslb" } } */
|
|
|