[PATCH 02/13] optabs: Fix vec_perm -> V16QI middle end lowering.
Andreas Krebbel
krebbel@linux.vnet.ibm.com
Mon May 11 13:24:00 GMT 2015
The current implementation re-uses the location of the selection
pattern to generate a new one. This fails if the pattern resides in a
read-only location. With the patch a new temporary register is
allocated for that purpose.
gcc/
* optabs.c (expand_vec_perm): Allocate a temp reg for the new
select pattern.
---
gcc/optabs.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 983c8d9..8926efa 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -6784,14 +6784,18 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
{
/* Multiply each element by its byte size. */
machine_mode selmode = GET_MODE (sel);
+ /* We cannot re-use SEL as a temp operand since it might by in
+ read-only storage. */
+ rtx sel_reg = gen_reg_rtx (selmode);
+
if (u == 2)
- sel = expand_simple_binop (selmode, PLUS, sel, sel,
- sel, 0, OPTAB_DIRECT);
+ sel_reg = expand_simple_binop (selmode, PLUS, sel, sel,
+ sel_reg, 0, OPTAB_DIRECT);
else
- sel = expand_simple_binop (selmode, ASHIFT, sel,
- GEN_INT (exact_log2 (u)),
- sel, 0, OPTAB_DIRECT);
- gcc_assert (sel != NULL);
+ sel_reg = expand_simple_binop (selmode, ASHIFT, sel,
+ GEN_INT (exact_log2 (u)),
+ sel_reg, 0, OPTAB_DIRECT);
+ gcc_assert (sel_reg != NULL);
/* Broadcast the low byte each element into each of its bytes. */
vec = rtvec_alloc (w);
@@ -6803,7 +6807,7 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
RTVEC_ELT (vec, i) = GEN_INT (this_e);
}
tmp = gen_rtx_CONST_VECTOR (qimode, vec);
- sel = gen_lowpart (qimode, sel);
+ sel = gen_lowpart (qimode, sel_reg);
sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
gcc_assert (sel != NULL);
--
1.7.9.5
More information about the Gcc-patches
mailing list