diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-06-27 09:03:50 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-06-27 09:03:50 +0200 |
commit | a4ee446d6d7f1c120e9ef281ec4586f7535647cc (patch) | |
tree | 95f86e468f89c90def7089d63fb1c45c8a0f789e /gcc/expmed.c | |
parent | 9698b078c86c21aa6a2a2fb4e5bc198f6f1df24c (diff) | |
download | gcc-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.c | 19 |
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))); |