Commit 00347934 by Richard Sandiford Committed by Richard Sandiford

[12/n] PR85694: Rework detection of widened operations

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
parent 41949de9
2018-06-30 Richard Sandiford <richard.sandiford@arm.com>
* 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.
2018-06-30 Richard Sandiford <richard.sandiford@arm.com>
* gimple-iterator.c (gsi_for_stmt): Add a new overload that takes
the containing gimple_seq *.
* gimple-iterator.h (gsi_for_stmt): Declare it.
......
2018-06-30 Richard Sandiford <richard.sandiford@arm.com>
* 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.
2018-06-30 Richard Sandiford <richard.sandiford@arm.com>
* gcc.dg/vect/vect-reduc-dot-u16b.c: Remove xfail and update the
test for vectorization along the lines described in the comment.
......
......@@ -52,4 +52,5 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { unaligned_stack || { vect_no_align && { ! vect_hw_misalign } } } } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" { xfail *-*-* } } } */
/* Exclude widening of i * 4 in the calculation of a[i]. */
/* { dg-final { scan-tree-dump-times {vect_recog_widen_mult_pattern: detected: [^\n]* \* ([^4]|4[^;])} 1 "vect" { xfail *-*-* } } } */
......@@ -37,5 +37,5 @@ main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "vect_recog_mult_pattern: detected" 2 "vect" { target aarch64*-*-* xfail aarch64_sve } } } */
/* { dg-final { scan-tree-dump {vect_recog_mult_pattern: detected:[^\n]* \* 123} "vect" { target aarch64*-*-* xfail aarch64_sve } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target aarch64*-*-* } } } */
......@@ -36,5 +36,5 @@ main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "vect_recog_mult_pattern: detected" 2 "vect" { target aarch64*-*-* xfail aarch64_sve } } } */
/* { dg-final { scan-tree-dump {vect_recog_mult_pattern: detected:[^\n]* \* -19594} "vect" { target aarch64*-*-* xfail aarch64_sve } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target aarch64*-*-* } } } */
/* { dg-require-effective-target vect_int } */
#include "tree-vect.h"
#define N 50
#ifndef SIGNEDNESS_1
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 unsigned
#endif
SIGNEDNESS_1 int __attribute__ ((noipa))
f (SIGNEDNESS_1 int res, SIGNEDNESS_3 char *restrict a,
SIGNEDNESS_3 char *restrict b)
{
for (__INTPTR_TYPE__ i = 0; i < N; ++i)
{
int av = a[i];
int bv = b[i];
SIGNEDNESS_2 short mult = av * bv;
res += mult;
}
return res;
}
#define BASE ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4)
#define OFFSET 20
int
main (void)
{
check_vect ();
SIGNEDNESS_3 char a[N], b[N];
int expected = 0x12345;
for (int i = 0; i < N; ++i)
{
a[i] = BASE + i * 5;
b[i] = BASE + OFFSET + i * 4;
asm volatile ("" ::: "memory");
expected += (SIGNEDNESS_2 short) (a[i] * b[i]);
}
if (f (0x12345, a, b) != expected)
__builtin_abort ();
}
/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 signed
#include "vect-reduc-dot-1.c"
/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 unsigned
#include "vect-reduc-dot-1.c"
/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 signed
#include "vect-reduc-dot-1.c"
/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 unsigned
#include "vect-reduc-dot-1.c"
/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 signed
#include "vect-reduc-dot-1.c"
/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 unsigned
#include "vect-reduc-dot-1.c"
/* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 signed
#include "vect-reduc-dot-1.c"
/* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#include "tree-vect.h"
#define N 50
#ifndef SIGNEDNESS_1
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 unsigned
#endif
SIGNEDNESS_1 int __attribute__ ((noipa))
f (SIGNEDNESS_1 int res, SIGNEDNESS_3 char *restrict a,
SIGNEDNESS_3 char *restrict b)
{
for (__INTPTR_TYPE__ i = 0; i < N; ++i)
{
int av = a[i];
int bv = b[i];
short diff = av - bv;
SIGNEDNESS_2 short abs = diff < 0 ? -diff : diff;
res += abs;
}
return res;
}
#define BASE1 ((SIGNEDNESS_3 int) -1 < 0 ? -126 : 4)
#define BASE2 ((SIGNEDNESS_3 int) -1 < 0 ? 116 : 220)
int
main (void)
{
check_vect ();
SIGNEDNESS_3 char a[N], b[N];
int expected = 0x12345;
for (int i = 0; i < N; ++i)
{
a[i] = BASE1 + i * 5;
b[i] = BASE1 - i * 4;
asm volatile ("" ::: "memory");
int diff = a[i] - b[i];
expected += (SIGNEDNESS_2 short) (diff < 0 ? -diff : diff);
}
if (f (0x12345, a, b) != expected)
__builtin_abort ();
}
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 signed
#include "vect-reduc-sad-1.c"
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 unsigned
#include "vect-reduc-sad-1.c"
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 signed
#include "vect-reduc-sad-1.c"
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 unsigned
#include "vect-reduc-sad-1.c"
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 unsigned
#define SIGNEDNESS_3 signed
#include "vect-reduc-sad-1.c"
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 unsigned
#include "vect-reduc-sad-1.c"
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 signed
#define SIGNEDNESS_3 signed
#include "vect-reduc-sad-1.c"
/* { dg-final { scan-tree-dump "vect_recog_sad_pattern: detected" "vect" } } */
/* { dg-require-effective-target vect_int } */
#include "tree-vect.h"
#define N 50
#ifndef SIGNEDNESS_1
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 signed
#endif
void __attribute__ ((noipa))
f (SIGNEDNESS_1 short *restrict a, SIGNEDNESS_2 char *restrict b,
SIGNEDNESS_2 char *restrict c)
{
for (__INTPTR_TYPE__ i = 0; i < N; ++i)
{
int bv = (SIGNEDNESS_2 char) b[i];
int cv = (SIGNEDNESS_2 char) c[i];
a[i] = bv * cv;
}
}
#define BASE ((SIGNEDNESS_2 int) -1 < 0 ? -126 : 4)
#define OFFSET 20
int
main (void)
{
check_vect ();
SIGNEDNESS_1 short a[N];
SIGNEDNESS_2 char b[N], c[N];
for (int i = 0; i < N; ++i)
{
b[i] = BASE + i * 5;
c[i] = BASE + OFFSET + i * 4;
asm volatile ("" ::: "memory");
}
f (a, b, c);
for (int i = 0; i < N; ++i)
if (a[i] != (SIGNEDNESS_1 short) ((BASE + i * 5)
* (BASE + OFFSET + i * 4)))
__builtin_abort ();
}
/* { dg-final { scan-tree-dump "vect_recog_widen_mult_pattern: detected" "vect" } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_widen_mult_qi_to_hi } } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 unsigned
#define SIGNEDNESS_2 unsigned
#include "vect-widen-mult-1.c"
/* { dg-final { scan-tree-dump "vect_recog_widen_mult_pattern: detected" "vect" } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_widen_mult_qi_to_hi } } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 unsigned
#include "vect-widen-mult-1.c"
/* { dg-final { scan-tree-dump "vect_recog_widen_mult_pattern: detected" "vect" } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_widen_mult_qi_to_hi } } } */
/* { dg-require-effective-target vect_int } */
#define SIGNEDNESS_1 signed
#define SIGNEDNESS_2 signed
#include "vect-widen-mult-1.c"
/* { dg-final { scan-tree-dump "vect_recog_widen_mult_pattern: detected" "vect" } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_widen_mult_qi_to_hi } } } */
......@@ -56,6 +56,6 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_widen_mult_hi_to_si } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times "widen_mult pattern recognized" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times {vect_recog_widen_mult_pattern: detected:[^\n]* 2333} 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times {widen_mult pattern recognized:[^\n]* 2333} 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
......@@ -73,5 +73,5 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { target vect_widen_mult_hi_to_si } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times "widen_mult pattern recognized" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times {vect_recog_widen_mult_pattern: detected:[^\n]* 2333} 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times {widen_mult pattern recognized:[^\n]* = \(int\)} 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
......@@ -43,4 +43,4 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_hi_to_si } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" } } */
/* { dg-final { scan-tree-dump "vect_recog_widen_mult_pattern: detected" "vect" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment