aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-06-27 09:03:50 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2014-06-27 09:03:50 +0200
commita4ee446d6d7f1c120e9ef281ec4586f7535647cc (patch)
tree95f86e468f89c90def7089d63fb1c45c8a0f789e /gcc/expmed.c
parent9698b078c86c21aa6a2a2fb4e5bc198f6f1df24c (diff)
downloadgcc-a4ee446d6d7f1c120e9ef281ec4586f7535647cc.zip
gcc-a4ee446d6d7f1c120e9ef281ec4586f7535647cc.tar.gz
gcc-a4ee446d6d7f1c120e9ef281ec4586f7535647cc.tar.bz2
re PR tree-optimization/57233 (Vector lowering of LROTATE_EXPR pessimizes code)
PR tree-optimization/57233 PR tree-optimization/61299 * tree-vect-generic.c (get_compute_type, count_type_subparts): New functions. (expand_vector_operations_1): Use them. If {L,R}ROTATE_EXPR would be lowered to scalar shifts, check if corresponding shifts and vector BIT_IOR_EXPR are supported and don't lower or lower just to narrower vector type in that case. * expmed.c (expand_shift_1): Fix up handling of vector shifts and rotates. * gcc.dg/pr57233.c: New test. * gcc.target/i386/pr57233.c: New test. * gcc.target/i386/sse2-pr57233.c: New test. * gcc.target/i386/avx-pr57233.c: New test. * gcc.target/i386/avx2-pr57233.c: New test. * gcc.target/i386/avx512f-pr57233.c: New test. * gcc.target/i386/xop-pr57233.c: New test. From-SVN: r212063
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index e76b6fc..861626e 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2128,9 +2128,12 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
optab lrotate_optab = rotl_optab;
optab rrotate_optab = rotr_optab;
enum machine_mode op1_mode;
+ enum machine_mode scalar_mode = mode;
int attempt;
bool speed = optimize_insn_for_speed_p ();
+ if (VECTOR_MODE_P (mode))
+ scalar_mode = GET_MODE_INNER (mode);
op1 = amount;
op1_mode = GET_MODE (op1);
@@ -2153,9 +2156,9 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
{
if (CONST_INT_P (op1)
&& ((unsigned HOST_WIDE_INT) INTVAL (op1) >=
- (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode)))
+ (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (scalar_mode)))
op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
- % GET_MODE_BITSIZE (mode));
+ % GET_MODE_BITSIZE (scalar_mode));
else if (GET_CODE (op1) == SUBREG
&& subreg_lowpart_p (op1)
&& SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (op1)))
@@ -2169,10 +2172,10 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
amount instead. */
if (rotate
&& CONST_INT_P (op1)
- && IN_RANGE (INTVAL (op1), GET_MODE_BITSIZE (mode) / 2 + left,
- GET_MODE_BITSIZE (mode) - 1))
+ && IN_RANGE (INTVAL (op1), GET_MODE_BITSIZE (scalar_mode) / 2 + left,
+ GET_MODE_BITSIZE (scalar_mode) - 1))
{
- op1 = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1));
+ op1 = GEN_INT (GET_MODE_BITSIZE (scalar_mode) - INTVAL (op1));
left = !left;
code = left ? LROTATE_EXPR : RROTATE_EXPR;
}
@@ -2185,7 +2188,7 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
if (code == LSHIFT_EXPR
&& CONST_INT_P (op1)
&& INTVAL (op1) > 0
- && INTVAL (op1) < GET_MODE_PRECISION (mode)
+ && INTVAL (op1) < GET_MODE_PRECISION (scalar_mode)
&& INTVAL (op1) < MAX_BITS_PER_WORD
&& (shift_cost (speed, mode, INTVAL (op1))
> INTVAL (op1) * add_cost (speed, mode))
@@ -2240,14 +2243,14 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
if (op1 == const0_rtx)
return shifted;
else if (CONST_INT_P (op1))
- other_amount = GEN_INT (GET_MODE_BITSIZE (mode)
+ other_amount = GEN_INT (GET_MODE_BITSIZE (scalar_mode)
- INTVAL (op1));
else
{
other_amount
= simplify_gen_unary (NEG, GET_MODE (op1),
op1, GET_MODE (op1));
- HOST_WIDE_INT mask = GET_MODE_PRECISION (mode) - 1;
+ HOST_WIDE_INT mask = GET_MODE_PRECISION (scalar_mode) - 1;
other_amount
= simplify_gen_binary (AND, GET_MODE (op1), other_amount,
gen_int_mode (mask, GET_MODE (op1)));