diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 169b2dd24b65a03636e00c14948d8bf53b7ce02f..cb3c14bbb346ac05bc1bcbf41c15612b98be9b0c 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -22975,7 +22975,7 @@ ix86_autovectorize_vector_modes (vector_modes *modes, bool all) if (TARGET_SSE2) modes->safe_push (V4QImode); - return 0; + return ix86_vect_compare_costs ? VECT_COMPARE_COSTS : 0; } /* Implemenation of targetm.vectorize.get_mask_mode. */ @@ -23230,6 +23230,23 @@ ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, stmt_cost = ix86_cost->add; break; default: + if (truth_value_p (subcode)) + { + if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode)) + /* CMPccS? instructions are cheap, so use sse_op. While they + produce a mask which may need to be turned to 0/1 by and, + expect that this will be optimized away in a common case. */ + stmt_cost = ix86_cost->sse_op; + else if (X87_FLOAT_MODE_P (mode)) + /* fcmp + setcc. */ + stmt_cost = ix86_cost->fadd + ix86_cost->add; + else if (VECTOR_MODE_P (mode)) + stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op); + else + /* setcc. */ + stmt_cost = ix86_cost->add; + break; + } break; } } diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index ed31cab0a46a7af8def157ec43b65bcdfc778edf..d8cd58f5291829ef79bc80273f970a0800fd1be0 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1219,6 +1219,10 @@ Do not use GOT to access external symbols. Target Joined UInteger Var(x86_stlf_window_ninsns) Init(64) Param Instructions number above which STFL stall penalty can be compensated. +-param=ix86-vect-compare-costs= +Target Joined UInteger Var(ix86_vect_compare_costs) Init(1) IntegerRange(0, 1) Param Optimization +Whether x86 vectorizer cost modeling compares costs of different vector sizes. + mgather Target Alias(mtune-ctrl=, use_gather, ^use_gather) Enable vectorization for gather instruction. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index baf066400daf290b54c4b3db3756666f8b22ef5d..7df9e16fdf322fe6093ce8dc3721228b069ebe50 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -15302,6 +15302,11 @@ The following choices of @var{name} are available on i386 and x86_64 targets: @item x86-stlf-window-ninsns Instructions number above which STFL stall penalty can be compensated. +@item ix86-vect-compare-costs +Whether x86 vectorizer cost modeling compares costs of different vector sizes. +The value may be 0 or 1. The default is 1; set it to 0 to restore the +previous behavior. + @end table @end table diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr120398.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr120398.c new file mode 100644 index 0000000000000000000000000000000000000000..39be0b61efd8cb3b373bb638661c72aea248a7bc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr120398.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +static float +muladd (float x, float y, float z) +{ + return x * y + z; +} + +float +g (float x[], long n) +{ + float r0 = 0, r1 = 0; + for (; n; x += 2, n--) + { + r0 = muladd (x[0], x[0], r0); + r1 = muladd (x[1], x[1], r1); + } + return r0 + r1; +} + +/* { dg-final { scan-tree-dump "Choosing vector mode V8QI" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr123603.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr123603.c new file mode 100644 index 0000000000000000000000000000000000000000..b9844867ac1db62fe65e306edafdf12887a18abe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr123603.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* This test relies on the EulerGCC-specific c86-4g-m7 cost model. */ +/* { dg-additional-options "-mtune=c86-4g-m7" } */ + +void foo (int *block) +{ + for (int i = 0; i < 3; ++i) + { + int a = block[i * 9]; + int b = block[i * 9 + 1]; + block[i * 9] = a + 10; + block[i * 9 + 1] = b + 10; + } +} + +/* { dg-final { scan-tree-dump "optimized: loop vectorized using 8 byte vectors" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-1.c b/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-1.c index 4aa536ba86c93526a40744e42be1f86d737af2cf..39ca8b13fdf545dad5cac76f4f13a04dbd7505ea 100644 --- a/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-1.c +++ b/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-1.c @@ -85,6 +85,6 @@ int main() __builtin_abort (); } -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 4 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 7 "vect" } } */ /* Verify all vector accesses are emitted as aligned. */ /* { dg-final { scan-assembler-not "movup" } } */ diff --git a/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-2.c b/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-2.c index 834bf0f770d66d1513dacb9cfb66387a75da3b76..9557e620a18e9128e641d78737393dc7e6692751 100644 --- a/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-2.c +++ b/gcc/testsuite/gcc.target/i386/vect-alignment-peeling-2.c @@ -85,6 +85,6 @@ int main() __builtin_abort (); } -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 4 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 7 "vect" } } */ /* Verify all vector accesses are emitted as aligned. */ /* { dg-final { scan-assembler-not "movup" } } */