From 4d95edca1212e23855e4f613b588cbc6dac89999 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 27 Nov 2015 10:01:20 +0100 Subject: [PATCH] re PR tree-optimization/68552 (ICE in in expand_expr_real_2 with -O2 -ftree-vectorize) PR tree-optimization/68552 * optabs.c (expand_vec_perm_1): Move vec_shr handling from here... (expand_vec_perm): ... here. Do it regardless of vec_perm_const_optab or whether v0 == v1. From-SVN: r231000 --- gcc/ChangeLog | 7 +++++++ gcc/optabs.c | 49 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1a04191a0fc..d70eddb1960 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-11-27 Jakub Jelinek + + PR tree-optimization/68552 + * optabs.c (expand_vec_perm_1): Move vec_shr handling from here... + (expand_vec_perm): ... here. Do it regardless of vec_perm_const_optab + or whether v0 == v1. + 2015-11-27 Martin Liska * tree-ssa-uninit.c: Fix whitespaces in the source file. diff --git a/gcc/optabs.c b/gcc/optabs.c index 40ef5829150..550764293b9 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -5274,17 +5274,6 @@ expand_vec_perm_1 (enum insn_code icode, rtx target, else { create_input_operand (&ops[1], v0, tmode); - /* See if this can be handled with a vec_shr. We only do this if the - second vector is all zeroes. */ - enum insn_code shift_code = optab_handler (vec_shr_optab, GET_MODE (v0)); - if (v1 == CONST0_RTX (GET_MODE (v1)) && shift_code) - if (rtx shift_amt = shift_amt_for_vec_perm_mask (sel)) - { - create_convert_operand_from_type (&ops[2], shift_amt, - sizetype_tab[(int) stk_sizetype]); - if (maybe_expand_insn (shift_code, 3, ops)) - return ops[0].value; - } create_input_operand (&ops[2], v1, tmode); } @@ -5326,6 +5315,44 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target) gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT); if (GET_CODE (sel) == CONST_VECTOR) { + /* See if this can be handled with a vec_shr. We only do this if the + second vector is all zeroes. */ + enum insn_code shift_code = optab_handler (vec_shr_optab, mode); + enum insn_code shift_code_qi = ((qimode != VOIDmode && qimode != mode) + ? optab_handler (vec_shr_optab, qimode) + : CODE_FOR_nothing); + rtx shift_amt = NULL_RTX; + if (v1 == CONST0_RTX (GET_MODE (v1)) + && (shift_code != CODE_FOR_nothing + || shift_code_qi != CODE_FOR_nothing)) + { + shift_amt = shift_amt_for_vec_perm_mask (sel); + if (shift_amt) + { + struct expand_operand ops[3]; + if (shift_code != CODE_FOR_nothing) + { + create_output_operand (&ops[0], target, mode); + create_input_operand (&ops[1], v0, mode); + create_convert_operand_from_type (&ops[2], shift_amt, + sizetype); + if (maybe_expand_insn (shift_code, 3, ops)) + return ops[0].value; + } + if (shift_code_qi != CODE_FOR_nothing) + { + tmp = gen_reg_rtx (qimode); + create_output_operand (&ops[0], tmp, qimode); + create_input_operand (&ops[1], gen_lowpart (qimode, v0), + qimode); + create_convert_operand_from_type (&ops[2], shift_amt, + sizetype); + if (maybe_expand_insn (shift_code_qi, 3, ops)) + return gen_lowpart (mode, ops[0].value); + } + } + } + icode = direct_optab_handler (vec_perm_const_optab, mode); if (icode != CODE_FOR_nothing) {