re PR tree-optimization/68552 (ICE in in expand_expr_real_2 with -O2 -ftree-vectorize)
authorJakub Jelinek <jakub@redhat.com>
Fri, 27 Nov 2015 09:01:20 +0000 (10:01 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 27 Nov 2015 09:01:20 +0000 (10:01 +0100)
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
gcc/optabs.c

index 1a04191a0fcd730ea3696675f58042f1547796aa..d70eddb1960ac16d364ca537abf73bee6f4f2ffe 100644 (file)
@@ -1,3 +1,10 @@
+2015-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <mliska@suse.cz>
 
        * tree-ssa-uninit.c: Fix whitespaces in the source file.
index 40ef5829150e8760ee90d226c3172e7efb7bd1d1..550764293b99137b4c879ec348b1dcc00df2259d 100644 (file)
@@ -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)
        {