1 /* Lower vector operations to scalar operations.
2 Copyright (C) 2004-2022 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
27 #include "tree-pass.h"
30 #include "optabs-tree.h"
31 #include "diagnostic.h"
32 #include "fold-const.h"
33 #include "stor-layout.h"
34 #include "langhooks.h"
36 #include "gimple-iterator.h"
37 #include "gimplify-me.h"
40 #include "tree-vector-builder.h"
41 #include "vec-perm-indices.h"
42 #include "insn-config.h"
43 #include "tree-ssa-dce.h"
44 #include "gimple-fold.h"
45 #include "gimple-match.h"
46 #include "recog.h" /* FIXME: for insn_data */
49 /* Build a ternary operation and gimplify it. Emit code before GSI.
50 Return the gimple_val holding the result. */
53 gimplify_build3 (gimple_stmt_iterator
*gsi
, enum tree_code code
,
54 tree type
, tree a
, tree b
, tree c
)
56 location_t loc
= gimple_location (gsi_stmt (*gsi
));
57 return gimple_build (gsi
, true, GSI_SAME_STMT
, loc
, code
, type
, a
, b
, c
);
60 /* Build a binary operation and gimplify it. Emit code before GSI.
61 Return the gimple_val holding the result. */
64 gimplify_build2 (gimple_stmt_iterator
*gsi
, enum tree_code code
,
65 tree type
, tree a
, tree b
)
67 location_t loc
= gimple_location (gsi_stmt (*gsi
));
68 return gimple_build (gsi
, true, GSI_SAME_STMT
, loc
, code
, type
, a
, b
);
71 /* Build a unary operation and gimplify it. Emit code before GSI.
72 Return the gimple_val holding the result. */
75 gimplify_build1 (gimple_stmt_iterator
*gsi
, enum tree_code code
, tree type
,
78 location_t loc
= gimple_location (gsi_stmt (*gsi
));
79 return gimple_build (gsi
, true, GSI_SAME_STMT
, loc
, code
, type
, a
);
83 static void expand_vector_operations_1 (gimple_stmt_iterator
*, bitmap
);
85 /* Return the number of elements in a vector type TYPE that we have
86 already decided needs to be expanded piecewise. We don't support
87 this kind of expansion for variable-length vectors, since we should
88 always check for target support before introducing uses of those. */
90 nunits_for_known_piecewise_op (const_tree type
)
92 return TYPE_VECTOR_SUBPARTS (type
).to_constant ();
95 /* Return true if TYPE1 has more elements than TYPE2, where either
96 type may be a vector or a scalar. */
99 subparts_gt (tree type1
, tree type2
)
101 poly_uint64 n1
= VECTOR_TYPE_P (type1
) ? TYPE_VECTOR_SUBPARTS (type1
) : 1;
102 poly_uint64 n2
= VECTOR_TYPE_P (type2
) ? TYPE_VECTOR_SUBPARTS (type2
) : 1;
103 return known_gt (n1
, n2
);
106 /* Build a constant of type TYPE, made of VALUE's bits replicated
107 every WIDTH bits to fit TYPE's precision. */
109 build_replicated_const (tree type
, unsigned int width
, HOST_WIDE_INT value
)
111 int n
= (TYPE_PRECISION (type
) + HOST_BITS_PER_WIDE_INT
- 1)
112 / HOST_BITS_PER_WIDE_INT
;
113 unsigned HOST_WIDE_INT low
, mask
;
114 HOST_WIDE_INT a
[WIDE_INT_MAX_ELTS
];
117 gcc_assert (n
&& n
<= WIDE_INT_MAX_ELTS
);
119 if (width
== HOST_BITS_PER_WIDE_INT
)
123 mask
= ((HOST_WIDE_INT
)1 << width
) - 1;
124 low
= (unsigned HOST_WIDE_INT
) ~0 / mask
* (value
& mask
);
127 for (i
= 0; i
< n
; i
++)
130 gcc_assert (TYPE_PRECISION (type
) <= MAX_BITSIZE_MODE_ANY_INT
);
131 return wide_int_to_tree
132 (type
, wide_int::from_array (a
, n
, TYPE_PRECISION (type
)));
135 static GTY(()) tree vector_inner_type
;
136 static GTY(()) tree vector_last_type
;
137 static GTY(()) int vector_last_nunits
;
139 /* Return a suitable vector types made of SUBPARTS units each of mode
140 "word_mode" (the global variable). */
142 build_word_mode_vector_type (int nunits
)
144 if (!vector_inner_type
)
145 vector_inner_type
= lang_hooks
.types
.type_for_mode (word_mode
, 1);
146 else if (vector_last_nunits
== nunits
)
148 gcc_assert (TREE_CODE (vector_last_type
) == VECTOR_TYPE
);
149 return vector_last_type
;
152 vector_last_nunits
= nunits
;
153 vector_last_type
= build_vector_type (vector_inner_type
, nunits
);
154 return vector_last_type
;
157 typedef tree (*elem_op_func
) (gimple_stmt_iterator
*,
158 tree
, tree
, tree
, tree
, tree
, enum tree_code
,
161 /* Extract the vector element of type TYPE at BITPOS with BITSIZE from T
165 tree_vec_extract (gimple_stmt_iterator
*gsi
, tree type
,
166 tree t
, tree bitsize
, tree bitpos
)
168 /* We're using the resimplify API and maybe_push_res_to_seq to
169 simplify the BIT_FIELD_REF but restrict the simplification to
170 a single stmt while at the same time following SSA edges for
171 simplification with already emitted CTORs. */
173 opr
.set_op (BIT_FIELD_REF
, type
, t
, bitsize
, bitpos
);
174 opr
.resimplify (NULL
, follow_all_ssa_edges
);
175 gimple_seq stmts
= NULL
;
176 tree res
= maybe_push_res_to_seq (&opr
, &stmts
);
178 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
183 do_unop (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
,
184 tree b ATTRIBUTE_UNUSED
, tree bitpos
, tree bitsize
,
185 enum tree_code code
, tree type ATTRIBUTE_UNUSED
)
187 a
= tree_vec_extract (gsi
, inner_type
, a
, bitsize
, bitpos
);
188 return gimplify_build1 (gsi
, code
, inner_type
, a
);
192 do_binop (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
, tree b
,
193 tree bitpos
, tree bitsize
, enum tree_code code
,
194 tree type ATTRIBUTE_UNUSED
)
196 if (TREE_CODE (TREE_TYPE (a
)) == VECTOR_TYPE
)
197 a
= tree_vec_extract (gsi
, inner_type
, a
, bitsize
, bitpos
);
198 if (TREE_CODE (TREE_TYPE (b
)) == VECTOR_TYPE
)
199 b
= tree_vec_extract (gsi
, inner_type
, b
, bitsize
, bitpos
);
200 return gimplify_build2 (gsi
, code
, inner_type
, a
, b
);
203 /* Construct expression (A[BITPOS] code B[BITPOS]) ? -1 : 0
205 INNER_TYPE is the type of A and B elements
207 returned expression is of signed integer type with the
208 size equal to the size of INNER_TYPE. */
210 do_compare (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
, tree b
,
211 tree bitpos
, tree bitsize
, enum tree_code code
, tree type
)
213 tree stype
= TREE_TYPE (type
);
214 tree cst_false
= build_zero_cst (stype
);
215 tree cst_true
= build_all_ones_cst (stype
);
218 a
= tree_vec_extract (gsi
, inner_type
, a
, bitsize
, bitpos
);
219 b
= tree_vec_extract (gsi
, inner_type
, b
, bitsize
, bitpos
);
221 cmp
= build2 (code
, boolean_type_node
, a
, b
);
222 return gimplify_build3 (gsi
, COND_EXPR
, stype
, cmp
, cst_true
, cst_false
);
225 /* Expand vector addition to scalars. This does bit twiddling
226 in order to increase parallelism:
228 a + b = (((int) a & 0x7f7f7f7f) + ((int) b & 0x7f7f7f7f)) ^
231 a - b = (((int) a | 0x80808080) - ((int) b & 0x7f7f7f7f)) ^
232 (a ^ ~b) & 0x80808080
234 -b = (0x80808080 - ((int) b & 0x7f7f7f7f)) ^ (~b & 0x80808080)
236 This optimization should be done only if 4 vector items or more
239 do_plus_minus (gimple_stmt_iterator
*gsi
, tree word_type
, tree a
, tree b
,
240 tree bitpos ATTRIBUTE_UNUSED
, tree bitsize ATTRIBUTE_UNUSED
,
241 enum tree_code code
, tree type ATTRIBUTE_UNUSED
)
243 unsigned int width
= vector_element_bits (TREE_TYPE (a
));
244 tree inner_type
= TREE_TYPE (TREE_TYPE (a
));
245 unsigned HOST_WIDE_INT max
;
246 tree low_bits
, high_bits
, a_low
, b_low
, result_low
, signs
;
248 max
= GET_MODE_MASK (TYPE_MODE (inner_type
));
249 low_bits
= build_replicated_const (word_type
, width
, max
>> 1);
250 high_bits
= build_replicated_const (word_type
, width
, max
& ~(max
>> 1));
252 a
= tree_vec_extract (gsi
, word_type
, a
, bitsize
, bitpos
);
253 b
= tree_vec_extract (gsi
, word_type
, b
, bitsize
, bitpos
);
255 signs
= gimplify_build2 (gsi
, BIT_XOR_EXPR
, word_type
, a
, b
);
256 b_low
= gimplify_build2 (gsi
, BIT_AND_EXPR
, word_type
, b
, low_bits
);
257 if (code
== PLUS_EXPR
)
258 a_low
= gimplify_build2 (gsi
, BIT_AND_EXPR
, word_type
, a
, low_bits
);
261 a_low
= gimplify_build2 (gsi
, BIT_IOR_EXPR
, word_type
, a
, high_bits
);
262 signs
= gimplify_build1 (gsi
, BIT_NOT_EXPR
, word_type
, signs
);
265 signs
= gimplify_build2 (gsi
, BIT_AND_EXPR
, word_type
, signs
, high_bits
);
266 result_low
= gimplify_build2 (gsi
, code
, word_type
, a_low
, b_low
);
267 return gimplify_build2 (gsi
, BIT_XOR_EXPR
, word_type
, result_low
, signs
);
271 do_negate (gimple_stmt_iterator
*gsi
, tree word_type
, tree b
,
272 tree unused ATTRIBUTE_UNUSED
, tree bitpos ATTRIBUTE_UNUSED
,
273 tree bitsize ATTRIBUTE_UNUSED
,
274 enum tree_code code ATTRIBUTE_UNUSED
,
275 tree type ATTRIBUTE_UNUSED
)
277 unsigned int width
= vector_element_bits (TREE_TYPE (b
));
278 tree inner_type
= TREE_TYPE (TREE_TYPE (b
));
280 tree low_bits
, high_bits
, b_low
, result_low
, signs
;
282 max
= GET_MODE_MASK (TYPE_MODE (inner_type
));
283 low_bits
= build_replicated_const (word_type
, width
, max
>> 1);
284 high_bits
= build_replicated_const (word_type
, width
, max
& ~(max
>> 1));
286 b
= tree_vec_extract (gsi
, word_type
, b
, bitsize
, bitpos
);
288 b_low
= gimplify_build2 (gsi
, BIT_AND_EXPR
, word_type
, b
, low_bits
);
289 signs
= gimplify_build1 (gsi
, BIT_NOT_EXPR
, word_type
, b
);
290 signs
= gimplify_build2 (gsi
, BIT_AND_EXPR
, word_type
, signs
, high_bits
);
291 result_low
= gimplify_build2 (gsi
, MINUS_EXPR
, word_type
, high_bits
, b_low
);
292 return gimplify_build2 (gsi
, BIT_XOR_EXPR
, word_type
, result_low
, signs
);
295 /* Expand a vector operation to scalars, by using many operations
296 whose type is the vector type's inner type. */
298 expand_vector_piecewise (gimple_stmt_iterator
*gsi
, elem_op_func f
,
299 tree type
, tree inner_type
,
300 tree a
, tree b
, enum tree_code code
,
301 bool parallel_p
, tree ret_type
= NULL_TREE
)
303 vec
<constructor_elt
, va_gc
> *v
;
304 tree part_width
= TYPE_SIZE (inner_type
);
305 tree index
= bitsize_int (0);
306 int nunits
= nunits_for_known_piecewise_op (type
);
307 int delta
= tree_to_uhwi (part_width
) / vector_element_bits (type
);
309 location_t loc
= gimple_location (gsi_stmt (*gsi
));
312 || warning_suppressed_p (gsi_stmt (*gsi
),
313 OPT_Wvector_operation_performance
))
314 /* Do not diagnose decomposing single element vectors or when
315 decomposing vectorizer produced operations. */
317 else if (ret_type
|| !parallel_p
)
318 warning_at (loc
, OPT_Wvector_operation_performance
,
319 "vector operation will be expanded piecewise");
321 warning_at (loc
, OPT_Wvector_operation_performance
,
322 "vector operation will be expanded in parallel");
326 vec_alloc (v
, (nunits
+ delta
- 1) / delta
);
327 bool constant_p
= true;
328 for (i
= 0; i
< nunits
;
329 i
+= delta
, index
= int_const_binop (PLUS_EXPR
, index
, part_width
))
331 tree result
= f (gsi
, inner_type
, a
, b
, index
, part_width
, code
,
333 if (!CONSTANT_CLASS_P (result
))
335 constructor_elt ce
= {NULL_TREE
, result
};
340 return build_vector_from_ctor (ret_type
, v
);
342 return build_constructor (ret_type
, v
);
345 /* Expand a vector operation to scalars with the freedom to use
346 a scalar integer type, or to use a different size for the items
347 in the vector type. */
349 expand_vector_parallel (gimple_stmt_iterator
*gsi
, elem_op_func f
, tree type
,
350 tree a
, tree b
, enum tree_code code
)
352 tree result
, compute_type
;
353 int n_words
= tree_to_uhwi (TYPE_SIZE_UNIT (type
)) / UNITS_PER_WORD
;
354 location_t loc
= gimple_location (gsi_stmt (*gsi
));
356 /* We have three strategies. If the type is already correct, just do
357 the operation an element at a time. Else, if the vector is wider than
358 one word, do it a word at a time; finally, if the vector is smaller
359 than one word, do it as a scalar. */
360 if (TYPE_MODE (TREE_TYPE (type
)) == word_mode
)
361 return expand_vector_piecewise (gsi
, f
,
362 type
, TREE_TYPE (type
),
364 else if (n_words
> 1)
366 tree word_type
= build_word_mode_vector_type (n_words
);
367 result
= expand_vector_piecewise (gsi
, f
,
368 word_type
, TREE_TYPE (word_type
),
370 result
= force_gimple_operand_gsi (gsi
, result
, true, NULL
, true,
375 /* Use a single scalar operation with a mode no wider than word_mode. */
376 if (!warning_suppressed_p (gsi_stmt (*gsi
),
377 OPT_Wvector_operation_performance
))
378 warning_at (loc
, OPT_Wvector_operation_performance
,
379 "vector operation will be expanded with a "
380 "single scalar operation");
382 = int_mode_for_size (tree_to_uhwi (TYPE_SIZE (type
)), 0).require ();
383 compute_type
= lang_hooks
.types
.type_for_mode (mode
, 1);
384 result
= f (gsi
, compute_type
, a
, b
, bitsize_zero_node
,
385 TYPE_SIZE (compute_type
), code
, type
);
391 /* Expand a vector operation to scalars; for integer types we can use
392 special bit twiddling tricks to do the sums a word at a time, using
393 function F_PARALLEL instead of F. These tricks are done only if
394 they can process at least four items, that is, only if the vector
395 holds at least four items and if a word can hold four items. */
397 expand_vector_addition (gimple_stmt_iterator
*gsi
,
398 elem_op_func f
, elem_op_func f_parallel
,
399 tree type
, tree a
, tree b
, enum tree_code code
)
401 int parts_per_word
= BITS_PER_WORD
/ vector_element_bits (type
);
403 if (INTEGRAL_TYPE_P (TREE_TYPE (type
))
404 && parts_per_word
>= 4
405 && nunits_for_known_piecewise_op (type
) >= 4)
406 return expand_vector_parallel (gsi
, f_parallel
,
409 return expand_vector_piecewise (gsi
, f
,
410 type
, TREE_TYPE (type
),
415 expand_vector_condition (gimple_stmt_iterator
*gsi
, bitmap dce_ssa_names
);
417 /* Try to expand vector comparison expression OP0 CODE OP1 by
418 querying optab if the following expression:
419 VEC_COND_EXPR< OP0 CODE OP1, {-1,...}, {0,...}>
422 expand_vector_comparison (gimple_stmt_iterator
*gsi
, tree type
, tree op0
,
423 tree op1
, enum tree_code code
,
424 bitmap dce_ssa_names
)
426 tree lhs
= gimple_assign_lhs (gsi_stmt (*gsi
));
428 imm_use_iterator iterator
;
429 bool vec_cond_expr_only
= true;
431 /* As seen in PR95830, we should not expand comparisons that are only
432 feeding a VEC_COND_EXPR statement. */
433 auto_vec
<gimple
*> uses
;
434 FOR_EACH_IMM_USE_FAST (use_p
, iterator
, lhs
)
436 gimple
*use
= USE_STMT (use_p
);
437 if (is_gimple_debug (use
))
439 if (is_gimple_assign (use
)
440 && gimple_assign_rhs_code (use
) == VEC_COND_EXPR
441 && gimple_assign_rhs1 (use
) == lhs
442 && gimple_assign_rhs2 (use
) != lhs
443 && gimple_assign_rhs3 (use
) != lhs
)
444 uses
.safe_push (use
);
446 vec_cond_expr_only
= false;
449 if (vec_cond_expr_only
)
450 for (gimple
*use
: uses
)
452 gimple_stmt_iterator it
= gsi_for_stmt (use
);
453 if (!expand_vector_condition (&it
, dce_ssa_names
))
455 vec_cond_expr_only
= false;
460 if (!uses
.is_empty () && vec_cond_expr_only
)
464 if (!expand_vec_cmp_expr_p (TREE_TYPE (op0
), type
, code
))
466 if (VECTOR_BOOLEAN_TYPE_P (type
)
467 && SCALAR_INT_MODE_P (TYPE_MODE (type
))
468 && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type
)),
469 TYPE_VECTOR_SUBPARTS (type
)
470 * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
471 (TREE_TYPE (type
)))))
473 tree inner_type
= TREE_TYPE (TREE_TYPE (op0
));
474 tree part_width
= vector_element_bits_tree (TREE_TYPE (op0
));
475 tree index
= bitsize_int (0);
476 int nunits
= nunits_for_known_piecewise_op (TREE_TYPE (op0
));
477 int prec
= GET_MODE_PRECISION (SCALAR_TYPE_MODE (type
));
478 tree ret_type
= build_nonstandard_integer_type (prec
, 1);
479 tree ret_inner_type
= boolean_type_node
;
481 location_t loc
= gimple_location (gsi_stmt (*gsi
));
482 t
= build_zero_cst (ret_type
);
484 if (TYPE_PRECISION (ret_inner_type
) != 1)
485 ret_inner_type
= build_nonstandard_integer_type (1, 1);
486 if (!warning_suppressed_p (gsi_stmt (*gsi
),
487 OPT_Wvector_operation_performance
))
488 warning_at (loc
, OPT_Wvector_operation_performance
,
489 "vector operation will be expanded piecewise");
490 for (i
= 0; i
< nunits
;
491 i
++, index
= int_const_binop (PLUS_EXPR
, index
, part_width
))
493 tree a
= tree_vec_extract (gsi
, inner_type
, op0
, part_width
,
495 tree b
= tree_vec_extract (gsi
, inner_type
, op1
, part_width
,
497 tree result
= gimplify_build2 (gsi
, code
, ret_inner_type
, a
, b
);
498 t
= gimplify_build3 (gsi
, BIT_INSERT_EXPR
, ret_type
, t
, result
,
501 t
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
, type
, t
);
504 t
= expand_vector_piecewise (gsi
, do_compare
, type
,
505 TREE_TYPE (TREE_TYPE (op0
)), op0
, op1
,
514 /* Helper function of expand_vector_divmod. Gimplify a RSHIFT_EXPR in type
515 of OP0 with shift counts in SHIFTCNTS array and return the temporary holding
516 the result if successful, otherwise return NULL_TREE. */
518 add_rshift (gimple_stmt_iterator
*gsi
, tree type
, tree op0
, int *shiftcnts
)
521 unsigned int i
, nunits
= nunits_for_known_piecewise_op (type
);
522 bool scalar_shift
= true;
524 for (i
= 1; i
< nunits
; i
++)
526 if (shiftcnts
[i
] != shiftcnts
[0])
527 scalar_shift
= false;
530 if (scalar_shift
&& shiftcnts
[0] == 0)
535 op
= optab_for_tree_code (RSHIFT_EXPR
, type
, optab_scalar
);
536 if (op
!= unknown_optab
537 && optab_handler (op
, TYPE_MODE (type
)) != CODE_FOR_nothing
)
538 return gimplify_build2 (gsi
, RSHIFT_EXPR
, type
, op0
,
539 build_int_cst (NULL_TREE
, shiftcnts
[0]));
542 op
= optab_for_tree_code (RSHIFT_EXPR
, type
, optab_vector
);
543 if (op
!= unknown_optab
544 && optab_handler (op
, TYPE_MODE (type
)) != CODE_FOR_nothing
)
546 tree_vector_builder
vec (type
, nunits
, 1);
547 for (i
= 0; i
< nunits
; i
++)
548 vec
.quick_push (build_int_cst (TREE_TYPE (type
), shiftcnts
[i
]));
549 return gimplify_build2 (gsi
, RSHIFT_EXPR
, type
, op0
, vec
.build ());
555 /* Try to expand integer vector division by constant using
556 widening multiply, shifts and additions. */
558 expand_vector_divmod (gimple_stmt_iterator
*gsi
, tree type
, tree op0
,
559 tree op1
, enum tree_code code
)
561 bool use_pow2
= true;
562 bool has_vector_shift
= true;
563 bool use_abs_op1
= false;
564 int mode
= -1, this_mode
;
565 int pre_shift
= -1, post_shift
;
566 unsigned int nunits
= nunits_for_known_piecewise_op (type
);
567 int *shifts
= XALLOCAVEC (int, nunits
* 4);
568 int *pre_shifts
= shifts
+ nunits
;
569 int *post_shifts
= pre_shifts
+ nunits
;
570 int *shift_temps
= post_shifts
+ nunits
;
571 unsigned HOST_WIDE_INT
*mulc
= XALLOCAVEC (unsigned HOST_WIDE_INT
, nunits
);
572 int prec
= TYPE_PRECISION (TREE_TYPE (type
));
575 signop sign_p
= TYPE_SIGN (TREE_TYPE (type
));
576 unsigned HOST_WIDE_INT mask
= GET_MODE_MASK (TYPE_MODE (TREE_TYPE (type
)));
577 tree cur_op
, mulcst
, tem
;
580 if (prec
> HOST_BITS_PER_WIDE_INT
)
583 op
= optab_for_tree_code (RSHIFT_EXPR
, type
, optab_vector
);
584 if (op
== unknown_optab
585 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
586 has_vector_shift
= false;
588 /* Analysis phase. Determine if all op1 elements are either power
589 of two and it is possible to expand it using shifts (or for remainder
590 using masking). Additionally compute the multiplicative constants
591 and pre and post shifts if the division is to be expanded using
592 widening or high part multiplication plus shifts. */
593 for (i
= 0; i
< nunits
; i
++)
595 tree cst
= VECTOR_CST_ELT (op1
, i
);
596 unsigned HOST_WIDE_INT ml
;
598 if (TREE_CODE (cst
) != INTEGER_CST
|| integer_zerop (cst
))
604 && (!integer_pow2p (cst
) || tree_int_cst_sgn (cst
) != 1))
608 shifts
[i
] = tree_log2 (cst
);
609 if (shifts
[i
] != shifts
[0]
610 && code
== TRUNC_DIV_EXPR
611 && !has_vector_shift
)
616 if (sign_p
== UNSIGNED
)
618 unsigned HOST_WIDE_INT mh
;
619 unsigned HOST_WIDE_INT d
= TREE_INT_CST_LOW (cst
) & mask
;
621 if (d
>= (HOST_WIDE_INT_1U
<< (prec
- 1)))
622 /* FIXME: Can transform this into op0 >= op1 ? 1 : 0. */
631 /* Find a suitable multiplier and right shift count
632 instead of multiplying with D. */
633 mh
= choose_multiplier (d
, prec
, prec
, &ml
, &post_shift
, &dummy_int
);
635 /* If the suggested multiplier is more than SIZE bits, we can
636 do better for even divisors, using an initial right shift. */
637 if ((mh
!= 0 && (d
& 1) == 0)
638 || (!has_vector_shift
&& pre_shift
!= -1))
640 if (has_vector_shift
)
641 pre_shift
= ctz_or_zero (d
);
642 else if (pre_shift
== -1)
645 for (j
= 0; j
< nunits
; j
++)
647 tree cst2
= VECTOR_CST_ELT (op1
, j
);
648 unsigned HOST_WIDE_INT d2
;
651 if (!tree_fits_uhwi_p (cst2
))
653 d2
= tree_to_uhwi (cst2
) & mask
;
656 this_pre_shift
= floor_log2 (d2
& -d2
);
657 if (pre_shift
== -1 || this_pre_shift
< pre_shift
)
658 pre_shift
= this_pre_shift
;
660 if (i
!= 0 && pre_shift
!= 0)
670 if ((d
>> pre_shift
) <= 1)
675 mh
= choose_multiplier (d
>> pre_shift
, prec
,
677 &ml
, &post_shift
, &dummy_int
);
679 pre_shifts
[i
] = pre_shift
;
689 HOST_WIDE_INT d
= TREE_INT_CST_LOW (cst
);
690 unsigned HOST_WIDE_INT abs_d
;
695 /* Since d might be INT_MIN, we have to cast to
696 unsigned HOST_WIDE_INT before negating to avoid
697 undefined signed overflow. */
699 ? (unsigned HOST_WIDE_INT
) d
700 : - (unsigned HOST_WIDE_INT
) d
);
702 /* n rem d = n rem -d */
703 if (code
== TRUNC_MOD_EXPR
&& d
< 0)
708 if (abs_d
== HOST_WIDE_INT_1U
<< (prec
- 1))
710 /* This case is not handled correctly below. */
720 choose_multiplier (abs_d
, prec
, prec
- 1, &ml
,
721 &post_shift
, &dummy_int
);
722 if (ml
>= HOST_WIDE_INT_1U
<< (prec
- 1))
724 this_mode
= 4 + (d
< 0);
725 ml
|= HOST_WIDE_INT_M1U
<< (prec
- 1);
728 this_mode
= 2 + (d
< 0);
731 post_shifts
[i
] = post_shift
;
732 if ((i
&& !has_vector_shift
&& post_shifts
[0] != post_shift
)
733 || post_shift
>= prec
734 || pre_shifts
[i
] >= prec
)
739 else if (mode
!= this_mode
)
745 tree addend
= NULL_TREE
;
746 if (sign_p
== SIGNED
)
750 /* Both division and remainder sequences need
751 op0 < 0 ? mask : 0 computed. It can be either computed as
752 (type) (((uns_type) (op0 >> (prec - 1))) >> (prec - shifts[i]))
753 if none of the shifts is 0, or as the conditional. */
754 for (i
= 0; i
< nunits
; i
++)
758 = build_vector_type (build_nonstandard_integer_type (prec
, 1),
760 if (i
== nunits
&& TYPE_MODE (uns_type
) == TYPE_MODE (type
))
762 for (i
= 0; i
< nunits
; i
++)
763 shift_temps
[i
] = prec
- 1;
764 cur_op
= add_rshift (gsi
, type
, op0
, shift_temps
);
765 if (cur_op
!= NULL_TREE
)
767 cur_op
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
,
769 for (i
= 0; i
< nunits
; i
++)
770 shift_temps
[i
] = prec
- shifts
[i
];
771 cur_op
= add_rshift (gsi
, uns_type
, cur_op
, shift_temps
);
772 if (cur_op
!= NULL_TREE
)
773 addend
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
,
777 if (addend
== NULL_TREE
778 && expand_vec_cond_expr_p (type
, type
, LT_EXPR
))
780 tree zero
, cst
, mask_type
, mask
;
783 mask_type
= truth_type_for (type
);
784 zero
= build_zero_cst (type
);
785 mask
= make_ssa_name (mask_type
);
786 cond
= gimple_build_assign (mask
, LT_EXPR
, op0
, zero
);
787 gsi_insert_before (gsi
, cond
, GSI_SAME_STMT
);
788 tree_vector_builder
vec (type
, nunits
, 1);
789 for (i
= 0; i
< nunits
; i
++)
790 vec
.quick_push (build_int_cst (TREE_TYPE (type
),
794 addend
= make_ssa_name (type
);
796 = gimple_build_assign (addend
, VEC_COND_EXPR
, mask
, cst
, zero
);
797 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
800 if (code
== TRUNC_DIV_EXPR
)
802 if (sign_p
== UNSIGNED
)
804 /* q = op0 >> shift; */
805 cur_op
= add_rshift (gsi
, type
, op0
, shifts
);
806 if (cur_op
!= NULL_TREE
)
809 else if (addend
!= NULL_TREE
)
811 /* t1 = op0 + addend;
813 op
= optab_for_tree_code (PLUS_EXPR
, type
, optab_default
);
814 if (op
!= unknown_optab
815 && optab_handler (op
, TYPE_MODE (type
)) != CODE_FOR_nothing
)
817 cur_op
= gimplify_build2 (gsi
, PLUS_EXPR
, type
, op0
, addend
);
818 cur_op
= add_rshift (gsi
, type
, cur_op
, shifts
);
819 if (cur_op
!= NULL_TREE
)
827 tree_vector_builder
vec (type
, nunits
, 1);
828 for (i
= 0; i
< nunits
; i
++)
829 vec
.quick_push (build_int_cst (TREE_TYPE (type
),
833 op
= optab_for_tree_code (BIT_AND_EXPR
, type
, optab_default
);
834 if (op
!= unknown_optab
835 && optab_handler (op
, TYPE_MODE (type
)) != CODE_FOR_nothing
)
837 if (sign_p
== UNSIGNED
)
838 /* r = op0 & mask; */
839 return gimplify_build2 (gsi
, BIT_AND_EXPR
, type
, op0
, mask
);
840 else if (addend
!= NULL_TREE
)
842 /* t1 = op0 + addend;
845 op
= optab_for_tree_code (PLUS_EXPR
, type
, optab_default
);
846 if (op
!= unknown_optab
847 && optab_handler (op
, TYPE_MODE (type
))
850 cur_op
= gimplify_build2 (gsi
, PLUS_EXPR
, type
, op0
,
852 cur_op
= gimplify_build2 (gsi
, BIT_AND_EXPR
, type
,
854 op
= optab_for_tree_code (MINUS_EXPR
, type
,
856 if (op
!= unknown_optab
857 && optab_handler (op
, TYPE_MODE (type
))
859 return gimplify_build2 (gsi
, MINUS_EXPR
, type
,
867 if (mode
== -2 || BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
)
870 if (!can_mult_highpart_p (TYPE_MODE (type
), TYPE_UNSIGNED (type
)))
878 gcc_assert (sign_p
== UNSIGNED
);
879 /* t1 = oprnd0 >> pre_shift;
881 q = t2 >> post_shift; */
882 cur_op
= add_rshift (gsi
, type
, cur_op
, pre_shifts
);
883 if (cur_op
== NULL_TREE
)
887 gcc_assert (sign_p
== UNSIGNED
);
888 for (i
= 0; i
< nunits
; i
++)
898 gcc_assert (sign_p
== SIGNED
);
899 for (i
= 0; i
< nunits
; i
++)
900 shift_temps
[i
] = prec
- 1;
906 tree_vector_builder
vec (type
, nunits
, 1);
907 for (i
= 0; i
< nunits
; i
++)
908 vec
.quick_push (build_int_cst (TREE_TYPE (type
), mulc
[i
]));
909 mulcst
= vec
.build ();
911 cur_op
= gimplify_build2 (gsi
, MULT_HIGHPART_EXPR
, type
, cur_op
, mulcst
);
916 /* t1 = oprnd0 >> pre_shift;
918 q = t2 >> post_shift; */
919 cur_op
= add_rshift (gsi
, type
, cur_op
, post_shifts
);
922 /* t1 = oprnd0 h* ml;
926 q = t4 >> (post_shift - 1); */
927 op
= optab_for_tree_code (MINUS_EXPR
, type
, optab_default
);
928 if (op
== unknown_optab
929 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
931 tem
= gimplify_build2 (gsi
, MINUS_EXPR
, type
, op0
, cur_op
);
932 tem
= add_rshift (gsi
, type
, tem
, shift_temps
);
933 op
= optab_for_tree_code (PLUS_EXPR
, type
, optab_default
);
934 if (op
== unknown_optab
935 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
937 tem
= gimplify_build2 (gsi
, PLUS_EXPR
, type
, cur_op
, tem
);
938 cur_op
= add_rshift (gsi
, type
, tem
, post_shifts
);
939 if (cur_op
== NULL_TREE
)
946 /* t1 = oprnd0 h* ml;
947 t2 = t1; [ iff (mode & 2) != 0 ]
948 t2 = t1 + oprnd0; [ iff (mode & 2) == 0 ]
949 t3 = t2 >> post_shift;
950 t4 = oprnd0 >> (prec - 1);
951 q = t3 - t4; [ iff (mode & 1) == 0 ]
952 q = t4 - t3; [ iff (mode & 1) != 0 ] */
955 op
= optab_for_tree_code (PLUS_EXPR
, type
, optab_default
);
956 if (op
== unknown_optab
957 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
959 cur_op
= gimplify_build2 (gsi
, PLUS_EXPR
, type
, cur_op
, op0
);
961 cur_op
= add_rshift (gsi
, type
, cur_op
, post_shifts
);
962 if (cur_op
== NULL_TREE
)
964 tem
= add_rshift (gsi
, type
, op0
, shift_temps
);
965 if (tem
== NULL_TREE
)
967 op
= optab_for_tree_code (MINUS_EXPR
, type
, optab_default
);
968 if (op
== unknown_optab
969 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
972 cur_op
= gimplify_build2 (gsi
, MINUS_EXPR
, type
, cur_op
, tem
);
974 cur_op
= gimplify_build2 (gsi
, MINUS_EXPR
, type
, tem
, cur_op
);
980 if (code
== TRUNC_DIV_EXPR
)
983 /* We divided. Now finish by:
986 op
= optab_for_tree_code (MULT_EXPR
, type
, optab_default
);
987 if (op
== unknown_optab
988 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
992 tree_vector_builder elts
;
993 if (!elts
.new_unary_operation (type
, op1
, false))
995 unsigned int count
= elts
.encoded_nelts ();
996 for (unsigned int i
= 0; i
< count
; ++i
)
998 tree elem1
= VECTOR_CST_ELT (op1
, i
);
1000 tree elt
= const_unop (ABS_EXPR
, TREE_TYPE (elem1
), elem1
);
1001 if (elt
== NULL_TREE
)
1003 elts
.quick_push (elt
);
1005 op1
= elts
.build ();
1007 tem
= gimplify_build2 (gsi
, MULT_EXPR
, type
, cur_op
, op1
);
1008 op
= optab_for_tree_code (MINUS_EXPR
, type
, optab_default
);
1009 if (op
== unknown_optab
1010 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
1012 return gimplify_build2 (gsi
, MINUS_EXPR
, type
, op0
, tem
);
1015 /* Expand a vector condition to scalars, by using many conditions
1016 on the vector's elements. */
1019 expand_vector_condition (gimple_stmt_iterator
*gsi
, bitmap dce_ssa_names
)
1021 gassign
*stmt
= as_a
<gassign
*> (gsi_stmt (*gsi
));
1022 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
1023 tree a
= gimple_assign_rhs1 (stmt
);
1025 tree a2
= NULL_TREE
;
1026 bool a_is_comparison
= false;
1027 bool a_is_scalar_bitmask
= false;
1028 tree b
= gimple_assign_rhs2 (stmt
);
1029 tree c
= gimple_assign_rhs3 (stmt
);
1030 vec
<constructor_elt
, va_gc
> *v
;
1032 tree inner_type
= TREE_TYPE (type
);
1033 tree width
= vector_element_bits_tree (type
);
1034 tree cond_type
= TREE_TYPE (TREE_TYPE (a
));
1035 tree comp_inner_type
= cond_type
;
1036 tree index
= bitsize_int (0);
1037 tree comp_width
= width
;
1038 tree comp_index
= index
;
1039 location_t loc
= gimple_location (gsi_stmt (*gsi
));
1040 tree_code code
= TREE_CODE (a
);
1041 gassign
*assign
= NULL
;
1043 if (code
== SSA_NAME
)
1045 assign
= dyn_cast
<gassign
*> (SSA_NAME_DEF_STMT (a
));
1047 && TREE_CODE_CLASS (gimple_assign_rhs_code (assign
)) == tcc_comparison
)
1049 a_is_comparison
= true;
1050 a1
= gimple_assign_rhs1 (assign
);
1051 a2
= gimple_assign_rhs2 (assign
);
1052 code
= gimple_assign_rhs_code (assign
);
1053 comp_inner_type
= TREE_TYPE (TREE_TYPE (a1
));
1054 comp_width
= vector_element_bits_tree (TREE_TYPE (a1
));
1058 if (expand_vec_cond_expr_p (type
, TREE_TYPE (a1
), code
)
1059 || (integer_all_onesp (b
) && integer_zerop (c
)
1060 && expand_vec_cmp_expr_p (type
, TREE_TYPE (a1
), code
)))
1062 gcc_assert (TREE_CODE (a
) == SSA_NAME
|| TREE_CODE (a
) == VECTOR_CST
);
1066 /* Handle vector boolean types with bitmasks. If there is a comparison
1067 and we can expand the comparison into the vector boolean bitmask,
1068 or otherwise if it is compatible with type, we can transform
1069 vbfld_1 = x_2 < y_3 ? vbfld_4 : vbfld_5;
1072 tmp_7 = tmp_6 & vbfld_4;
1074 tmp_9 = tmp_8 & vbfld_5;
1075 vbfld_1 = tmp_7 | tmp_9;
1076 Similarly for vbfld_10 instead of x_2 < y_3. */
1077 if (VECTOR_BOOLEAN_TYPE_P (type
)
1078 && SCALAR_INT_MODE_P (TYPE_MODE (type
))
1079 && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type
)),
1080 TYPE_VECTOR_SUBPARTS (type
)
1081 * GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type
))))
1083 ? useless_type_conversion_p (type
, TREE_TYPE (a
))
1084 : expand_vec_cmp_expr_p (TREE_TYPE (a1
), type
, TREE_CODE (a
))))
1086 if (a_is_comparison
)
1087 a
= gimplify_build2 (gsi
, code
, type
, a1
, a2
);
1088 a1
= gimplify_build2 (gsi
, BIT_AND_EXPR
, type
, a
, b
);
1089 a2
= gimplify_build1 (gsi
, BIT_NOT_EXPR
, type
, a
);
1090 a2
= gimplify_build2 (gsi
, BIT_AND_EXPR
, type
, a2
, c
);
1091 a
= gimplify_build2 (gsi
, BIT_IOR_EXPR
, type
, a1
, a2
);
1092 gimple_assign_set_rhs_from_tree (gsi
, a
);
1093 update_stmt (gsi_stmt (*gsi
));
1097 /* TODO: try and find a smaller vector type. */
1099 if (!warning_suppressed_p (stmt
, OPT_Wvector_operation_performance
))
1100 warning_at (loc
, OPT_Wvector_operation_performance
,
1101 "vector condition will be expanded piecewise");
1103 if (!a_is_comparison
1104 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a
))
1105 && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (a
)))
1106 && known_lt (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (a
))),
1107 TYPE_VECTOR_SUBPARTS (TREE_TYPE (a
))
1108 * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
1109 (TREE_TYPE (TREE_TYPE (a
))))))
1111 a_is_scalar_bitmask
= true;
1112 int prec
= GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (a
)));
1113 tree atype
= build_nonstandard_integer_type (prec
, 1);
1114 a
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
, atype
, a
);
1116 else if (!a_is_comparison
1117 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a
)))
1118 comp_width
= vector_element_bits_tree (TREE_TYPE (a
));
1120 int nunits
= nunits_for_known_piecewise_op (type
);
1121 vec_alloc (v
, nunits
);
1122 bool constant_p
= true;
1123 for (int i
= 0; i
< nunits
; i
++)
1126 tree bb
= tree_vec_extract (gsi
, inner_type
, b
, width
, index
);
1127 tree cc
= tree_vec_extract (gsi
, inner_type
, c
, width
, index
);
1128 if (a_is_comparison
)
1130 tree aa1
= tree_vec_extract (gsi
, comp_inner_type
, a1
,
1131 comp_width
, comp_index
);
1132 tree aa2
= tree_vec_extract (gsi
, comp_inner_type
, a2
,
1133 comp_width
, comp_index
);
1134 aa
= gimplify_build2 (gsi
, code
, cond_type
, aa1
, aa2
);
1136 else if (a_is_scalar_bitmask
)
1138 wide_int w
= wi::set_bit_in_zero (i
, TYPE_PRECISION (TREE_TYPE (a
)));
1139 result
= gimplify_build2 (gsi
, BIT_AND_EXPR
, TREE_TYPE (a
),
1140 a
, wide_int_to_tree (TREE_TYPE (a
), w
));
1141 aa
= gimplify_build2 (gsi
, NE_EXPR
, boolean_type_node
, result
,
1142 build_zero_cst (TREE_TYPE (a
)));
1145 aa
= tree_vec_extract (gsi
, cond_type
, a
, comp_width
, comp_index
);
1146 result
= gimplify_build3 (gsi
, COND_EXPR
, inner_type
, aa
, bb
, cc
);
1147 if (!CONSTANT_CLASS_P (result
))
1149 constructor_elt ce
= {NULL_TREE
, result
};
1151 index
= int_const_binop (PLUS_EXPR
, index
, width
);
1152 if (width
== comp_width
)
1155 comp_index
= int_const_binop (PLUS_EXPR
, comp_index
, comp_width
);
1159 constr
= build_vector_from_ctor (type
, v
);
1161 constr
= build_constructor (type
, v
);
1162 gimple_assign_set_rhs_from_tree (gsi
, constr
);
1163 update_stmt (gsi_stmt (*gsi
));
1165 if (a_is_comparison
)
1166 bitmap_set_bit (dce_ssa_names
,
1167 SSA_NAME_VERSION (gimple_assign_lhs (assign
)));
1173 expand_vector_operation (gimple_stmt_iterator
*gsi
, tree type
, tree compute_type
,
1174 gassign
*assign
, enum tree_code code
,
1175 bitmap dce_ssa_names
)
1177 machine_mode compute_mode
= TYPE_MODE (compute_type
);
1179 /* If the compute mode is not a vector mode (hence we are not decomposing
1180 a BLKmode vector to smaller, hardware-supported vectors), we may want
1181 to expand the operations in parallel. */
1182 if (!VECTOR_MODE_P (compute_mode
))
1187 if (ANY_INTEGRAL_TYPE_P (type
) && !TYPE_OVERFLOW_TRAPS (type
))
1188 return expand_vector_addition (gsi
, do_binop
, do_plus_minus
, type
,
1189 gimple_assign_rhs1 (assign
),
1190 gimple_assign_rhs2 (assign
), code
);
1194 if (ANY_INTEGRAL_TYPE_P (type
) && !TYPE_OVERFLOW_TRAPS (type
))
1195 return expand_vector_addition (gsi
, do_unop
, do_negate
, type
,
1196 gimple_assign_rhs1 (assign
),
1203 return expand_vector_parallel (gsi
, do_binop
, type
,
1204 gimple_assign_rhs1 (assign
),
1205 gimple_assign_rhs2 (assign
), code
);
1208 return expand_vector_parallel (gsi
, do_unop
, type
,
1209 gimple_assign_rhs1 (assign
),
1224 case UNORDERED_EXPR
:
1226 tree rhs1
= gimple_assign_rhs1 (assign
);
1227 tree rhs2
= gimple_assign_rhs2 (assign
);
1229 return expand_vector_comparison (gsi
, type
, rhs1
, rhs2
, code
,
1233 case TRUNC_DIV_EXPR
:
1234 case TRUNC_MOD_EXPR
:
1236 tree rhs1
= gimple_assign_rhs1 (assign
);
1237 tree rhs2
= gimple_assign_rhs2 (assign
);
1240 /* Check if the target was going to handle it through the special
1241 division callback hook. */
1242 tree cst
= uniform_integer_cst_p (rhs2
);
1244 targetm
.vectorize
.can_special_div_by_const (code
, type
,
1247 NULL_RTX
, NULL_RTX
))
1252 || !VECTOR_INTEGER_TYPE_P (type
)
1253 || TREE_CODE (rhs2
) != VECTOR_CST
1254 || !VECTOR_MODE_P (TYPE_MODE (type
)))
1257 ret
= expand_vector_divmod (gsi
, type
, rhs1
, rhs2
, code
);
1258 if (ret
!= NULL_TREE
)
1267 if (TREE_CODE_CLASS (code
) == tcc_unary
)
1268 return expand_vector_piecewise (gsi
, do_unop
, type
, compute_type
,
1269 gimple_assign_rhs1 (assign
),
1270 NULL_TREE
, code
, false);
1272 return expand_vector_piecewise (gsi
, do_binop
, type
, compute_type
,
1273 gimple_assign_rhs1 (assign
),
1274 gimple_assign_rhs2 (assign
), code
, false);
1278 a_5 = { b_7, b_7 + 3, b_7 + 6, b_7 + 9 };
1280 _9 = { b_7, b_7, b_7, b_7 };
1281 a_5 = _9 + { 0, 3, 6, 9 };
1282 because vector splat operation is usually more efficient
1283 than piecewise initialization of the vector. */
1286 optimize_vector_constructor (gimple_stmt_iterator
*gsi
)
1288 gassign
*stmt
= as_a
<gassign
*> (gsi_stmt (*gsi
));
1289 tree lhs
= gimple_assign_lhs (stmt
);
1290 tree rhs
= gimple_assign_rhs1 (stmt
);
1291 tree type
= TREE_TYPE (rhs
);
1293 unsigned HOST_WIDE_INT nelts
;
1294 bool all_same
= true;
1295 constructor_elt
*elt
;
1297 tree base
= NULL_TREE
;
1300 if (!TYPE_VECTOR_SUBPARTS (type
).is_constant (&nelts
)
1302 || CONSTRUCTOR_NELTS (rhs
) != nelts
)
1304 op
= optab_for_tree_code (PLUS_EXPR
, type
, optab_default
);
1305 if (op
== unknown_optab
1306 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
1308 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (rhs
), i
, elt
)
1309 if (TREE_CODE (elt
->value
) != SSA_NAME
1310 || TREE_CODE (TREE_TYPE (elt
->value
)) == VECTOR_TYPE
)
1314 tree this_base
= elt
->value
;
1315 if (this_base
!= CONSTRUCTOR_ELT (rhs
, 0)->value
)
1317 for (j
= 0; j
< nelts
+ 1; j
++)
1319 g
= SSA_NAME_DEF_STMT (this_base
);
1320 if (is_gimple_assign (g
)
1321 && gimple_assign_rhs_code (g
) == PLUS_EXPR
1322 && TREE_CODE (gimple_assign_rhs2 (g
)) == INTEGER_CST
1323 && TREE_CODE (gimple_assign_rhs1 (g
)) == SSA_NAME
1324 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g
)))
1325 this_base
= gimple_assign_rhs1 (g
);
1331 else if (this_base
!= base
)
1336 tree_vector_builder
cst (type
, nelts
, 1);
1337 for (i
= 0; i
< nelts
; i
++)
1339 tree this_base
= CONSTRUCTOR_ELT (rhs
, i
)->value
;
1340 tree elt
= build_zero_cst (TREE_TYPE (base
));
1341 while (this_base
!= base
)
1343 g
= SSA_NAME_DEF_STMT (this_base
);
1344 elt
= fold_binary (PLUS_EXPR
, TREE_TYPE (base
),
1345 elt
, gimple_assign_rhs2 (g
));
1346 if (elt
== NULL_TREE
1347 || TREE_CODE (elt
) != INTEGER_CST
1348 || TREE_OVERFLOW (elt
))
1350 this_base
= gimple_assign_rhs1 (g
);
1352 cst
.quick_push (elt
);
1354 for (i
= 0; i
< nelts
; i
++)
1355 CONSTRUCTOR_ELT (rhs
, i
)->value
= base
;
1356 g
= gimple_build_assign (make_ssa_name (type
), rhs
);
1357 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1358 g
= gimple_build_assign (lhs
, PLUS_EXPR
, gimple_assign_lhs (g
),
1360 gsi_replace (gsi
, g
, false);
1363 /* Return a type for the widest vector mode whose components are of type
1364 TYPE, or NULL_TREE if none is found. */
1367 type_for_widest_vector_mode (tree type
, optab op
)
1369 machine_mode inner_mode
= TYPE_MODE (type
);
1370 machine_mode best_mode
= VOIDmode
, mode
;
1371 poly_int64 best_nunits
= 0;
1373 if (SCALAR_FLOAT_MODE_P (inner_mode
))
1374 mode
= MIN_MODE_VECTOR_FLOAT
;
1375 else if (SCALAR_FRACT_MODE_P (inner_mode
))
1376 mode
= MIN_MODE_VECTOR_FRACT
;
1377 else if (SCALAR_UFRACT_MODE_P (inner_mode
))
1378 mode
= MIN_MODE_VECTOR_UFRACT
;
1379 else if (SCALAR_ACCUM_MODE_P (inner_mode
))
1380 mode
= MIN_MODE_VECTOR_ACCUM
;
1381 else if (SCALAR_UACCUM_MODE_P (inner_mode
))
1382 mode
= MIN_MODE_VECTOR_UACCUM
;
1383 else if (inner_mode
== BImode
)
1384 mode
= MIN_MODE_VECTOR_BOOL
;
1386 mode
= MIN_MODE_VECTOR_INT
;
1388 FOR_EACH_MODE_FROM (mode
, mode
)
1389 if (GET_MODE_INNER (mode
) == inner_mode
1390 && maybe_gt (GET_MODE_NUNITS (mode
), best_nunits
)
1391 && optab_handler (op
, mode
) != CODE_FOR_nothing
)
1392 best_mode
= mode
, best_nunits
= GET_MODE_NUNITS (mode
);
1394 if (best_mode
== VOIDmode
)
1397 return build_vector_type_for_mode (type
, best_mode
);
1401 /* Build a reference to the element of the vector VECT. Function
1402 returns either the element itself, either BIT_FIELD_REF, or an
1403 ARRAY_REF expression.
1405 GSI is required to insert temporary variables while building a
1406 refernece to the element of the vector VECT.
1408 PTMPVEC is a pointer to the temporary variable for caching
1409 purposes. In case when PTMPVEC is NULL new temporary variable
1412 vector_element (gimple_stmt_iterator
*gsi
, tree vect
, tree idx
, tree
*ptmpvec
)
1414 tree vect_type
, vect_elt_type
;
1418 bool need_asgn
= true;
1419 unsigned int elements
;
1421 vect_type
= TREE_TYPE (vect
);
1422 vect_elt_type
= TREE_TYPE (vect_type
);
1423 elements
= nunits_for_known_piecewise_op (vect_type
);
1425 if (TREE_CODE (idx
) == INTEGER_CST
)
1427 unsigned HOST_WIDE_INT index
;
1429 /* Given that we're about to compute a binary modulus,
1430 we don't care about the high bits of the value. */
1431 index
= TREE_INT_CST_LOW (idx
);
1432 if (!tree_fits_uhwi_p (idx
) || index
>= elements
)
1434 index
&= elements
- 1;
1435 idx
= build_int_cst (TREE_TYPE (idx
), index
);
1438 /* When lowering a vector statement sequence do some easy
1439 simplification by looking through intermediate vector results. */
1440 if (TREE_CODE (vect
) == SSA_NAME
)
1442 gimple
*def_stmt
= SSA_NAME_DEF_STMT (vect
);
1443 if (is_gimple_assign (def_stmt
)
1444 && (gimple_assign_rhs_code (def_stmt
) == VECTOR_CST
1445 || gimple_assign_rhs_code (def_stmt
) == CONSTRUCTOR
))
1446 vect
= gimple_assign_rhs1 (def_stmt
);
1449 if (TREE_CODE (vect
) == VECTOR_CST
)
1450 return VECTOR_CST_ELT (vect
, index
);
1451 else if (TREE_CODE (vect
) == CONSTRUCTOR
1452 && (CONSTRUCTOR_NELTS (vect
) == 0
1453 || TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (vect
, 0)->value
))
1456 if (index
< CONSTRUCTOR_NELTS (vect
))
1457 return CONSTRUCTOR_ELT (vect
, index
)->value
;
1458 return build_zero_cst (vect_elt_type
);
1462 tree size
= vector_element_bits_tree (vect_type
);
1463 tree pos
= fold_build2 (MULT_EXPR
, bitsizetype
, bitsize_int (index
),
1465 return fold_build3 (BIT_FIELD_REF
, vect_elt_type
, vect
, size
, pos
);
1470 tmpvec
= create_tmp_var (vect_type
, "vectmp");
1472 tmpvec
= *ptmpvec
= create_tmp_var (vect_type
, "vectmp");
1481 TREE_ADDRESSABLE (tmpvec
) = 1;
1482 asgn
= gimple_build_assign (tmpvec
, vect
);
1483 gsi_insert_before (gsi
, asgn
, GSI_SAME_STMT
);
1486 arraytype
= build_array_type_nelts (vect_elt_type
, elements
);
1487 return build4 (ARRAY_REF
, vect_elt_type
,
1488 build1 (VIEW_CONVERT_EXPR
, arraytype
, tmpvec
),
1489 idx
, NULL_TREE
, NULL_TREE
);
1492 /* Check if VEC_PERM_EXPR within the given setting is supported
1493 by hardware, or lower it piecewise.
1495 When VEC_PERM_EXPR has the same first and second operands:
1496 VEC_PERM_EXPR <v0, v0, mask> the lowered version would be
1497 {v0[mask[0]], v0[mask[1]], ...}
1498 MASK and V0 must have the same number of elements.
1500 Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to
1501 {mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...}
1502 V0 and V1 must have the same type. MASK, V0, V1 must have the
1503 same number of arguments. */
1506 lower_vec_perm (gimple_stmt_iterator
*gsi
)
1508 gassign
*stmt
= as_a
<gassign
*> (gsi_stmt (*gsi
));
1509 tree mask
= gimple_assign_rhs3 (stmt
);
1510 tree vec0
= gimple_assign_rhs1 (stmt
);
1511 tree vec1
= gimple_assign_rhs2 (stmt
);
1512 tree vect_type
= TREE_TYPE (vec0
);
1513 tree mask_type
= TREE_TYPE (mask
);
1514 tree vect_elt_type
= TREE_TYPE (vect_type
);
1515 tree mask_elt_type
= TREE_TYPE (mask_type
);
1516 unsigned HOST_WIDE_INT elements
;
1517 vec
<constructor_elt
, va_gc
> *v
;
1518 tree constr
, t
, si
, i_val
;
1519 tree vec0tmp
= NULL_TREE
, vec1tmp
= NULL_TREE
, masktmp
= NULL_TREE
;
1520 bool two_operand_p
= !operand_equal_p (vec0
, vec1
, 0);
1521 location_t loc
= gimple_location (gsi_stmt (*gsi
));
1524 if (!TYPE_VECTOR_SUBPARTS (vect_type
).is_constant (&elements
))
1527 if (TREE_CODE (mask
) == SSA_NAME
)
1529 gimple
*def_stmt
= SSA_NAME_DEF_STMT (mask
);
1530 if (is_gimple_assign (def_stmt
)
1531 && gimple_assign_rhs_code (def_stmt
) == VECTOR_CST
)
1532 mask
= gimple_assign_rhs1 (def_stmt
);
1535 vec_perm_builder sel_int
;
1537 if (TREE_CODE (mask
) == VECTOR_CST
1538 && tree_to_vec_perm_builder (&sel_int
, mask
))
1540 vec_perm_indices
indices (sel_int
, 2, elements
);
1541 machine_mode vmode
= TYPE_MODE (vect_type
);
1542 tree lhs_type
= TREE_TYPE (gimple_assign_lhs (stmt
));
1543 machine_mode lhs_mode
= TYPE_MODE (lhs_type
);
1544 if (can_vec_perm_const_p (lhs_mode
, vmode
, indices
))
1546 gimple_assign_set_rhs3 (stmt
, mask
);
1550 /* Also detect vec_shr pattern - VEC_PERM_EXPR with zero
1551 vector as VEC1 and a right element shift MASK. */
1552 if (optab_handler (vec_shr_optab
, TYPE_MODE (vect_type
))
1554 && TREE_CODE (vec1
) == VECTOR_CST
1555 && initializer_zerop (vec1
)
1556 && maybe_ne (indices
[0], 0)
1557 && known_lt (poly_uint64 (indices
[0]), elements
))
1559 bool ok_p
= indices
.series_p (0, 1, indices
[0], 1);
1562 for (i
= 1; i
< elements
; ++i
)
1564 poly_uint64 actual
= indices
[i
];
1565 poly_uint64 expected
= i
+ indices
[0];
1566 /* Indices into the second vector are all equivalent. */
1567 if (maybe_lt (actual
, elements
)
1568 ? maybe_ne (actual
, expected
)
1569 : maybe_lt (expected
, elements
))
1572 ok_p
= i
== elements
;
1576 gimple_assign_set_rhs3 (stmt
, mask
);
1581 /* And similarly vec_shl pattern. */
1582 if (optab_handler (vec_shl_optab
, TYPE_MODE (vect_type
))
1584 && TREE_CODE (vec0
) == VECTOR_CST
1585 && initializer_zerop (vec0
))
1587 unsigned int first
= 0;
1588 for (i
= 0; i
< elements
; ++i
)
1589 if (known_eq (poly_uint64 (indices
[i
]), elements
))
1591 if (i
== 0 || first
)
1596 ? maybe_ne (poly_uint64 (indices
[i
]),
1597 elements
+ i
- first
)
1598 : maybe_ge (poly_uint64 (indices
[i
]), elements
))
1600 if (first
&& i
== elements
)
1602 gimple_assign_set_rhs3 (stmt
, mask
);
1608 else if (can_vec_perm_var_p (TYPE_MODE (vect_type
)))
1611 if (!warning_suppressed_p (stmt
, OPT_Wvector_operation_performance
))
1612 warning_at (loc
, OPT_Wvector_operation_performance
,
1613 "vector shuffling operation will be expanded piecewise");
1615 vec_alloc (v
, elements
);
1616 bool constant_p
= true;
1617 for (i
= 0; i
< elements
; i
++)
1620 i_val
= vector_element (gsi
, mask
, si
, &masktmp
);
1622 if (TREE_CODE (i_val
) == INTEGER_CST
)
1624 unsigned HOST_WIDE_INT index
;
1626 index
= TREE_INT_CST_LOW (i_val
);
1627 if (!tree_fits_uhwi_p (i_val
) || index
>= elements
)
1628 i_val
= build_int_cst (mask_elt_type
, index
& (elements
- 1));
1630 if (two_operand_p
&& (index
& elements
) != 0)
1631 t
= vector_element (gsi
, vec1
, i_val
, &vec1tmp
);
1633 t
= vector_element (gsi
, vec0
, i_val
, &vec0tmp
);
1635 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
,
1636 true, GSI_SAME_STMT
);
1640 tree cond
= NULL_TREE
, v0_val
;
1644 cond
= fold_build2 (BIT_AND_EXPR
, mask_elt_type
, i_val
,
1645 build_int_cst (mask_elt_type
, elements
));
1646 cond
= force_gimple_operand_gsi (gsi
, cond
, true, NULL_TREE
,
1647 true, GSI_SAME_STMT
);
1650 i_val
= fold_build2 (BIT_AND_EXPR
, mask_elt_type
, i_val
,
1651 build_int_cst (mask_elt_type
, elements
- 1));
1652 i_val
= force_gimple_operand_gsi (gsi
, i_val
, true, NULL_TREE
,
1653 true, GSI_SAME_STMT
);
1655 v0_val
= vector_element (gsi
, vec0
, i_val
, &vec0tmp
);
1656 v0_val
= force_gimple_operand_gsi (gsi
, v0_val
, true, NULL_TREE
,
1657 true, GSI_SAME_STMT
);
1663 v1_val
= vector_element (gsi
, vec1
, i_val
, &vec1tmp
);
1664 v1_val
= force_gimple_operand_gsi (gsi
, v1_val
, true, NULL_TREE
,
1665 true, GSI_SAME_STMT
);
1667 cond
= fold_build2 (EQ_EXPR
, boolean_type_node
,
1668 cond
, build_zero_cst (mask_elt_type
));
1669 cond
= fold_build3 (COND_EXPR
, vect_elt_type
,
1670 cond
, v0_val
, v1_val
);
1671 t
= force_gimple_operand_gsi (gsi
, cond
, true, NULL_TREE
,
1672 true, GSI_SAME_STMT
);
1678 if (!CONSTANT_CLASS_P (t
))
1680 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
1684 constr
= build_vector_from_ctor (vect_type
, v
);
1686 constr
= build_constructor (vect_type
, v
);
1687 gimple_assign_set_rhs_from_tree (gsi
, constr
);
1688 update_stmt (gsi_stmt (*gsi
));
1691 /* If OP is a uniform vector return the element it is a splat from. */
1694 ssa_uniform_vector_p (tree op
)
1696 if (TREE_CODE (op
) == VECTOR_CST
1697 || TREE_CODE (op
) == VEC_DUPLICATE_EXPR
1698 || TREE_CODE (op
) == CONSTRUCTOR
)
1699 return uniform_vector_p (op
);
1700 if (TREE_CODE (op
) == SSA_NAME
)
1702 gimple
*def_stmt
= SSA_NAME_DEF_STMT (op
);
1703 if (gimple_assign_single_p (def_stmt
))
1704 return uniform_vector_p (gimple_assign_rhs1 (def_stmt
));
1709 /* Return type in which CODE operation with optab OP can be
1713 get_compute_type (enum tree_code code
, optab op
, tree type
)
1715 /* For very wide vectors, try using a smaller vector mode. */
1716 tree compute_type
= type
;
1718 && (!VECTOR_MODE_P (TYPE_MODE (type
))
1719 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
))
1721 tree vector_compute_type
1722 = type_for_widest_vector_mode (TREE_TYPE (type
), op
);
1723 if (vector_compute_type
!= NULL_TREE
1724 && subparts_gt (compute_type
, vector_compute_type
)
1725 && maybe_ne (TYPE_VECTOR_SUBPARTS (vector_compute_type
), 1U)
1726 && (optab_handler (op
, TYPE_MODE (vector_compute_type
))
1727 != CODE_FOR_nothing
))
1728 compute_type
= vector_compute_type
;
1731 /* If we are breaking a BLKmode vector into smaller pieces,
1732 type_for_widest_vector_mode has already looked into the optab,
1733 so skip these checks. */
1734 if (compute_type
== type
)
1736 machine_mode compute_mode
= TYPE_MODE (compute_type
);
1737 if (VECTOR_MODE_P (compute_mode
))
1739 if (op
&& optab_handler (op
, compute_mode
) != CODE_FOR_nothing
)
1740 return compute_type
;
1741 if (code
== MULT_HIGHPART_EXPR
1742 && can_mult_highpart_p (compute_mode
,
1743 TYPE_UNSIGNED (compute_type
)))
1744 return compute_type
;
1746 /* There is no operation in hardware, so fall back to scalars. */
1747 compute_type
= TREE_TYPE (type
);
1750 return compute_type
;
1754 do_cond (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
, tree b
,
1755 tree bitpos
, tree bitsize
, enum tree_code code
,
1756 tree type ATTRIBUTE_UNUSED
)
1758 if (TREE_CODE (TREE_TYPE (a
)) == VECTOR_TYPE
)
1759 a
= tree_vec_extract (gsi
, inner_type
, a
, bitsize
, bitpos
);
1760 if (TREE_CODE (TREE_TYPE (b
)) == VECTOR_TYPE
)
1761 b
= tree_vec_extract (gsi
, inner_type
, b
, bitsize
, bitpos
);
1762 tree cond
= gimple_assign_rhs1 (gsi_stmt (*gsi
));
1763 return gimplify_build3 (gsi
, code
, inner_type
, unshare_expr (cond
), a
, b
);
1766 /* Expand a vector COND_EXPR to scalars, piecewise. */
1768 expand_vector_scalar_condition (gimple_stmt_iterator
*gsi
)
1770 gassign
*stmt
= as_a
<gassign
*> (gsi_stmt (*gsi
));
1771 tree lhs
= gimple_assign_lhs (stmt
);
1772 tree type
= TREE_TYPE (lhs
);
1773 tree compute_type
= get_compute_type (COND_EXPR
, mov_optab
, type
);
1774 machine_mode compute_mode
= TYPE_MODE (compute_type
);
1775 gcc_assert (compute_mode
!= BLKmode
);
1776 tree rhs2
= gimple_assign_rhs2 (stmt
);
1777 tree rhs3
= gimple_assign_rhs3 (stmt
);
1780 /* If the compute mode is not a vector mode (hence we are not decomposing
1781 a BLKmode vector to smaller, hardware-supported vectors), we may want
1782 to expand the operations in parallel. */
1783 if (!VECTOR_MODE_P (compute_mode
))
1784 new_rhs
= expand_vector_parallel (gsi
, do_cond
, type
, rhs2
, rhs3
,
1787 new_rhs
= expand_vector_piecewise (gsi
, do_cond
, type
, compute_type
,
1788 rhs2
, rhs3
, COND_EXPR
, false);
1789 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (new_rhs
)))
1790 new_rhs
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
1793 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
1794 way to do it is change expand_vector_operation and its callees to
1795 return a tree_code, RHS1 and RHS2 instead of a tree. */
1796 gimple_assign_set_rhs_from_tree (gsi
, new_rhs
);
1797 update_stmt (gsi_stmt (*gsi
));
1800 /* Callback for expand_vector_piecewise to do VEC_CONVERT ifn call
1801 lowering. If INNER_TYPE is not a vector type, this is a scalar
1805 do_vec_conversion (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
,
1806 tree decl
, tree bitpos
, tree bitsize
,
1807 enum tree_code code
, tree type
)
1809 a
= tree_vec_extract (gsi
, inner_type
, a
, bitsize
, bitpos
);
1810 if (!VECTOR_TYPE_P (inner_type
))
1811 return gimplify_build1 (gsi
, code
, TREE_TYPE (type
), a
);
1812 if (code
== CALL_EXPR
)
1814 gimple
*g
= gimple_build_call (decl
, 1, a
);
1815 tree lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (decl
)));
1816 gimple_call_set_lhs (g
, lhs
);
1817 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1822 tree outer_type
= build_vector_type (TREE_TYPE (type
),
1823 TYPE_VECTOR_SUBPARTS (inner_type
));
1824 return gimplify_build1 (gsi
, code
, outer_type
, a
);
1828 /* Similarly, but for narrowing conversion. */
1831 do_vec_narrow_conversion (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
,
1832 tree
, tree bitpos
, tree
, enum tree_code code
,
1835 tree itype
= build_vector_type (TREE_TYPE (inner_type
),
1836 exact_div (TYPE_VECTOR_SUBPARTS (inner_type
),
1838 tree b
= tree_vec_extract (gsi
, itype
, a
, TYPE_SIZE (itype
), bitpos
);
1839 tree c
= tree_vec_extract (gsi
, itype
, a
, TYPE_SIZE (itype
),
1840 int_const_binop (PLUS_EXPR
, bitpos
,
1841 TYPE_SIZE (itype
)));
1842 tree outer_type
= build_vector_type (TREE_TYPE (type
),
1843 TYPE_VECTOR_SUBPARTS (inner_type
));
1844 return gimplify_build2 (gsi
, code
, outer_type
, b
, c
);
1847 /* Expand VEC_CONVERT ifn call. */
1850 expand_vector_conversion (gimple_stmt_iterator
*gsi
)
1852 gimple
*stmt
= gsi_stmt (*gsi
);
1854 tree lhs
= gimple_call_lhs (stmt
);
1855 if (lhs
== NULL_TREE
)
1857 g
= gimple_build_nop ();
1858 gsi_replace (gsi
, g
, false);
1861 tree arg
= gimple_call_arg (stmt
, 0);
1862 tree ret_type
= TREE_TYPE (lhs
);
1863 tree arg_type
= TREE_TYPE (arg
);
1864 tree new_rhs
, compute_type
= TREE_TYPE (arg_type
);
1865 enum tree_code code
= NOP_EXPR
;
1866 enum tree_code code1
= ERROR_MARK
;
1867 enum { NARROW
, NONE
, WIDEN
} modifier
= NONE
;
1868 optab optab1
= unknown_optab
;
1870 gcc_checking_assert (VECTOR_TYPE_P (ret_type
) && VECTOR_TYPE_P (arg_type
));
1871 if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type
))
1872 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type
)))
1873 code
= FIX_TRUNC_EXPR
;
1874 else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type
))
1875 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type
)))
1877 unsigned int ret_elt_bits
= vector_element_bits (ret_type
);
1878 unsigned int arg_elt_bits
= vector_element_bits (arg_type
);
1879 if (ret_elt_bits
< arg_elt_bits
)
1881 else if (ret_elt_bits
> arg_elt_bits
)
1884 if (modifier
== NONE
&& (code
== FIX_TRUNC_EXPR
|| code
== FLOAT_EXPR
))
1886 if (supportable_convert_operation (code
, ret_type
, arg_type
, &code1
))
1888 g
= gimple_build_assign (lhs
, code1
, arg
);
1889 gsi_replace (gsi
, g
, false);
1892 /* Can't use get_compute_type here, as supportable_convert_operation
1893 doesn't necessarily use an optab and needs two arguments. */
1894 tree vec_compute_type
1895 = type_for_widest_vector_mode (TREE_TYPE (arg_type
), mov_optab
);
1896 if (vec_compute_type
1897 && VECTOR_MODE_P (TYPE_MODE (vec_compute_type
))
1898 && subparts_gt (arg_type
, vec_compute_type
))
1900 unsigned HOST_WIDE_INT nelts
1901 = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vec_compute_type
));
1904 tree ret1_type
= build_vector_type (TREE_TYPE (ret_type
), nelts
);
1905 tree arg1_type
= build_vector_type (TREE_TYPE (arg_type
), nelts
);
1906 if (supportable_convert_operation (code
, ret1_type
, arg1_type
,
1909 new_rhs
= expand_vector_piecewise (gsi
, do_vec_conversion
,
1910 ret_type
, arg1_type
, arg
,
1911 NULL_TREE
, code1
, false);
1912 g
= gimple_build_assign (lhs
, new_rhs
);
1913 gsi_replace (gsi
, g
, false);
1920 else if (modifier
== NARROW
)
1925 code1
= VEC_PACK_TRUNC_EXPR
;
1926 optab1
= optab_for_tree_code (code1
, arg_type
, optab_default
);
1928 case FIX_TRUNC_EXPR
:
1929 code1
= VEC_PACK_FIX_TRUNC_EXPR
;
1930 /* The signedness is determined from output operand. */
1931 optab1
= optab_for_tree_code (code1
, ret_type
, optab_default
);
1934 code1
= VEC_PACK_FLOAT_EXPR
;
1935 optab1
= optab_for_tree_code (code1
, arg_type
, optab_default
);
1942 compute_type
= get_compute_type (code1
, optab1
, arg_type
);
1943 enum insn_code icode1
;
1944 if (VECTOR_TYPE_P (compute_type
)
1945 && ((icode1
= optab_handler (optab1
, TYPE_MODE (compute_type
)))
1946 != CODE_FOR_nothing
)
1947 && VECTOR_MODE_P (insn_data
[icode1
].operand
[0].mode
))
1950 = build_vector_type (TREE_TYPE (ret_type
),
1951 TYPE_VECTOR_SUBPARTS (compute_type
) * 2);
1952 if (insn_data
[icode1
].operand
[0].mode
== TYPE_MODE (cretd_type
))
1954 if (compute_type
== arg_type
)
1956 new_rhs
= gimplify_build2 (gsi
, code1
, cretd_type
,
1957 arg
, build_zero_cst (arg_type
));
1958 new_rhs
= tree_vec_extract (gsi
, ret_type
, new_rhs
,
1959 TYPE_SIZE (ret_type
),
1961 g
= gimple_build_assign (lhs
, new_rhs
);
1962 gsi_replace (gsi
, g
, false);
1966 = build_vector_type (TREE_TYPE (compute_type
),
1967 TYPE_VECTOR_SUBPARTS (compute_type
) * 2);
1968 if (TYPE_MAIN_VARIANT (dcompute_type
)
1969 == TYPE_MAIN_VARIANT (arg_type
))
1970 new_rhs
= do_vec_narrow_conversion (gsi
, dcompute_type
, arg
,
1971 NULL_TREE
, bitsize_int (0),
1975 new_rhs
= expand_vector_piecewise (gsi
,
1976 do_vec_narrow_conversion
,
1977 arg_type
, dcompute_type
,
1978 arg
, NULL_TREE
, code1
,
1980 g
= gimple_build_assign (lhs
, new_rhs
);
1981 gsi_replace (gsi
, g
, false);
1986 else if (modifier
== WIDEN
)
1988 enum tree_code code2
= ERROR_MARK
;
1989 optab optab2
= unknown_optab
;
1993 code1
= VEC_UNPACK_LO_EXPR
;
1994 code2
= VEC_UNPACK_HI_EXPR
;
1996 case FIX_TRUNC_EXPR
:
1997 code1
= VEC_UNPACK_FIX_TRUNC_LO_EXPR
;
1998 code2
= VEC_UNPACK_FIX_TRUNC_HI_EXPR
;
2001 code1
= VEC_UNPACK_FLOAT_LO_EXPR
;
2002 code2
= VEC_UNPACK_FLOAT_HI_EXPR
;
2007 if (BYTES_BIG_ENDIAN
)
2008 std::swap (code1
, code2
);
2010 if (code
== FIX_TRUNC_EXPR
)
2012 /* The signedness is determined from output operand. */
2013 optab1
= optab_for_tree_code (code1
, ret_type
, optab_default
);
2014 optab2
= optab_for_tree_code (code2
, ret_type
, optab_default
);
2018 optab1
= optab_for_tree_code (code1
, arg_type
, optab_default
);
2019 optab2
= optab_for_tree_code (code2
, arg_type
, optab_default
);
2022 if (optab1
&& optab2
)
2023 compute_type
= get_compute_type (code1
, optab1
, arg_type
);
2025 enum insn_code icode1
, icode2
;
2026 if (VECTOR_TYPE_P (compute_type
)
2027 && ((icode1
= optab_handler (optab1
, TYPE_MODE (compute_type
)))
2028 != CODE_FOR_nothing
)
2029 && ((icode2
= optab_handler (optab2
, TYPE_MODE (compute_type
)))
2030 != CODE_FOR_nothing
)
2031 && VECTOR_MODE_P (insn_data
[icode1
].operand
[0].mode
)
2032 && (insn_data
[icode1
].operand
[0].mode
2033 == insn_data
[icode2
].operand
[0].mode
))
2036 = exact_div (TYPE_VECTOR_SUBPARTS (compute_type
), 2);
2037 tree cretd_type
= build_vector_type (TREE_TYPE (ret_type
), nunits
);
2038 if (insn_data
[icode1
].operand
[0].mode
== TYPE_MODE (cretd_type
))
2040 vec
<constructor_elt
, va_gc
> *v
;
2041 tree part_width
= TYPE_SIZE (compute_type
);
2042 tree index
= bitsize_int (0);
2043 int nunits
= nunits_for_known_piecewise_op (arg_type
);
2044 int delta
= tree_to_uhwi (part_width
) / arg_elt_bits
;
2046 location_t loc
= gimple_location (gsi_stmt (*gsi
));
2048 if (compute_type
!= arg_type
)
2050 if (!warning_suppressed_p (gsi_stmt (*gsi
),
2051 OPT_Wvector_operation_performance
))
2052 warning_at (loc
, OPT_Wvector_operation_performance
,
2053 "vector operation will be expanded piecewise");
2061 vec_alloc (v
, (nunits
+ delta
- 1) / delta
* 2);
2062 bool constant_p
= true;
2063 for (i
= 0; i
< nunits
;
2064 i
+= delta
, index
= int_const_binop (PLUS_EXPR
, index
,
2068 if (compute_type
!= arg_type
)
2069 a
= tree_vec_extract (gsi
, compute_type
, a
, part_width
,
2071 tree result
= gimplify_build1 (gsi
, code1
, cretd_type
, a
);
2072 constructor_elt ce
= { NULL_TREE
, result
};
2073 if (!CONSTANT_CLASS_P (ce
.value
))
2076 ce
.value
= gimplify_build1 (gsi
, code2
, cretd_type
, a
);
2077 if (!CONSTANT_CLASS_P (ce
.value
))
2083 new_rhs
= build_vector_from_ctor (ret_type
, v
);
2085 new_rhs
= build_constructor (ret_type
, v
);
2086 g
= gimple_build_assign (lhs
, new_rhs
);
2087 gsi_replace (gsi
, g
, false);
2093 new_rhs
= expand_vector_piecewise (gsi
, do_vec_conversion
, arg_type
,
2094 TREE_TYPE (arg_type
), arg
,
2095 NULL_TREE
, code
, false, ret_type
);
2096 g
= gimple_build_assign (lhs
, new_rhs
);
2097 gsi_replace (gsi
, g
, false);
2100 /* Process one statement. If we identify a vector operation, expand it. */
2103 expand_vector_operations_1 (gimple_stmt_iterator
*gsi
,
2104 bitmap dce_ssa_names
)
2106 tree lhs
, rhs1
, rhs2
= NULL
, type
, compute_type
= NULL_TREE
;
2107 enum tree_code code
;
2108 optab op
= unknown_optab
;
2109 enum gimple_rhs_class rhs_class
;
2112 /* Only consider code == GIMPLE_ASSIGN. */
2113 gassign
*stmt
= dyn_cast
<gassign
*> (gsi_stmt (*gsi
));
2116 if (gimple_call_internal_p (gsi_stmt (*gsi
), IFN_VEC_CONVERT
))
2117 expand_vector_conversion (gsi
);
2121 code
= gimple_assign_rhs_code (stmt
);
2122 rhs_class
= get_gimple_rhs_class (code
);
2123 lhs
= gimple_assign_lhs (stmt
);
2125 if (code
== VEC_PERM_EXPR
)
2127 lower_vec_perm (gsi
);
2131 if (code
== VEC_COND_EXPR
)
2133 expand_vector_condition (gsi
, dce_ssa_names
);
2137 if (code
== COND_EXPR
2138 && TREE_CODE (TREE_TYPE (gimple_assign_lhs (stmt
))) == VECTOR_TYPE
2139 && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt
))) == BLKmode
)
2141 expand_vector_scalar_condition (gsi
);
2145 if (code
== CONSTRUCTOR
2146 && TREE_CODE (lhs
) == SSA_NAME
2147 && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (lhs
)))
2148 && !gimple_clobber_p (stmt
)
2151 optimize_vector_constructor (gsi
);
2155 if (rhs_class
!= GIMPLE_UNARY_RHS
&& rhs_class
!= GIMPLE_BINARY_RHS
)
2158 rhs1
= gimple_assign_rhs1 (stmt
);
2159 if (rhs_class
== GIMPLE_BINARY_RHS
)
2160 rhs2
= gimple_assign_rhs2 (stmt
);
2162 type
= TREE_TYPE (lhs
);
2163 if (!VECTOR_TYPE_P (type
)
2164 || !VECTOR_TYPE_P (TREE_TYPE (rhs1
)))
2167 /* A scalar operation pretending to be a vector one. */
2168 if (VECTOR_BOOLEAN_TYPE_P (type
)
2169 && !VECTOR_MODE_P (TYPE_MODE (type
))
2170 && TYPE_MODE (type
) != BLKmode
2171 && (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt
)) != tcc_comparison
2172 || (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1
))
2173 && !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs1
)))
2174 && TYPE_MODE (TREE_TYPE (rhs1
)) != BLKmode
)))
2177 /* If the vector operation is operating on all same vector elements
2178 implement it with a scalar operation and a splat if the target
2179 supports the scalar operation. */
2180 tree srhs1
, srhs2
= NULL_TREE
;
2181 if ((srhs1
= ssa_uniform_vector_p (rhs1
)) != NULL_TREE
2182 && (rhs2
== NULL_TREE
2183 || (! VECTOR_TYPE_P (TREE_TYPE (rhs2
))
2185 || (srhs2
= ssa_uniform_vector_p (rhs2
)) != NULL_TREE
)
2186 /* As we query direct optabs restrict to non-convert operations. */
2187 && TYPE_MODE (TREE_TYPE (type
)) == TYPE_MODE (TREE_TYPE (srhs1
)))
2189 op
= optab_for_tree_code (code
, TREE_TYPE (type
), optab_scalar
);
2190 if (op
>= FIRST_NORM_OPTAB
&& op
<= LAST_NORM_OPTAB
2191 && optab_handler (op
, TYPE_MODE (TREE_TYPE (type
))) != CODE_FOR_nothing
)
2193 tree stype
= TREE_TYPE (TREE_TYPE (lhs
));
2194 tree slhs
= (rhs2
!= NULL_TREE
)
2195 ? gimplify_build2 (gsi
, code
, stype
, srhs1
, srhs2
)
2196 : gimplify_build1 (gsi
, code
, stype
, srhs1
);
2197 gimple_assign_set_rhs_from_tree (gsi
,
2198 build_vector_from_val (type
, slhs
));
2204 if (CONVERT_EXPR_CODE_P (code
)
2205 || code
== FLOAT_EXPR
2206 || code
== FIX_TRUNC_EXPR
2207 || code
== VIEW_CONVERT_EXPR
)
2210 /* The signedness is determined from input argument. */
2211 if (code
== VEC_UNPACK_FLOAT_HI_EXPR
2212 || code
== VEC_UNPACK_FLOAT_LO_EXPR
2213 || code
== VEC_PACK_FLOAT_EXPR
)
2215 /* We do not know how to scalarize those. */
2219 /* For widening/narrowing vector operations, the relevant type is of the
2220 arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is
2221 calculated in the same way above. */
2222 if (code
== WIDEN_SUM_EXPR
2223 || code
== VEC_WIDEN_PLUS_HI_EXPR
2224 || code
== VEC_WIDEN_PLUS_LO_EXPR
2225 || code
== VEC_WIDEN_MINUS_HI_EXPR
2226 || code
== VEC_WIDEN_MINUS_LO_EXPR
2227 || code
== VEC_WIDEN_MULT_HI_EXPR
2228 || code
== VEC_WIDEN_MULT_LO_EXPR
2229 || code
== VEC_WIDEN_MULT_EVEN_EXPR
2230 || code
== VEC_WIDEN_MULT_ODD_EXPR
2231 || code
== VEC_UNPACK_HI_EXPR
2232 || code
== VEC_UNPACK_LO_EXPR
2233 || code
== VEC_UNPACK_FIX_TRUNC_HI_EXPR
2234 || code
== VEC_UNPACK_FIX_TRUNC_LO_EXPR
2235 || code
== VEC_PACK_TRUNC_EXPR
2236 || code
== VEC_PACK_SAT_EXPR
2237 || code
== VEC_PACK_FIX_TRUNC_EXPR
2238 || code
== VEC_WIDEN_LSHIFT_HI_EXPR
2239 || code
== VEC_WIDEN_LSHIFT_LO_EXPR
)
2241 /* We do not know how to scalarize those. */
2245 /* Choose between vector shift/rotate by vector and vector shift/rotate by
2247 if (code
== LSHIFT_EXPR
2248 || code
== RSHIFT_EXPR
2249 || code
== LROTATE_EXPR
2250 || code
== RROTATE_EXPR
)
2254 /* Check whether we have vector <op> {x,x,x,x} where x
2255 could be a scalar variable or a constant. Transform
2256 vector <op> {x,x,x,x} ==> vector <op> scalar. */
2257 if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2
)))
2261 if ((first
= ssa_uniform_vector_p (rhs2
)) != NULL_TREE
)
2263 gimple_assign_set_rhs2 (stmt
, first
);
2269 opv
= optab_for_tree_code (code
, type
, optab_vector
);
2270 if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2
)))
2274 op
= optab_for_tree_code (code
, type
, optab_scalar
);
2276 compute_type
= get_compute_type (code
, op
, type
);
2277 if (compute_type
== type
)
2279 /* The rtl expander will expand vector/scalar as vector/vector
2280 if necessary. Pick one with wider vector type. */
2281 tree compute_vtype
= get_compute_type (code
, opv
, type
);
2282 if (subparts_gt (compute_vtype
, compute_type
))
2284 compute_type
= compute_vtype
;
2289 if (code
== LROTATE_EXPR
|| code
== RROTATE_EXPR
)
2291 if (compute_type
== NULL_TREE
)
2292 compute_type
= get_compute_type (code
, op
, type
);
2293 if (compute_type
== type
)
2295 /* Before splitting vector rotates into scalar rotates,
2296 see if we can't use vector shifts and BIT_IOR_EXPR
2297 instead. For vector by vector rotates we'd also
2298 need to check BIT_AND_EXPR and NEGATE_EXPR, punt there
2299 for now, fold doesn't seem to create such rotates anyway. */
2300 if (compute_type
== TREE_TYPE (type
)
2301 && !VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2
)))
2303 optab oplv
= vashl_optab
, opl
= ashl_optab
;
2304 optab oprv
= vlshr_optab
, opr
= lshr_optab
, opo
= ior_optab
;
2305 tree compute_lvtype
= get_compute_type (LSHIFT_EXPR
, oplv
, type
);
2306 tree compute_rvtype
= get_compute_type (RSHIFT_EXPR
, oprv
, type
);
2307 tree compute_otype
= get_compute_type (BIT_IOR_EXPR
, opo
, type
);
2308 tree compute_ltype
= get_compute_type (LSHIFT_EXPR
, opl
, type
);
2309 tree compute_rtype
= get_compute_type (RSHIFT_EXPR
, opr
, type
);
2310 /* The rtl expander will expand vector/scalar as vector/vector
2311 if necessary. Pick one with wider vector type. */
2312 if (subparts_gt (compute_lvtype
, compute_ltype
))
2314 compute_ltype
= compute_lvtype
;
2317 if (subparts_gt (compute_rvtype
, compute_rtype
))
2319 compute_rtype
= compute_rvtype
;
2322 /* Pick the narrowest type from LSHIFT_EXPR, RSHIFT_EXPR and
2324 compute_type
= compute_ltype
;
2325 if (subparts_gt (compute_type
, compute_rtype
))
2326 compute_type
= compute_rtype
;
2327 if (subparts_gt (compute_type
, compute_otype
))
2328 compute_type
= compute_otype
;
2329 /* Verify all 3 operations can be performed in that type. */
2330 if (compute_type
!= TREE_TYPE (type
))
2332 if (optab_handler (opl
, TYPE_MODE (compute_type
))
2334 || optab_handler (opr
, TYPE_MODE (compute_type
))
2336 || optab_handler (opo
, TYPE_MODE (compute_type
))
2337 == CODE_FOR_nothing
)
2338 compute_type
= TREE_TYPE (type
);
2344 op
= optab_for_tree_code (code
, type
, optab_default
);
2346 /* Optabs will try converting a negation into a subtraction, so
2347 look for it as well. TODO: negation of floating-point vectors
2348 might be turned into an exclusive OR toggling the sign bit. */
2349 if (op
== unknown_optab
2350 && code
== NEGATE_EXPR
2351 && INTEGRAL_TYPE_P (TREE_TYPE (type
)))
2352 op
= optab_for_tree_code (MINUS_EXPR
, type
, optab_default
);
2354 if (compute_type
== NULL_TREE
)
2355 compute_type
= get_compute_type (code
, op
, type
);
2356 if (compute_type
== type
)
2359 new_rhs
= expand_vector_operation (gsi
, type
, compute_type
, stmt
, code
,
2362 /* Leave expression untouched for later expansion. */
2363 if (new_rhs
== NULL_TREE
)
2366 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (new_rhs
)))
2367 new_rhs
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
2370 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
2371 way to do it is change expand_vector_operation and its callees to
2372 return a tree_code, RHS1 and RHS2 instead of a tree. */
2373 gimple_assign_set_rhs_from_tree (gsi
, new_rhs
);
2374 update_stmt (gsi_stmt (*gsi
));
2377 /* Use this to lower vector operations introduced by the vectorizer,
2378 if it may need the bit-twiddling tricks implemented in this file. */
2381 expand_vector_operations (void)
2383 gimple_stmt_iterator gsi
;
2385 bool cfg_changed
= false;
2387 auto_bitmap dce_ssa_names
;
2389 FOR_EACH_BB_FN (bb
, cfun
)
2391 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2393 expand_vector_operations_1 (&gsi
, dce_ssa_names
);
2394 /* ??? If we do not cleanup EH then we will ICE in
2395 verification. But in reality we have created wrong-code
2396 as we did not properly transition EH info and edges to
2397 the piecewise computations. */
2398 if (maybe_clean_eh_stmt (gsi_stmt (gsi
))
2399 && gimple_purge_dead_eh_edges (bb
))
2404 simple_dce_from_worklist (dce_ssa_names
);
2406 return cfg_changed
? TODO_cleanup_cfg
: 0;
2411 const pass_data pass_data_lower_vector
=
2413 GIMPLE_PASS
, /* type */
2414 "veclower", /* name */
2415 OPTGROUP_VEC
, /* optinfo_flags */
2416 TV_NONE
, /* tv_id */
2417 PROP_cfg
, /* properties_required */
2418 PROP_gimple_lvec
, /* properties_provided */
2419 0, /* properties_destroyed */
2420 0, /* todo_flags_start */
2421 TODO_update_ssa
, /* todo_flags_finish */
2424 class pass_lower_vector
: public gimple_opt_pass
2427 pass_lower_vector (gcc::context
*ctxt
)
2428 : gimple_opt_pass (pass_data_lower_vector
, ctxt
)
2431 /* opt_pass methods: */
2432 bool gate (function
*fun
) final override
2434 return !(fun
->curr_properties
& PROP_gimple_lvec
);
2437 unsigned int execute (function
*) final override
2439 return expand_vector_operations ();
2442 }; // class pass_lower_vector
2447 make_pass_lower_vector (gcc::context
*ctxt
)
2449 return new pass_lower_vector (ctxt
);
2454 const pass_data pass_data_lower_vector_ssa
=
2456 GIMPLE_PASS
, /* type */
2457 "veclower2", /* name */
2458 OPTGROUP_VEC
, /* optinfo_flags */
2459 TV_NONE
, /* tv_id */
2460 PROP_cfg
, /* properties_required */
2461 PROP_gimple_lvec
, /* properties_provided */
2462 0, /* properties_destroyed */
2463 0, /* todo_flags_start */
2465 | TODO_cleanup_cfg
), /* todo_flags_finish */
2468 class pass_lower_vector_ssa
: public gimple_opt_pass
2471 pass_lower_vector_ssa (gcc::context
*ctxt
)
2472 : gimple_opt_pass (pass_data_lower_vector_ssa
, ctxt
)
2475 /* opt_pass methods: */
2476 opt_pass
* clone () final override
2478 return new pass_lower_vector_ssa (m_ctxt
);
2480 unsigned int execute (function
*) final override
2482 return expand_vector_operations ();
2485 }; // class pass_lower_vector_ssa
2490 make_pass_lower_vector_ssa (gcc::context
*ctxt
)
2492 return new pass_lower_vector_ssa (ctxt
);
2495 #include "gt-tree-vect-generic.h"