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
);
1241 || !VECTOR_INTEGER_TYPE_P (type
)
1242 || TREE_CODE (rhs2
) != VECTOR_CST
1243 || !VECTOR_MODE_P (TYPE_MODE (type
)))
1246 ret
= expand_vector_divmod (gsi
, type
, rhs1
, rhs2
, code
);
1247 if (ret
!= NULL_TREE
)
1256 if (TREE_CODE_CLASS (code
) == tcc_unary
)
1257 return expand_vector_piecewise (gsi
, do_unop
, type
, compute_type
,
1258 gimple_assign_rhs1 (assign
),
1259 NULL_TREE
, code
, false);
1261 return expand_vector_piecewise (gsi
, do_binop
, type
, compute_type
,
1262 gimple_assign_rhs1 (assign
),
1263 gimple_assign_rhs2 (assign
), code
, false);
1267 a_5 = { b_7, b_7 + 3, b_7 + 6, b_7 + 9 };
1269 _9 = { b_7, b_7, b_7, b_7 };
1270 a_5 = _9 + { 0, 3, 6, 9 };
1271 because vector splat operation is usually more efficient
1272 than piecewise initialization of the vector. */
1275 optimize_vector_constructor (gimple_stmt_iterator
*gsi
)
1277 gassign
*stmt
= as_a
<gassign
*> (gsi_stmt (*gsi
));
1278 tree lhs
= gimple_assign_lhs (stmt
);
1279 tree rhs
= gimple_assign_rhs1 (stmt
);
1280 tree type
= TREE_TYPE (rhs
);
1282 unsigned HOST_WIDE_INT nelts
;
1283 bool all_same
= true;
1284 constructor_elt
*elt
;
1286 tree base
= NULL_TREE
;
1289 if (!TYPE_VECTOR_SUBPARTS (type
).is_constant (&nelts
)
1291 || CONSTRUCTOR_NELTS (rhs
) != nelts
)
1293 op
= optab_for_tree_code (PLUS_EXPR
, type
, optab_default
);
1294 if (op
== unknown_optab
1295 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
)
1297 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (rhs
), i
, elt
)
1298 if (TREE_CODE (elt
->value
) != SSA_NAME
1299 || TREE_CODE (TREE_TYPE (elt
->value
)) == VECTOR_TYPE
)
1303 tree this_base
= elt
->value
;
1304 if (this_base
!= CONSTRUCTOR_ELT (rhs
, 0)->value
)
1306 for (j
= 0; j
< nelts
+ 1; j
++)
1308 g
= SSA_NAME_DEF_STMT (this_base
);
1309 if (is_gimple_assign (g
)
1310 && gimple_assign_rhs_code (g
) == PLUS_EXPR
1311 && TREE_CODE (gimple_assign_rhs2 (g
)) == INTEGER_CST
1312 && TREE_CODE (gimple_assign_rhs1 (g
)) == SSA_NAME
1313 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g
)))
1314 this_base
= gimple_assign_rhs1 (g
);
1320 else if (this_base
!= base
)
1325 tree_vector_builder
cst (type
, nelts
, 1);
1326 for (i
= 0; i
< nelts
; i
++)
1328 tree this_base
= CONSTRUCTOR_ELT (rhs
, i
)->value
;
1329 tree elt
= build_zero_cst (TREE_TYPE (base
));
1330 while (this_base
!= base
)
1332 g
= SSA_NAME_DEF_STMT (this_base
);
1333 elt
= fold_binary (PLUS_EXPR
, TREE_TYPE (base
),
1334 elt
, gimple_assign_rhs2 (g
));
1335 if (elt
== NULL_TREE
1336 || TREE_CODE (elt
) != INTEGER_CST
1337 || TREE_OVERFLOW (elt
))
1339 this_base
= gimple_assign_rhs1 (g
);
1341 cst
.quick_push (elt
);
1343 for (i
= 0; i
< nelts
; i
++)
1344 CONSTRUCTOR_ELT (rhs
, i
)->value
= base
;
1345 g
= gimple_build_assign (make_ssa_name (type
), rhs
);
1346 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1347 g
= gimple_build_assign (lhs
, PLUS_EXPR
, gimple_assign_lhs (g
),
1349 gsi_replace (gsi
, g
, false);
1352 /* Return a type for the widest vector mode whose components are of type
1353 TYPE, or NULL_TREE if none is found. */
1356 type_for_widest_vector_mode (tree type
, optab op
)
1358 machine_mode inner_mode
= TYPE_MODE (type
);
1359 machine_mode best_mode
= VOIDmode
, mode
;
1360 poly_int64 best_nunits
= 0;
1362 if (SCALAR_FLOAT_MODE_P (inner_mode
))
1363 mode
= MIN_MODE_VECTOR_FLOAT
;
1364 else if (SCALAR_FRACT_MODE_P (inner_mode
))
1365 mode
= MIN_MODE_VECTOR_FRACT
;
1366 else if (SCALAR_UFRACT_MODE_P (inner_mode
))
1367 mode
= MIN_MODE_VECTOR_UFRACT
;
1368 else if (SCALAR_ACCUM_MODE_P (inner_mode
))
1369 mode
= MIN_MODE_VECTOR_ACCUM
;
1370 else if (SCALAR_UACCUM_MODE_P (inner_mode
))
1371 mode
= MIN_MODE_VECTOR_UACCUM
;
1372 else if (inner_mode
== BImode
)
1373 mode
= MIN_MODE_VECTOR_BOOL
;
1375 mode
= MIN_MODE_VECTOR_INT
;
1377 FOR_EACH_MODE_FROM (mode
, mode
)
1378 if (GET_MODE_INNER (mode
) == inner_mode
1379 && maybe_gt (GET_MODE_NUNITS (mode
), best_nunits
)
1380 && optab_handler (op
, mode
) != CODE_FOR_nothing
)
1381 best_mode
= mode
, best_nunits
= GET_MODE_NUNITS (mode
);
1383 if (best_mode
== VOIDmode
)
1386 return build_vector_type_for_mode (type
, best_mode
);
1390 /* Build a reference to the element of the vector VECT. Function
1391 returns either the element itself, either BIT_FIELD_REF, or an
1392 ARRAY_REF expression.
1394 GSI is required to insert temporary variables while building a
1395 refernece to the element of the vector VECT.
1397 PTMPVEC is a pointer to the temporary variable for caching
1398 purposes. In case when PTMPVEC is NULL new temporary variable
1401 vector_element (gimple_stmt_iterator
*gsi
, tree vect
, tree idx
, tree
*ptmpvec
)
1403 tree vect_type
, vect_elt_type
;
1407 bool need_asgn
= true;
1408 unsigned int elements
;
1410 vect_type
= TREE_TYPE (vect
);
1411 vect_elt_type
= TREE_TYPE (vect_type
);
1412 elements
= nunits_for_known_piecewise_op (vect_type
);
1414 if (TREE_CODE (idx
) == INTEGER_CST
)
1416 unsigned HOST_WIDE_INT index
;
1418 /* Given that we're about to compute a binary modulus,
1419 we don't care about the high bits of the value. */
1420 index
= TREE_INT_CST_LOW (idx
);
1421 if (!tree_fits_uhwi_p (idx
) || index
>= elements
)
1423 index
&= elements
- 1;
1424 idx
= build_int_cst (TREE_TYPE (idx
), index
);
1427 /* When lowering a vector statement sequence do some easy
1428 simplification by looking through intermediate vector results. */
1429 if (TREE_CODE (vect
) == SSA_NAME
)
1431 gimple
*def_stmt
= SSA_NAME_DEF_STMT (vect
);
1432 if (is_gimple_assign (def_stmt
)
1433 && (gimple_assign_rhs_code (def_stmt
) == VECTOR_CST
1434 || gimple_assign_rhs_code (def_stmt
) == CONSTRUCTOR
))
1435 vect
= gimple_assign_rhs1 (def_stmt
);
1438 if (TREE_CODE (vect
) == VECTOR_CST
)
1439 return VECTOR_CST_ELT (vect
, index
);
1440 else if (TREE_CODE (vect
) == CONSTRUCTOR
1441 && (CONSTRUCTOR_NELTS (vect
) == 0
1442 || TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (vect
, 0)->value
))
1445 if (index
< CONSTRUCTOR_NELTS (vect
))
1446 return CONSTRUCTOR_ELT (vect
, index
)->value
;
1447 return build_zero_cst (vect_elt_type
);
1451 tree size
= vector_element_bits_tree (vect_type
);
1452 tree pos
= fold_build2 (MULT_EXPR
, bitsizetype
, bitsize_int (index
),
1454 return fold_build3 (BIT_FIELD_REF
, vect_elt_type
, vect
, size
, pos
);
1459 tmpvec
= create_tmp_var (vect_type
, "vectmp");
1461 tmpvec
= *ptmpvec
= create_tmp_var (vect_type
, "vectmp");
1470 TREE_ADDRESSABLE (tmpvec
) = 1;
1471 asgn
= gimple_build_assign (tmpvec
, vect
);
1472 gsi_insert_before (gsi
, asgn
, GSI_SAME_STMT
);
1475 arraytype
= build_array_type_nelts (vect_elt_type
, elements
);
1476 return build4 (ARRAY_REF
, vect_elt_type
,
1477 build1 (VIEW_CONVERT_EXPR
, arraytype
, tmpvec
),
1478 idx
, NULL_TREE
, NULL_TREE
);
1481 /* Check if VEC_PERM_EXPR within the given setting is supported
1482 by hardware, or lower it piecewise.
1484 When VEC_PERM_EXPR has the same first and second operands:
1485 VEC_PERM_EXPR <v0, v0, mask> the lowered version would be
1486 {v0[mask[0]], v0[mask[1]], ...}
1487 MASK and V0 must have the same number of elements.
1489 Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to
1490 {mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...}
1491 V0 and V1 must have the same type. MASK, V0, V1 must have the
1492 same number of arguments. */
1495 lower_vec_perm (gimple_stmt_iterator
*gsi
)
1497 gassign
*stmt
= as_a
<gassign
*> (gsi_stmt (*gsi
));
1498 tree mask
= gimple_assign_rhs3 (stmt
);
1499 tree vec0
= gimple_assign_rhs1 (stmt
);
1500 tree vec1
= gimple_assign_rhs2 (stmt
);
1501 tree vect_type
= TREE_TYPE (vec0
);
1502 tree mask_type
= TREE_TYPE (mask
);
1503 tree vect_elt_type
= TREE_TYPE (vect_type
);
1504 tree mask_elt_type
= TREE_TYPE (mask_type
);
1505 unsigned HOST_WIDE_INT elements
;
1506 vec
<constructor_elt
, va_gc
> *v
;
1507 tree constr
, t
, si
, i_val
;
1508 tree vec0tmp
= NULL_TREE
, vec1tmp
= NULL_TREE
, masktmp
= NULL_TREE
;
1509 bool two_operand_p
= !operand_equal_p (vec0
, vec1
, 0);
1510 location_t loc
= gimple_location (gsi_stmt (*gsi
));
1513 if (!TYPE_VECTOR_SUBPARTS (vect_type
).is_constant (&elements
))
1516 if (TREE_CODE (mask
) == SSA_NAME
)
1518 gimple
*def_stmt
= SSA_NAME_DEF_STMT (mask
);
1519 if (is_gimple_assign (def_stmt
)
1520 && gimple_assign_rhs_code (def_stmt
) == VECTOR_CST
)
1521 mask
= gimple_assign_rhs1 (def_stmt
);
1524 vec_perm_builder sel_int
;
1526 if (TREE_CODE (mask
) == VECTOR_CST
1527 && tree_to_vec_perm_builder (&sel_int
, mask
))
1529 vec_perm_indices
indices (sel_int
, 2, elements
);
1530 machine_mode vmode
= TYPE_MODE (vect_type
);
1531 tree lhs_type
= TREE_TYPE (gimple_assign_lhs (stmt
));
1532 machine_mode lhs_mode
= TYPE_MODE (lhs_type
);
1533 if (can_vec_perm_const_p (lhs_mode
, vmode
, indices
))
1535 gimple_assign_set_rhs3 (stmt
, mask
);
1539 /* Also detect vec_shr pattern - VEC_PERM_EXPR with zero
1540 vector as VEC1 and a right element shift MASK. */
1541 if (optab_handler (vec_shr_optab
, TYPE_MODE (vect_type
))
1543 && TREE_CODE (vec1
) == VECTOR_CST
1544 && initializer_zerop (vec1
)
1545 && maybe_ne (indices
[0], 0)
1546 && known_lt (poly_uint64 (indices
[0]), elements
))
1548 bool ok_p
= indices
.series_p (0, 1, indices
[0], 1);
1551 for (i
= 1; i
< elements
; ++i
)
1553 poly_uint64 actual
= indices
[i
];
1554 poly_uint64 expected
= i
+ indices
[0];
1555 /* Indices into the second vector are all equivalent. */
1556 if (maybe_lt (actual
, elements
)
1557 ? maybe_ne (actual
, expected
)
1558 : maybe_lt (expected
, elements
))
1561 ok_p
= i
== elements
;
1565 gimple_assign_set_rhs3 (stmt
, mask
);
1570 /* And similarly vec_shl pattern. */
1571 if (optab_handler (vec_shl_optab
, TYPE_MODE (vect_type
))
1573 && TREE_CODE (vec0
) == VECTOR_CST
1574 && initializer_zerop (vec0
))
1576 unsigned int first
= 0;
1577 for (i
= 0; i
< elements
; ++i
)
1578 if (known_eq (poly_uint64 (indices
[i
]), elements
))
1580 if (i
== 0 || first
)
1585 ? maybe_ne (poly_uint64 (indices
[i
]),
1586 elements
+ i
- first
)
1587 : maybe_ge (poly_uint64 (indices
[i
]), elements
))
1589 if (first
&& i
== elements
)
1591 gimple_assign_set_rhs3 (stmt
, mask
);
1597 else if (can_vec_perm_var_p (TYPE_MODE (vect_type
)))
1600 if (!warning_suppressed_p (stmt
, OPT_Wvector_operation_performance
))
1601 warning_at (loc
, OPT_Wvector_operation_performance
,
1602 "vector shuffling operation will be expanded piecewise");
1604 vec_alloc (v
, elements
);
1605 bool constant_p
= true;
1606 for (i
= 0; i
< elements
; i
++)
1609 i_val
= vector_element (gsi
, mask
, si
, &masktmp
);
1611 if (TREE_CODE (i_val
) == INTEGER_CST
)
1613 unsigned HOST_WIDE_INT index
;
1615 index
= TREE_INT_CST_LOW (i_val
);
1616 if (!tree_fits_uhwi_p (i_val
) || index
>= elements
)
1617 i_val
= build_int_cst (mask_elt_type
, index
& (elements
- 1));
1619 if (two_operand_p
&& (index
& elements
) != 0)
1620 t
= vector_element (gsi
, vec1
, i_val
, &vec1tmp
);
1622 t
= vector_element (gsi
, vec0
, i_val
, &vec0tmp
);
1624 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
,
1625 true, GSI_SAME_STMT
);
1629 tree cond
= NULL_TREE
, v0_val
;
1633 cond
= fold_build2 (BIT_AND_EXPR
, mask_elt_type
, i_val
,
1634 build_int_cst (mask_elt_type
, elements
));
1635 cond
= force_gimple_operand_gsi (gsi
, cond
, true, NULL_TREE
,
1636 true, GSI_SAME_STMT
);
1639 i_val
= fold_build2 (BIT_AND_EXPR
, mask_elt_type
, i_val
,
1640 build_int_cst (mask_elt_type
, elements
- 1));
1641 i_val
= force_gimple_operand_gsi (gsi
, i_val
, true, NULL_TREE
,
1642 true, GSI_SAME_STMT
);
1644 v0_val
= vector_element (gsi
, vec0
, i_val
, &vec0tmp
);
1645 v0_val
= force_gimple_operand_gsi (gsi
, v0_val
, true, NULL_TREE
,
1646 true, GSI_SAME_STMT
);
1652 v1_val
= vector_element (gsi
, vec1
, i_val
, &vec1tmp
);
1653 v1_val
= force_gimple_operand_gsi (gsi
, v1_val
, true, NULL_TREE
,
1654 true, GSI_SAME_STMT
);
1656 cond
= fold_build2 (EQ_EXPR
, boolean_type_node
,
1657 cond
, build_zero_cst (mask_elt_type
));
1658 cond
= fold_build3 (COND_EXPR
, vect_elt_type
,
1659 cond
, v0_val
, v1_val
);
1660 t
= force_gimple_operand_gsi (gsi
, cond
, true, NULL_TREE
,
1661 true, GSI_SAME_STMT
);
1667 if (!CONSTANT_CLASS_P (t
))
1669 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
1673 constr
= build_vector_from_ctor (vect_type
, v
);
1675 constr
= build_constructor (vect_type
, v
);
1676 gimple_assign_set_rhs_from_tree (gsi
, constr
);
1677 update_stmt (gsi_stmt (*gsi
));
1680 /* If OP is a uniform vector return the element it is a splat from. */
1683 ssa_uniform_vector_p (tree op
)
1685 if (TREE_CODE (op
) == VECTOR_CST
1686 || TREE_CODE (op
) == VEC_DUPLICATE_EXPR
1687 || TREE_CODE (op
) == CONSTRUCTOR
)
1688 return uniform_vector_p (op
);
1689 if (TREE_CODE (op
) == SSA_NAME
)
1691 gimple
*def_stmt
= SSA_NAME_DEF_STMT (op
);
1692 if (gimple_assign_single_p (def_stmt
))
1693 return uniform_vector_p (gimple_assign_rhs1 (def_stmt
));
1698 /* Return type in which CODE operation with optab OP can be
1702 get_compute_type (enum tree_code code
, optab op
, tree type
)
1704 /* For very wide vectors, try using a smaller vector mode. */
1705 tree compute_type
= type
;
1707 && (!VECTOR_MODE_P (TYPE_MODE (type
))
1708 || optab_handler (op
, TYPE_MODE (type
)) == CODE_FOR_nothing
))
1710 tree vector_compute_type
1711 = type_for_widest_vector_mode (TREE_TYPE (type
), op
);
1712 if (vector_compute_type
!= NULL_TREE
1713 && subparts_gt (compute_type
, vector_compute_type
)
1714 && maybe_ne (TYPE_VECTOR_SUBPARTS (vector_compute_type
), 1U)
1715 && (optab_handler (op
, TYPE_MODE (vector_compute_type
))
1716 != CODE_FOR_nothing
))
1717 compute_type
= vector_compute_type
;
1720 /* If we are breaking a BLKmode vector into smaller pieces,
1721 type_for_widest_vector_mode has already looked into the optab,
1722 so skip these checks. */
1723 if (compute_type
== type
)
1725 machine_mode compute_mode
= TYPE_MODE (compute_type
);
1726 if (VECTOR_MODE_P (compute_mode
))
1728 if (op
&& optab_handler (op
, compute_mode
) != CODE_FOR_nothing
)
1729 return compute_type
;
1730 if (code
== MULT_HIGHPART_EXPR
1731 && can_mult_highpart_p (compute_mode
,
1732 TYPE_UNSIGNED (compute_type
)))
1733 return compute_type
;
1735 /* There is no operation in hardware, so fall back to scalars. */
1736 compute_type
= TREE_TYPE (type
);
1739 return compute_type
;
1743 do_cond (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
, tree b
,
1744 tree bitpos
, tree bitsize
, enum tree_code code
,
1745 tree type ATTRIBUTE_UNUSED
)
1747 if (TREE_CODE (TREE_TYPE (a
)) == VECTOR_TYPE
)
1748 a
= tree_vec_extract (gsi
, inner_type
, a
, bitsize
, bitpos
);
1749 if (TREE_CODE (TREE_TYPE (b
)) == VECTOR_TYPE
)
1750 b
= tree_vec_extract (gsi
, inner_type
, b
, bitsize
, bitpos
);
1751 tree cond
= gimple_assign_rhs1 (gsi_stmt (*gsi
));
1752 return gimplify_build3 (gsi
, code
, inner_type
, unshare_expr (cond
), a
, b
);
1755 /* Expand a vector COND_EXPR to scalars, piecewise. */
1757 expand_vector_scalar_condition (gimple_stmt_iterator
*gsi
)
1759 gassign
*stmt
= as_a
<gassign
*> (gsi_stmt (*gsi
));
1760 tree lhs
= gimple_assign_lhs (stmt
);
1761 tree type
= TREE_TYPE (lhs
);
1762 tree compute_type
= get_compute_type (COND_EXPR
, mov_optab
, type
);
1763 machine_mode compute_mode
= TYPE_MODE (compute_type
);
1764 gcc_assert (compute_mode
!= BLKmode
);
1765 tree rhs2
= gimple_assign_rhs2 (stmt
);
1766 tree rhs3
= gimple_assign_rhs3 (stmt
);
1769 /* If the compute mode is not a vector mode (hence we are not decomposing
1770 a BLKmode vector to smaller, hardware-supported vectors), we may want
1771 to expand the operations in parallel. */
1772 if (!VECTOR_MODE_P (compute_mode
))
1773 new_rhs
= expand_vector_parallel (gsi
, do_cond
, type
, rhs2
, rhs3
,
1776 new_rhs
= expand_vector_piecewise (gsi
, do_cond
, type
, compute_type
,
1777 rhs2
, rhs3
, COND_EXPR
, false);
1778 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (new_rhs
)))
1779 new_rhs
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
1782 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
1783 way to do it is change expand_vector_operation and its callees to
1784 return a tree_code, RHS1 and RHS2 instead of a tree. */
1785 gimple_assign_set_rhs_from_tree (gsi
, new_rhs
);
1786 update_stmt (gsi_stmt (*gsi
));
1789 /* Callback for expand_vector_piecewise to do VEC_CONVERT ifn call
1790 lowering. If INNER_TYPE is not a vector type, this is a scalar
1794 do_vec_conversion (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
,
1795 tree decl
, tree bitpos
, tree bitsize
,
1796 enum tree_code code
, tree type
)
1798 a
= tree_vec_extract (gsi
, inner_type
, a
, bitsize
, bitpos
);
1799 if (!VECTOR_TYPE_P (inner_type
))
1800 return gimplify_build1 (gsi
, code
, TREE_TYPE (type
), a
);
1801 if (code
== CALL_EXPR
)
1803 gimple
*g
= gimple_build_call (decl
, 1, a
);
1804 tree lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (decl
)));
1805 gimple_call_set_lhs (g
, lhs
);
1806 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1811 tree outer_type
= build_vector_type (TREE_TYPE (type
),
1812 TYPE_VECTOR_SUBPARTS (inner_type
));
1813 return gimplify_build1 (gsi
, code
, outer_type
, a
);
1817 /* Similarly, but for narrowing conversion. */
1820 do_vec_narrow_conversion (gimple_stmt_iterator
*gsi
, tree inner_type
, tree a
,
1821 tree
, tree bitpos
, tree
, enum tree_code code
,
1824 tree itype
= build_vector_type (TREE_TYPE (inner_type
),
1825 exact_div (TYPE_VECTOR_SUBPARTS (inner_type
),
1827 tree b
= tree_vec_extract (gsi
, itype
, a
, TYPE_SIZE (itype
), bitpos
);
1828 tree c
= tree_vec_extract (gsi
, itype
, a
, TYPE_SIZE (itype
),
1829 int_const_binop (PLUS_EXPR
, bitpos
,
1830 TYPE_SIZE (itype
)));
1831 tree outer_type
= build_vector_type (TREE_TYPE (type
),
1832 TYPE_VECTOR_SUBPARTS (inner_type
));
1833 return gimplify_build2 (gsi
, code
, outer_type
, b
, c
);
1836 /* Expand VEC_CONVERT ifn call. */
1839 expand_vector_conversion (gimple_stmt_iterator
*gsi
)
1841 gimple
*stmt
= gsi_stmt (*gsi
);
1843 tree lhs
= gimple_call_lhs (stmt
);
1844 if (lhs
== NULL_TREE
)
1846 g
= gimple_build_nop ();
1847 gsi_replace (gsi
, g
, false);
1850 tree arg
= gimple_call_arg (stmt
, 0);
1851 tree ret_type
= TREE_TYPE (lhs
);
1852 tree arg_type
= TREE_TYPE (arg
);
1853 tree new_rhs
, compute_type
= TREE_TYPE (arg_type
);
1854 enum tree_code code
= NOP_EXPR
;
1855 enum tree_code code1
= ERROR_MARK
;
1856 enum { NARROW
, NONE
, WIDEN
} modifier
= NONE
;
1857 optab optab1
= unknown_optab
;
1859 gcc_checking_assert (VECTOR_TYPE_P (ret_type
) && VECTOR_TYPE_P (arg_type
));
1860 if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type
))
1861 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type
)))
1862 code
= FIX_TRUNC_EXPR
;
1863 else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type
))
1864 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type
)))
1866 unsigned int ret_elt_bits
= vector_element_bits (ret_type
);
1867 unsigned int arg_elt_bits
= vector_element_bits (arg_type
);
1868 if (ret_elt_bits
< arg_elt_bits
)
1870 else if (ret_elt_bits
> arg_elt_bits
)
1873 if (modifier
== NONE
&& (code
== FIX_TRUNC_EXPR
|| code
== FLOAT_EXPR
))
1875 if (supportable_convert_operation (code
, ret_type
, arg_type
, &code1
))
1877 g
= gimple_build_assign (lhs
, code1
, arg
);
1878 gsi_replace (gsi
, g
, false);
1881 /* Can't use get_compute_type here, as supportable_convert_operation
1882 doesn't necessarily use an optab and needs two arguments. */
1883 tree vec_compute_type
1884 = type_for_widest_vector_mode (TREE_TYPE (arg_type
), mov_optab
);
1885 if (vec_compute_type
1886 && VECTOR_MODE_P (TYPE_MODE (vec_compute_type
))
1887 && subparts_gt (arg_type
, vec_compute_type
))
1889 unsigned HOST_WIDE_INT nelts
1890 = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vec_compute_type
));
1893 tree ret1_type
= build_vector_type (TREE_TYPE (ret_type
), nelts
);
1894 tree arg1_type
= build_vector_type (TREE_TYPE (arg_type
), nelts
);
1895 if (supportable_convert_operation (code
, ret1_type
, arg1_type
,
1898 new_rhs
= expand_vector_piecewise (gsi
, do_vec_conversion
,
1899 ret_type
, arg1_type
, arg
,
1900 NULL_TREE
, code1
, false);
1901 g
= gimple_build_assign (lhs
, new_rhs
);
1902 gsi_replace (gsi
, g
, false);
1909 else if (modifier
== NARROW
)
1914 code1
= VEC_PACK_TRUNC_EXPR
;
1915 optab1
= optab_for_tree_code (code1
, arg_type
, optab_default
);
1917 case FIX_TRUNC_EXPR
:
1918 code1
= VEC_PACK_FIX_TRUNC_EXPR
;
1919 /* The signedness is determined from output operand. */
1920 optab1
= optab_for_tree_code (code1
, ret_type
, optab_default
);
1923 code1
= VEC_PACK_FLOAT_EXPR
;
1924 optab1
= optab_for_tree_code (code1
, arg_type
, optab_default
);
1931 compute_type
= get_compute_type (code1
, optab1
, arg_type
);
1932 enum insn_code icode1
;
1933 if (VECTOR_TYPE_P (compute_type
)
1934 && ((icode1
= optab_handler (optab1
, TYPE_MODE (compute_type
)))
1935 != CODE_FOR_nothing
)
1936 && VECTOR_MODE_P (insn_data
[icode1
].operand
[0].mode
))
1939 = build_vector_type (TREE_TYPE (ret_type
),
1940 TYPE_VECTOR_SUBPARTS (compute_type
) * 2);
1941 if (insn_data
[icode1
].operand
[0].mode
== TYPE_MODE (cretd_type
))
1943 if (compute_type
== arg_type
)
1945 new_rhs
= gimplify_build2 (gsi
, code1
, cretd_type
,
1946 arg
, build_zero_cst (arg_type
));
1947 new_rhs
= tree_vec_extract (gsi
, ret_type
, new_rhs
,
1948 TYPE_SIZE (ret_type
),
1950 g
= gimple_build_assign (lhs
, new_rhs
);
1951 gsi_replace (gsi
, g
, false);
1955 = build_vector_type (TREE_TYPE (compute_type
),
1956 TYPE_VECTOR_SUBPARTS (compute_type
) * 2);
1957 if (TYPE_MAIN_VARIANT (dcompute_type
)
1958 == TYPE_MAIN_VARIANT (arg_type
))
1959 new_rhs
= do_vec_narrow_conversion (gsi
, dcompute_type
, arg
,
1960 NULL_TREE
, bitsize_int (0),
1964 new_rhs
= expand_vector_piecewise (gsi
,
1965 do_vec_narrow_conversion
,
1966 arg_type
, dcompute_type
,
1967 arg
, NULL_TREE
, code1
,
1969 g
= gimple_build_assign (lhs
, new_rhs
);
1970 gsi_replace (gsi
, g
, false);
1975 else if (modifier
== WIDEN
)
1977 enum tree_code code2
= ERROR_MARK
;
1978 optab optab2
= unknown_optab
;
1982 code1
= VEC_UNPACK_LO_EXPR
;
1983 code2
= VEC_UNPACK_HI_EXPR
;
1985 case FIX_TRUNC_EXPR
:
1986 code1
= VEC_UNPACK_FIX_TRUNC_LO_EXPR
;
1987 code2
= VEC_UNPACK_FIX_TRUNC_HI_EXPR
;
1990 code1
= VEC_UNPACK_FLOAT_LO_EXPR
;
1991 code2
= VEC_UNPACK_FLOAT_HI_EXPR
;
1996 if (BYTES_BIG_ENDIAN
)
1997 std::swap (code1
, code2
);
1999 if (code
== FIX_TRUNC_EXPR
)
2001 /* The signedness is determined from output operand. */
2002 optab1
= optab_for_tree_code (code1
, ret_type
, optab_default
);
2003 optab2
= optab_for_tree_code (code2
, ret_type
, optab_default
);
2007 optab1
= optab_for_tree_code (code1
, arg_type
, optab_default
);
2008 optab2
= optab_for_tree_code (code2
, arg_type
, optab_default
);
2011 if (optab1
&& optab2
)
2012 compute_type
= get_compute_type (code1
, optab1
, arg_type
);
2014 enum insn_code icode1
, icode2
;
2015 if (VECTOR_TYPE_P (compute_type
)
2016 && ((icode1
= optab_handler (optab1
, TYPE_MODE (compute_type
)))
2017 != CODE_FOR_nothing
)
2018 && ((icode2
= optab_handler (optab2
, TYPE_MODE (compute_type
)))
2019 != CODE_FOR_nothing
)
2020 && VECTOR_MODE_P (insn_data
[icode1
].operand
[0].mode
)
2021 && (insn_data
[icode1
].operand
[0].mode
2022 == insn_data
[icode2
].operand
[0].mode
))
2025 = exact_div (TYPE_VECTOR_SUBPARTS (compute_type
), 2);
2026 tree cretd_type
= build_vector_type (TREE_TYPE (ret_type
), nunits
);
2027 if (insn_data
[icode1
].operand
[0].mode
== TYPE_MODE (cretd_type
))
2029 vec
<constructor_elt
, va_gc
> *v
;
2030 tree part_width
= TYPE_SIZE (compute_type
);
2031 tree index
= bitsize_int (0);
2032 int nunits
= nunits_for_known_piecewise_op (arg_type
);
2033 int delta
= tree_to_uhwi (part_width
) / arg_elt_bits
;
2035 location_t loc
= gimple_location (gsi_stmt (*gsi
));
2037 if (compute_type
!= arg_type
)
2039 if (!warning_suppressed_p (gsi_stmt (*gsi
),
2040 OPT_Wvector_operation_performance
))
2041 warning_at (loc
, OPT_Wvector_operation_performance
,
2042 "vector operation will be expanded piecewise");
2050 vec_alloc (v
, (nunits
+ delta
- 1) / delta
* 2);
2051 bool constant_p
= true;
2052 for (i
= 0; i
< nunits
;
2053 i
+= delta
, index
= int_const_binop (PLUS_EXPR
, index
,
2057 if (compute_type
!= arg_type
)
2058 a
= tree_vec_extract (gsi
, compute_type
, a
, part_width
,
2060 tree result
= gimplify_build1 (gsi
, code1
, cretd_type
, a
);
2061 constructor_elt ce
= { NULL_TREE
, result
};
2062 if (!CONSTANT_CLASS_P (ce
.value
))
2065 ce
.value
= gimplify_build1 (gsi
, code2
, cretd_type
, a
);
2066 if (!CONSTANT_CLASS_P (ce
.value
))
2072 new_rhs
= build_vector_from_ctor (ret_type
, v
);
2074 new_rhs
= build_constructor (ret_type
, v
);
2075 g
= gimple_build_assign (lhs
, new_rhs
);
2076 gsi_replace (gsi
, g
, false);
2082 new_rhs
= expand_vector_piecewise (gsi
, do_vec_conversion
, arg_type
,
2083 TREE_TYPE (arg_type
), arg
,
2084 NULL_TREE
, code
, false, ret_type
);
2085 g
= gimple_build_assign (lhs
, new_rhs
);
2086 gsi_replace (gsi
, g
, false);
2089 /* Process one statement. If we identify a vector operation, expand it. */
2092 expand_vector_operations_1 (gimple_stmt_iterator
*gsi
,
2093 bitmap dce_ssa_names
)
2095 tree lhs
, rhs1
, rhs2
= NULL
, type
, compute_type
= NULL_TREE
;
2096 enum tree_code code
;
2097 optab op
= unknown_optab
;
2098 enum gimple_rhs_class rhs_class
;
2101 /* Only consider code == GIMPLE_ASSIGN. */
2102 gassign
*stmt
= dyn_cast
<gassign
*> (gsi_stmt (*gsi
));
2105 if (gimple_call_internal_p (gsi_stmt (*gsi
), IFN_VEC_CONVERT
))
2106 expand_vector_conversion (gsi
);
2110 code
= gimple_assign_rhs_code (stmt
);
2111 rhs_class
= get_gimple_rhs_class (code
);
2112 lhs
= gimple_assign_lhs (stmt
);
2114 if (code
== VEC_PERM_EXPR
)
2116 lower_vec_perm (gsi
);
2120 if (code
== VEC_COND_EXPR
)
2122 expand_vector_condition (gsi
, dce_ssa_names
);
2126 if (code
== COND_EXPR
2127 && TREE_CODE (TREE_TYPE (gimple_assign_lhs (stmt
))) == VECTOR_TYPE
2128 && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt
))) == BLKmode
)
2130 expand_vector_scalar_condition (gsi
);
2134 if (code
== CONSTRUCTOR
2135 && TREE_CODE (lhs
) == SSA_NAME
2136 && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (lhs
)))
2137 && !gimple_clobber_p (stmt
)
2140 optimize_vector_constructor (gsi
);
2144 if (rhs_class
!= GIMPLE_UNARY_RHS
&& rhs_class
!= GIMPLE_BINARY_RHS
)
2147 rhs1
= gimple_assign_rhs1 (stmt
);
2148 if (rhs_class
== GIMPLE_BINARY_RHS
)
2149 rhs2
= gimple_assign_rhs2 (stmt
);
2151 type
= TREE_TYPE (lhs
);
2152 if (!VECTOR_TYPE_P (type
)
2153 || !VECTOR_TYPE_P (TREE_TYPE (rhs1
)))
2156 /* A scalar operation pretending to be a vector one. */
2157 if (VECTOR_BOOLEAN_TYPE_P (type
)
2158 && !VECTOR_MODE_P (TYPE_MODE (type
))
2159 && TYPE_MODE (type
) != BLKmode
2160 && (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt
)) != tcc_comparison
2161 || (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1
))
2162 && !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs1
)))
2163 && TYPE_MODE (TREE_TYPE (rhs1
)) != BLKmode
)))
2166 /* If the vector operation is operating on all same vector elements
2167 implement it with a scalar operation and a splat if the target
2168 supports the scalar operation. */
2169 tree srhs1
, srhs2
= NULL_TREE
;
2170 if ((srhs1
= ssa_uniform_vector_p (rhs1
)) != NULL_TREE
2171 && (rhs2
== NULL_TREE
2172 || (! VECTOR_TYPE_P (TREE_TYPE (rhs2
))
2174 || (srhs2
= ssa_uniform_vector_p (rhs2
)) != NULL_TREE
)
2175 /* As we query direct optabs restrict to non-convert operations. */
2176 && TYPE_MODE (TREE_TYPE (type
)) == TYPE_MODE (TREE_TYPE (srhs1
)))
2178 op
= optab_for_tree_code (code
, TREE_TYPE (type
), optab_scalar
);
2179 if (op
>= FIRST_NORM_OPTAB
&& op
<= LAST_NORM_OPTAB
2180 && optab_handler (op
, TYPE_MODE (TREE_TYPE (type
))) != CODE_FOR_nothing
)
2182 tree stype
= TREE_TYPE (TREE_TYPE (lhs
));
2183 tree slhs
= (rhs2
!= NULL_TREE
)
2184 ? gimplify_build2 (gsi
, code
, stype
, srhs1
, srhs2
)
2185 : gimplify_build1 (gsi
, code
, stype
, srhs1
);
2186 gimple_assign_set_rhs_from_tree (gsi
,
2187 build_vector_from_val (type
, slhs
));
2193 if (CONVERT_EXPR_CODE_P (code
)
2194 || code
== FLOAT_EXPR
2195 || code
== FIX_TRUNC_EXPR
2196 || code
== VIEW_CONVERT_EXPR
)
2199 /* The signedness is determined from input argument. */
2200 if (code
== VEC_UNPACK_FLOAT_HI_EXPR
2201 || code
== VEC_UNPACK_FLOAT_LO_EXPR
2202 || code
== VEC_PACK_FLOAT_EXPR
)
2204 /* We do not know how to scalarize those. */
2208 /* For widening/narrowing vector operations, the relevant type is of the
2209 arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is
2210 calculated in the same way above. */
2211 if (code
== WIDEN_SUM_EXPR
2212 || code
== VEC_WIDEN_PLUS_HI_EXPR
2213 || code
== VEC_WIDEN_PLUS_LO_EXPR
2214 || code
== VEC_WIDEN_MINUS_HI_EXPR
2215 || code
== VEC_WIDEN_MINUS_LO_EXPR
2216 || code
== VEC_WIDEN_MULT_HI_EXPR
2217 || code
== VEC_WIDEN_MULT_LO_EXPR
2218 || code
== VEC_WIDEN_MULT_EVEN_EXPR
2219 || code
== VEC_WIDEN_MULT_ODD_EXPR
2220 || code
== VEC_UNPACK_HI_EXPR
2221 || code
== VEC_UNPACK_LO_EXPR
2222 || code
== VEC_UNPACK_FIX_TRUNC_HI_EXPR
2223 || code
== VEC_UNPACK_FIX_TRUNC_LO_EXPR
2224 || code
== VEC_PACK_TRUNC_EXPR
2225 || code
== VEC_PACK_SAT_EXPR
2226 || code
== VEC_PACK_FIX_TRUNC_EXPR
2227 || code
== VEC_WIDEN_LSHIFT_HI_EXPR
2228 || code
== VEC_WIDEN_LSHIFT_LO_EXPR
)
2230 /* We do not know how to scalarize those. */
2234 /* Choose between vector shift/rotate by vector and vector shift/rotate by
2236 if (code
== LSHIFT_EXPR
2237 || code
== RSHIFT_EXPR
2238 || code
== LROTATE_EXPR
2239 || code
== RROTATE_EXPR
)
2243 /* Check whether we have vector <op> {x,x,x,x} where x
2244 could be a scalar variable or a constant. Transform
2245 vector <op> {x,x,x,x} ==> vector <op> scalar. */
2246 if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2
)))
2250 if ((first
= ssa_uniform_vector_p (rhs2
)) != NULL_TREE
)
2252 gimple_assign_set_rhs2 (stmt
, first
);
2258 opv
= optab_for_tree_code (code
, type
, optab_vector
);
2259 if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2
)))
2263 op
= optab_for_tree_code (code
, type
, optab_scalar
);
2265 compute_type
= get_compute_type (code
, op
, type
);
2266 if (compute_type
== type
)
2268 /* The rtl expander will expand vector/scalar as vector/vector
2269 if necessary. Pick one with wider vector type. */
2270 tree compute_vtype
= get_compute_type (code
, opv
, type
);
2271 if (subparts_gt (compute_vtype
, compute_type
))
2273 compute_type
= compute_vtype
;
2278 if (code
== LROTATE_EXPR
|| code
== RROTATE_EXPR
)
2280 if (compute_type
== NULL_TREE
)
2281 compute_type
= get_compute_type (code
, op
, type
);
2282 if (compute_type
== type
)
2284 /* Before splitting vector rotates into scalar rotates,
2285 see if we can't use vector shifts and BIT_IOR_EXPR
2286 instead. For vector by vector rotates we'd also
2287 need to check BIT_AND_EXPR and NEGATE_EXPR, punt there
2288 for now, fold doesn't seem to create such rotates anyway. */
2289 if (compute_type
== TREE_TYPE (type
)
2290 && !VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2
)))
2292 optab oplv
= vashl_optab
, opl
= ashl_optab
;
2293 optab oprv
= vlshr_optab
, opr
= lshr_optab
, opo
= ior_optab
;
2294 tree compute_lvtype
= get_compute_type (LSHIFT_EXPR
, oplv
, type
);
2295 tree compute_rvtype
= get_compute_type (RSHIFT_EXPR
, oprv
, type
);
2296 tree compute_otype
= get_compute_type (BIT_IOR_EXPR
, opo
, type
);
2297 tree compute_ltype
= get_compute_type (LSHIFT_EXPR
, opl
, type
);
2298 tree compute_rtype
= get_compute_type (RSHIFT_EXPR
, opr
, type
);
2299 /* The rtl expander will expand vector/scalar as vector/vector
2300 if necessary. Pick one with wider vector type. */
2301 if (subparts_gt (compute_lvtype
, compute_ltype
))
2303 compute_ltype
= compute_lvtype
;
2306 if (subparts_gt (compute_rvtype
, compute_rtype
))
2308 compute_rtype
= compute_rvtype
;
2311 /* Pick the narrowest type from LSHIFT_EXPR, RSHIFT_EXPR and
2313 compute_type
= compute_ltype
;
2314 if (subparts_gt (compute_type
, compute_rtype
))
2315 compute_type
= compute_rtype
;
2316 if (subparts_gt (compute_type
, compute_otype
))
2317 compute_type
= compute_otype
;
2318 /* Verify all 3 operations can be performed in that type. */
2319 if (compute_type
!= TREE_TYPE (type
))
2321 if (optab_handler (opl
, TYPE_MODE (compute_type
))
2323 || optab_handler (opr
, TYPE_MODE (compute_type
))
2325 || optab_handler (opo
, TYPE_MODE (compute_type
))
2326 == CODE_FOR_nothing
)
2327 compute_type
= TREE_TYPE (type
);
2333 op
= optab_for_tree_code (code
, type
, optab_default
);
2335 /* Optabs will try converting a negation into a subtraction, so
2336 look for it as well. TODO: negation of floating-point vectors
2337 might be turned into an exclusive OR toggling the sign bit. */
2338 if (op
== unknown_optab
2339 && code
== NEGATE_EXPR
2340 && INTEGRAL_TYPE_P (TREE_TYPE (type
)))
2341 op
= optab_for_tree_code (MINUS_EXPR
, type
, optab_default
);
2343 if (compute_type
== NULL_TREE
)
2344 compute_type
= get_compute_type (code
, op
, type
);
2345 if (compute_type
== type
)
2348 new_rhs
= expand_vector_operation (gsi
, type
, compute_type
, stmt
, code
,
2351 /* Leave expression untouched for later expansion. */
2352 if (new_rhs
== NULL_TREE
)
2355 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (new_rhs
)))
2356 new_rhs
= gimplify_build1 (gsi
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
2359 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
2360 way to do it is change expand_vector_operation and its callees to
2361 return a tree_code, RHS1 and RHS2 instead of a tree. */
2362 gimple_assign_set_rhs_from_tree (gsi
, new_rhs
);
2363 update_stmt (gsi_stmt (*gsi
));
2366 /* Use this to lower vector operations introduced by the vectorizer,
2367 if it may need the bit-twiddling tricks implemented in this file. */
2370 expand_vector_operations (void)
2372 gimple_stmt_iterator gsi
;
2374 bool cfg_changed
= false;
2376 auto_bitmap dce_ssa_names
;
2378 FOR_EACH_BB_FN (bb
, cfun
)
2380 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2382 expand_vector_operations_1 (&gsi
, dce_ssa_names
);
2383 /* ??? If we do not cleanup EH then we will ICE in
2384 verification. But in reality we have created wrong-code
2385 as we did not properly transition EH info and edges to
2386 the piecewise computations. */
2387 if (maybe_clean_eh_stmt (gsi_stmt (gsi
))
2388 && gimple_purge_dead_eh_edges (bb
))
2393 simple_dce_from_worklist (dce_ssa_names
);
2395 return cfg_changed
? TODO_cleanup_cfg
: 0;
2400 const pass_data pass_data_lower_vector
=
2402 GIMPLE_PASS
, /* type */
2403 "veclower", /* name */
2404 OPTGROUP_VEC
, /* optinfo_flags */
2405 TV_NONE
, /* tv_id */
2406 PROP_cfg
, /* properties_required */
2407 PROP_gimple_lvec
, /* properties_provided */
2408 0, /* properties_destroyed */
2409 0, /* todo_flags_start */
2410 TODO_update_ssa
, /* todo_flags_finish */
2413 class pass_lower_vector
: public gimple_opt_pass
2416 pass_lower_vector (gcc::context
*ctxt
)
2417 : gimple_opt_pass (pass_data_lower_vector
, ctxt
)
2420 /* opt_pass methods: */
2421 bool gate (function
*fun
) final override
2423 return !(fun
->curr_properties
& PROP_gimple_lvec
);
2426 unsigned int execute (function
*) final override
2428 return expand_vector_operations ();
2431 }; // class pass_lower_vector
2436 make_pass_lower_vector (gcc::context
*ctxt
)
2438 return new pass_lower_vector (ctxt
);
2443 const pass_data pass_data_lower_vector_ssa
=
2445 GIMPLE_PASS
, /* type */
2446 "veclower2", /* name */
2447 OPTGROUP_VEC
, /* optinfo_flags */
2448 TV_NONE
, /* tv_id */
2449 PROP_cfg
, /* properties_required */
2450 PROP_gimple_lvec
, /* properties_provided */
2451 0, /* properties_destroyed */
2452 0, /* todo_flags_start */
2454 | TODO_cleanup_cfg
), /* todo_flags_finish */
2457 class pass_lower_vector_ssa
: public gimple_opt_pass
2460 pass_lower_vector_ssa (gcc::context
*ctxt
)
2461 : gimple_opt_pass (pass_data_lower_vector_ssa
, ctxt
)
2464 /* opt_pass methods: */
2465 opt_pass
* clone () final override
2467 return new pass_lower_vector_ssa (m_ctxt
);
2469 unsigned int execute (function
*) final override
2471 return expand_vector_operations ();
2474 }; // class pass_lower_vector_ssa
2479 make_pass_lower_vector_ssa (gcc::context
*ctxt
)
2481 return new pass_lower_vector_ssa (ctxt
);
2484 #include "gt-tree-vect-generic.h"