vect-mult-const-pattern-2.c
769 Bytes
-
[12/n] PR85694: Rework detection of widened operations · 00347934
This patch adds helper functions for detecting widened operations and generalises the existing code to handle more cases. One of the main changes is to recognise multi-stage type conversions, which are possible even in the original IR and can also occur as a result of earlier pattern matching (especially after the main over-widening patch). E.g. for: unsigned int res = 0; for (__INTPTR_TYPE__ i = 0; i < N; ++i) { int av = a[i]; int bv = b[i]; short diff = av - bv; unsigned short abs = diff < 0 ? -diff : diff; res += abs; } we have: _9 = _7 - _8; diff_20 = (short int) _9; _10 = (int) diff_20; _11 = ABS_EXPR <_10>; where the first cast establishes the sign of the promotion done by the second cast. vect_recog_sad_pattern didn't handle this kind of intermediate promotion between the MINUS_EXPR and the ABS_EXPR. Sign extensions and casts from unsigned to signed are both OK there. Unsigned promotions aren't, and need to be rejected, but should have been folded away earlier anyway. Also, the dot_prod and widen_sum patterns both required the promotions to be from one signedness to the same signedness, rather than say signed char to unsigned int. That shouldn't be necessary, since it's only the sign of the input to the promotion that matters. Nothing requires the narrow and wide types in a DOT_PROD_EXPR or WIDEN_SUM_EXPR to have the same sign (and IMO that's a good thing). Fixing these fixed an XFAIL in gcc.dg/vect/vect-widen-mult-sum.c. vect_widened_op_tree is a bit more general than the current patch needs, since it copes with a tree of operations rather than a single statement. This is used by the later average-detection patch. The patch also uses a common routine to handle both the WIDEN_MULT_EXPR and WIDEN_LSHIFT_EXPR patterns. I hope this could be reused for other similar operations in future. Also, the patch means we recognise the index calculations in vect-mult-const-pattern*.c as widening multiplications, whereas the scan test was expecting them to be recognised as mult patterns instead. The patch makes the tests check specifically for the multiplication we care about. 2018-06-30 Richard Sandiford <richard.sandiford@arm.com> gcc/ * tree-vect-patterns.c (append_pattern_def_seq): Take an optional vector type. If given, install it in the new statement's STMT_VINFO_VECTYPE. (vect_element_precision): New function. (vect_unpromoted_value): New struct. (vect_unpromoted_value::vect_unpromoted_value): New function. (vect_unpromoted_value::set_op): Likewise. (vect_look_through_possible_promotion): Likewise. (vect_joust_widened_integer, vect_joust_widened_type): Likewise. (vect_widened_op_tree, vect_convert_input): Likewise. (vect_convert_inputs, vect_convert_output): Likewise. (vect_recog_dot_prod_pattern): Use vect_look_through_possible_promotion to handle the optional cast of the multiplication result and vect_widened_op_tree to detect the widened multiplication itself. Do not require the input and output of promotion casts to have the same sign, but base the signedness of the operation on the input rather than the result. If the pattern includes two promotions, check that those promotions have the same sign. Do not restrict the MULT_EXPR handling to a double-width result; handle quadruple-width results and wider. Use vect_convert_inputs to convert the inputs to the common type. (vect_recog_sad_pattern): Use vect_look_through_possible_promotion to handle the optional cast of the ABS result. Also allow a sign change or a sign extension between the ABS and MINUS. Use vect_widened_op_tree to detect the widened subtraction and use vect_convert_inputs to convert the inputs to the common type. (vect_handle_widen_op_by_const): Delete. (vect_recog_widen_op_pattern): New function. (vect_recog_widen_mult_pattern): Use it. (vect_recog_widen_shift_pattern): Likewise. (vect_recog_widen_sum_pattern): Use vect_look_through_possible_promotion to handle the promoted PLUS_EXPR operand. gcc/testsuite/ * gcc.dg/vect/vect-widen-mult-sum.c: Remove xfail. * gcc.dg/vect/no-scevccp-outer-6.c: Don't match widened multiplications by 4 in the computation of a[i]. * gcc.dg/vect/vect-mult-const-pattern-1.c: Test specifically for the main multiplication constant. * gcc.dg/vect/vect-mult-const-pattern-2.c: Likewise. * gcc.dg/vect/vect-widen-mult-const-s16.c: Likewise. * gcc.dg/vect/vect-widen-mult-const-u16.c: Likewise. Expect the pattern to cast the result to int. * gcc.dg/vect/vect-reduc-dot-1.c: New test. * gcc.dg/vect/vect-reduc-dot-2.c: Likewise. * gcc.dg/vect/vect-reduc-dot-3.c: Likewise. * gcc.dg/vect/vect-reduc-dot-4.c: Likewise. * gcc.dg/vect/vect-reduc-dot-5.c: Likewise. * gcc.dg/vect/vect-reduc-dot-6.c: Likewise. * gcc.dg/vect/vect-reduc-dot-7.c: Likewise. * gcc.dg/vect/vect-reduc-dot-8.c: Likewise. * gcc.dg/vect/vect-reduc-sad-1.c: Likewise. * gcc.dg/vect/vect-reduc-sad-2.c: Likewise. * gcc.dg/vect/vect-reduc-sad-3.c: Likewise. * gcc.dg/vect/vect-reduc-sad-4.c: Likewise. * gcc.dg/vect/vect-reduc-sad-5.c: Likewise. * gcc.dg/vect/vect-reduc-sad-6.c: Likewise. * gcc.dg/vect/vect-reduc-sad-7.c: Likewise. * gcc.dg/vect/vect-reduc-sad-8.c: Likewise. * gcc.dg/vect/vect-widen-mult-1.c: Likewise. * gcc.dg/vect/vect-widen-mult-2.c: Likewise. * gcc.dg/vect/vect-widen-mult-3.c: Likewise. * gcc.dg/vect/vect-widen-mult-4.c: Likewise. From-SVN: r262276
Richard Sandiford committed