[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2025-06-04 Thread liuhongt at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645
Bug 92645 depends on bug 92658, which changed state.

Bug 92658 Summary: x86 lacks vector extend / truncate
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92658

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2023-05-22 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Andrew Pinski  changed:

   What|Removed |Added

   Target Milestone|--- |11.0

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2021-01-13 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #26 from CVS Commits  ---
The master branch has been updated by Richard Biener :

https://gcc.gnu.org/g:285fa338b06b804e72997c4d876ecf08a9c083af

commit r11-6649-g285fa338b06b804e72997c4d876ecf08a9c083af
Author: Richard Biener 
Date:   Wed Jan 13 13:48:31 2021 +0100

tree-optimization/92645 - avoid harmful early BIT_FIELD_REF
canonicalization

This avoids canonicalizing BIT_FIELD_REF  (a, , 0) to
(T1)a on integer typed a.  This confuses the vectorizer SLP matching.

With this delayed to after vector lowering the testcase in PR92645
from Skia is now finally optimized to reasonable assembly.

2021-01-13  Richard Biener  

PR tree-optimization/92645
* match.pd (BIT_FIELD_REF to conversion): Delay canonicalization
until after vector lowering.

* gcc.target/i386/pr92645-7.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-54.c: Adjust.
* gcc.dg/pr69047.c: Likewise.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2021-01-13 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Richard Biener  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

--- Comment #27 from Richard Biener  ---
Fixed.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2021-01-13 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #25 from CVS Commits  ---
The master branch has been updated by Richard Biener :

https://gcc.gnu.org/g:3ddc18251a821fe69d6229abbf83d77284d2340a

commit r11-6644-g3ddc18251a821fe69d6229abbf83d77284d2340a
Author: Richard Biener 
Date:   Wed Jan 13 12:40:01 2021 +0100

tree-optimization/92645 - improve SLP with existing vectors

This improves SLP discovery in the face of existing vectors allowing
punning of the vector shape (or even punning from an integer type).
For punning from integer types this does not yet handle lane zero
extraction being represented as conversion rather than BIT_FIELD_REF.

2021-01-13  Richard Biener  

PR tree-optimization/92645
* tree-vect-slp.c (vect_build_slp_tree_1): Relax supported
BIT_FIELD_REF argument.
(vect_build_slp_tree_2): Record the desired vector type
on the external vector def.
(vectorizable_slp_permutation): Handle required punning
of existing vector defs.

* gcc.target/i386/pr92645-6.c: New testcase.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2021-01-13 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #24 from Richard Biener  ---
Created attachment 49958
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49958&action=edit
unincluded GCC source

The GCC source no longer compiles due to missing changes in the x86 intrinsic
includes in the preprocessed source:

...
/aux/hubicka/trunk-install2/lib/gcc/x86_64-pc-linux-gnu/10.0.0/include/avx512vlbwintrin.h:
In function 'void _mm_mask_cvtsepi16_storeu_epi8(void*, __mmask8, __m128i)':
/aux/hubicka/trunk-install2/lib/gcc/x86_64-pc-linux-gnu/10.0.0/include/avx512vlbwintrin.h:258:38:
error: cannot convert '__v8qi*' to 'long long unsigned int*'
: note:   initializing argument 1 of 'void
__builtin_ia32_pmovswb128mem_mask(long long unsigned int*, __vector(8) short
int, unsigned char)'
In file included from
/aux/hubicka/trunk-install2/lib/gcc/x86_64-pc-linux-gnu/10.0.0/include/immintrin.h:69,
 from
/aux/hubicka/firefox-2019-2/gfx/skia/skia/src/opts/SkOpts_
...

attached unincluded source that can be compiled with trunk and GCC 10
when using -march=haswell

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2020-04-23 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #23 from Richard Biener  ---
So the issue is we're both not doing enough and too much, the half way early
optimizations do confuse us later.  Another such opportunity would maybe
be:

   short unsigned int _950;
  _950 = BIT_FIELD_REF <_58, 16, 240>;
  _253 = (unsigned char) _950;

where this is the only use of _950.  It might be tempting to "optimize"
this into

  _253 = BIT_FIELD_REF <_58, 8, 240>;

forwprop does similar transforms for loads of complex and vector (though
the above is not a load but the transform would extend to loads as well).

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2020-03-05 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #22 from Andrew Pinski  ---
(In reply to Richard Biener from comment #20)
> where SLP vectorization is confused about (char) _19 vs. BIT_FIELD_REF
> but also wouldn't handle BIT_FIELD_REFs.  It neither vectorizes the
> store to a store from a CTOR which forwprop could then pattern-match.

I ran into the issue of (cast) _1 also.  I had a function which finds BFRs and
treated the cast to a lower precision as a BFR:
/* Find a BIT_FIELD_REF from the ssa is defined by.
   Expand the BIT_FIELD_REF to BITPOS, BITSIZE and OUTERSIZE.  Returning
   the inner value of the BIT_FIELD_REF.   */
tree
ssa_name_to_BFR (tree value, unsigned HOST_WIDE_INT &bitpos,
 unsigned HOST_WIDE_INT &bitsize,
 unsigned HOST_WIDE_INT &outersize)
{
  if (TREE_CODE (value) != SSA_NAME)
return NULL;
  gimple *def = SSA_NAME_DEF_STMT (value);
  if (stmt_could_throw_p (cfun, def)
  || !is_gimple_assign (def))
return NULL;

  /* Treat a normal cast as extracting the lower bits of the inner value. */
  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
{
  tree inner = gimple_assign_rhs1 (def);
  tree outer_type = TREE_TYPE (value);
  tree inner_type = TREE_TYPE (inner);
  if (!INTEGRAL_TYPE_P (outer_type)
  || !INTEGRAL_TYPE_P (inner_type))
return NULL;
  outersize = TYPE_PRECISION (inner_type);
  bitsize = TYPE_PRECISION (outer_type);
  if (outersize <= bitsize)
return NULL;
  gimple_set_visited (def, true);
  bitpos = 0;
  return inner;
}

  if (gimple_assign_rhs_code (def) != BIT_FIELD_REF)
return NULL;

  tree bfr = gimple_assign_rhs1 (def);
  /* Make sure the BIT_FIELD_REF is acting on a SSA_NAME.
 Cannot handle an memory value. */
  if (TREE_CODE (TREE_OPERAND (bfr, 0)) != SSA_NAME)
return NULL;

  bitsize = tree_to_uhwi (TREE_OPERAND (bfr, 1));
  bitpos = tree_to_uhwi (TREE_OPERAND (bfr, 2));
  tree otype = TREE_TYPE (TREE_OPERAND (bfr, 0));

  if (INTEGRAL_TYPE_P (otype))
outersize = TYPE_PRECISION (otype);
  else
outersize = tree_to_uhwi (TYPE_SIZE (otype));

  if (INTEGRAL_TYPE_P (otype) && BYTES_BIG_ENDIAN)
bitpos = outersize - bitsize - bitpos;

  /* Mark the statement as visited as we might remove the
 reference to it later on. */
  gimple_set_visited (def, true);
  return TREE_OPERAND (bfr, 0);
}

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2020-03-05 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #21 from Jakub Jelinek  ---
Perhaps that is something store-merging should handle too and related to the
issue Xionghu Luo showed in the "Run store-merging pass once more before pass
fre/pre" thread on gcc-patches.  Ideally store-merging should handle both, and
SLP too.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2020-03-05 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #20 from Richard Biener  ---
Small C testcase for one of the patterns we miss to optimize/vectorize:

void foo (char * __restrict src, short * __restrict dest)
{
  union {
  __int128_t i;
  char v[16];
  } u;
  __builtin_memcpy (&u.i, src, 16);
  dest[0] = u.v[0];
  dest[1] = u.v[1];
  dest[2] = u.v[2];
  dest[3] = u.v[3];
  dest[4] = u.v[4];
  dest[5] = u.v[5];
  dest[6] = u.v[6];
  dest[7] = u.v[7];
  dest[8] = u.v[8];
  dest[9] = u.v[9];
  dest[10] = u.v[10];
  dest[11] = u.v[11];
  dest[12] = u.v[12];
  dest[13] = u.v[13];
  dest[14] = u.v[14];
  dest[15] = u.v[15];
}

presents itself as

  _19 = MEM <__int128 unsigned> [(char * {ref-all})src_18(D)];
  _37 = (char) _19;
  _1 = (short int) _37;
  *dest_20(D) = _1;
  _38 = BIT_FIELD_REF <_19, 8, 8>;
  _2 = (short int) _38;
  MEM[(short int *)dest_20(D) + 2B] = _2;
  _39 = BIT_FIELD_REF <_19, 8, 16>;
  _3 = (short int) _39;
  MEM[(short int *)dest_20(D) + 4B] = _3;
...
  _16 = (short int) _52;
  MEM[(short int *)dest_20(D) + 30B] = _16;
  return;

where SLP vectorization is confused about (char) _19 vs. BIT_FIELD_REF
but also wouldn't handle BIT_FIELD_REFs.  It neither vectorizes the
store to a store from a CTOR which forwprop could then pattern-match.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2020-02-27 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645
Bug 92645 depends on bug 93508, which changed state.

Bug 93508 Summary: VN doesn't handle _chk functions or valueize their length
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93508

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2020-01-30 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #19 from Richard Biener  ---
So after the PR92706 fix there's still a lot left on the table.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2020-01-30 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645
Bug 92645 depends on bug 92706, which changed state.

Bug 92706 Summary: SRA confuses FRE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92706

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-12-03 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #18 from Richard Biener  ---
Author: rguenth
Date: Tue Dec  3 11:59:13 2019
New Revision: 278934

URL: https://gcc.gnu.org/viewcvs?rev=278934&root=gcc&view=rev
Log:
2019-12-03  Richard Biener  

PR tree-optimization/92645
* gimple-fold.c (gimple_fold_builtin_memory_op): Fold memcpy
from or to a properly aligned register variable.

* gcc.target/i386/pr92645-5.c: New testcase.

Added:
trunk/gcc/testsuite/gcc.target/i386/pr92645-5.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/gimple-fold.c
trunk/gcc/testsuite/ChangeLog

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-12-03 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645
Bug 92645 depends on bug 92751, which changed state.

Bug 92751 Summary: VN partial def support confused about clobbers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92751

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-12-02 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #17 from Richard Biener  ---
Author: rguenth
Date: Tue Dec  3 07:36:14 2019
New Revision: 278920

URL: https://gcc.gnu.org/viewcvs?rev=278920&root=gcc&view=rev
Log:
2019-12-03  Richard Biener  

PR tree-optimization/92645
* tree-ssa.c (execute_update_addresses_taken): Avoid representing
a full def of a vector via a BIT_INSERT_EXPR.

Modified:
trunk/gcc/ChangeLog
trunk/gcc/tree-ssa.c

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-28 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #16 from Richard Biener  ---
Author: rguenth
Date: Thu Nov 28 12:26:50 2019
New Revision: 278807

URL: https://gcc.gnu.org/viewcvs?rev=278807&root=gcc&view=rev
Log:
2019-11-28  Richard Biener  

PR tree-optimization/92645
* tree-inline.c (remap_gimple_stmt): When the return value
is not wanted, elide GIMPLE_RETURN.

* gcc.dg/tree-ssa/inline-12.c: New testcase.

Added:
trunk/gcc/testsuite/gcc.dg/tree-ssa/inline-12.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/testsuite/ChangeLog
trunk/gcc/tree-inline.c

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-28 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #15 from Richard Biener  ---
Author: rguenth
Date: Thu Nov 28 12:22:04 2019
New Revision: 278806

URL: https://gcc.gnu.org/viewcvs?rev=278806&root=gcc&view=rev
Log:
2019-11-28  Richard Biener  

PR tree-optimization/92645
* tree-ssa-forwprop.c (get_bit_field_ref_def): Also handle
conversions inside a mode class.  Remove restriction on
preserving the element size.
(simplify_vector_constructor): Deal with the above and for
identity permutes also try using VEC_UNPACK_[FLOAT_]LO_EXPR
and VEC_PACK_TRUNC_EXPR.

* gcc.target/i386/pr92645-4.c: New testcase.

Added:
trunk/gcc/testsuite/gcc.target/i386/pr92645-4.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/testsuite/ChangeLog
trunk/gcc/tree-ssa-forwprop.c

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-27 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |rguenth at gcc dot 
gnu.org

--- Comment #14 from Richard Biener  ---
Created attachment 47378
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47378&action=edit
patch

Patch I was playing with.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-27 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #13 from Richard Biener  ---
So with all tricks I arrive at the following for the reduced testcase

f:
.LFB2:
.cfi_startproc
pushq   %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movl%ecx, %r9d
vpxor   %xmm4, %xmm4, %xmm4
movl$255, %eax
shrl$24, %r9d
subl%r9d, %eax
movq%rsp, %rbp
.cfi_def_cfa_register 6
andq$-32, %rsp
movl%eax, %r8d
vmovdqa %ymm4, -32(%rsp)
vmovd   %ecx, %xmm4
shrl$7, %eax
vpshufd $0, %xmm4, %xmm4
addl%r8d, %eax
vmovaps %xmm4, -32(%rsp)
vpmovzxbw   -32(%rsp), %ymm2
vmovd   %eax, %xmm0
vpbroadcastb%xmm0, %xmm0
vpsllw  $8, %ymm2, %ymm2
vpaddw  .LC1(%rip), %ymm2, %ymm2
testq   %rdx, %rdx
je  .L10
vpxor   %xmm5, %xmm5, %xmm5
vmovdqa .LC0(%rip), %xmm3
xorl%eax, %eax
vmovdqa %ymm5, -32(%rsp)
vmovaps %xmm0, -32(%rsp)
vpmovzxbw   -32(%rsp), %ymm4
.p2align 4,,10
.p2align 3
.L7:
vmovdqu (%rsi,%rax), %xmm6
vpxor   %xmm5, %xmm5, %xmm5
vmovdqa %ymm5, -32(%rsp)
vmovaps %xmm6, -32(%rsp)
vpmovzxbw   -32(%rsp), %ymm0
vpmullw %ymm4, %ymm0, %ymm0
vpaddw  %ymm2, %ymm0, %ymm0
vpsrlw  $8, %ymm0, %ymm0
vmovdqa %xmm0, %xmm1
vextracti128$0x1, %ymm0, %xmm0
vpand   %xmm1, %xmm3, %xmm1
vpand   %xmm0, %xmm3, %xmm0
vpackuswb   %xmm0, %xmm1, %xmm0
vmovups %xmm0, (%rdi,%rax)
addq$16, %rax
subq$4, %rdx
jne .L7
.L10:
vzeroupper
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size   f, .-f

where the stack spills still look bad - shomehow we don't like

  _60 = BIT_INSERT_EXPR <{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, _4, 0>;
  _61 = [vec_unpack_lo_expr] _60;

which is "widening" _4 to double vector size when we know we'll just need
the lowpart for the VEC_UNPACK_LO_EXPR.  This _should_ translate to
a mov %xmm, %ymm but somehow it doesn't.

A small testcase for that is the zxt() function in the reduced testcase.
Using an undef SSA name in place off the { 0, ... } vector doesn't help
either.  A simple VIEW_CONVERT isn't valid (it changes size).

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-27 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Richard Biener  changed:

   What|Removed |Added

 CC||hjl.tools at gmail dot com,
   ||uros at gcc dot gnu.org

--- Comment #12 from Richard Biener  ---
So it's probably better but not great yet.  It would help tremendously to look
at PR92658, for this testcase we specifically need truncv16hiv16qi2 which
can be implemented with pshufb (maybe also better).  I tried the following
(the upper half of the selector is just "garbage")

(define_expand "truncv16hiv16qi2"
  [(set (subreg:V32QI (match_operand:V16QI 0 "register_operand") 0)
(vec_select:V32QI
  (subreg:V32QI (match_operand:V16HI 1 "register_operand") 0)
  (parallel [(const_int 0) (const_int 2)
 (const_int 4) (const_int 6)
 (const_int 8) (const_int 10)
 (const_int 12) (const_int 14)
 (const_int 16) (const_int 18)
 (const_int 20) (const_int 22)
 (const_int 24) (const_int 26)
 (const_int 28) (const_int 30)
 (const_int 0) (const_int 2)
 (const_int 4) (const_int 6)
 (const_int 8) (const_int 10)
 (const_int 12) (const_int 14)
 (const_int 16) (const_int 18)
 (const_int 20) (const_int 22)
 (const_int 24) (const_int 26)
 (const_int 28) (const_int 30)
 ])))]
  "TARGET_AVX2") 

but that isn't recognized.  Possibly because of the outer subreg, who
knows.

(define_insn "truncv16hiv16qi2"
 [(set (match_operand:V16QI 0 "register_operand" "=x,v")
   (truncate:V16QI
(match_operand:V16HI 1 "register_operand" "x,v")))]
 "TARGET_AVX2"
 "@
  pshufb\t{%1, %0|%0, %1}
  vpshufb\t{%1, %0|%0, %1}")

"works" but of course is wrong (somehow need the constant mask in a
register).  The rest of the backend also doesn't know truncate of
vectors so representing as shuffles is probably better.

I also wonder how to macroize all this - probably via some
helpers in i386-expand.c I guess.

But I can also work with the pack/unpack tree codes for now.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-27 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #11 from Richard Biener  ---
Author: rguenth
Date: Wed Nov 27 08:56:23 2019
New Revision: 278758

URL: https://gcc.gnu.org/viewcvs?rev=278758&root=gcc&view=rev
Log:
2019-11-27  Richard Biener  

PR tree-optimization/92645
* tree-ssa-forwprop.c (simplify_vector_constructor): Handle
CTORs with just a subset of the original vectors.

* gcc.target/i386/pr92645-2.c: New testcase.
* gcc.target/i386/pr92645-3.c: Likewise.

Added:
trunk/gcc/testsuite/gcc.target/i386/pr92645-2.c
trunk/gcc/testsuite/gcc.target/i386/pr92645-3.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/testsuite/ChangeLog
trunk/gcc/tree-ssa-forwprop.c

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-26 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #10 from Richard Biener  ---
Author: rguenth
Date: Tue Nov 26 08:32:38 2019
New Revision: 278719

URL: https://gcc.gnu.org/viewcvs?rev=278719&root=gcc&view=rev
Log:
2019-11-26  Richard Biener  

PR tree-optimization/92645
* tree-vect-slp.c (vect_build_slp_tree_2): For unary ops
do not build the operation from scalars if the operand is.

* gcc.target/i386/pr92645.c: New testcase.

Added:
trunk/gcc/testsuite/gcc.target/i386/pr92645.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/testsuite/ChangeLog
trunk/gcc/tree-vect-slp.c

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #9 from Richard Biener  ---
Thanks a lot.  So besides the following mismatch for SLP

  _24 = MEM[base: src_22(D), index: ivtmp.20_267, offset: 0B];
  _97 = (unsigned char) _24;
  _98 = (short unsigned int) _97;
  _99 = BIT_FIELD_REF <_24, 8, 8>;
  _100 = (short unsigned int) _99;
  _101 = BIT_FIELD_REF <_24, 8, 16>;
...


there's also missing forwprop (CTOR -> vector SSA) for

  _62 = BIT_FIELD_REF <_8, 16, 0>;
  _64 = BIT_FIELD_REF <_8, 16, 16>;
  _66 = BIT_FIELD_REF <_8, 16, 32>;
  _68 = BIT_FIELD_REF <_8, 16, 48>;
  _70 = BIT_FIELD_REF <_8, 16, 64>;
  _72 = BIT_FIELD_REF <_8, 16, 80>;
  _74 = BIT_FIELD_REF <_8, 16, 96>;
  _76 = BIT_FIELD_REF <_8, 16, 112>;
  _78 = BIT_FIELD_REF <_8, 16, 128>;
  _80 = BIT_FIELD_REF <_8, 16, 144>;
  _82 = BIT_FIELD_REF <_8, 16, 160>;
  _84 = BIT_FIELD_REF <_8, 16, 176>;
  _86 = BIT_FIELD_REF <_8, 16, 192>;
  _88 = BIT_FIELD_REF <_8, 16, 208>;
  _90 = BIT_FIELD_REF <_8, 16, 224>;
  _92 = BIT_FIELD_REF <_8, 16, 240>;
  _136 = {_78, _80, _82, _84, _86, _88, _90, _92};
  _270 = {_62, _64, _66, _68, _70, _72, _74, _76};

because we only look for full vector builds/shuffles but those CTORs
extract the low/high part of _8.  I'll see to fix that tomorrow.

The conversion vs. BIT_FIELD_REF somehow completely disables the SLP tree
but we could build from scalars, testing patch to fix that.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-25 Thread amonakov at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Alexander Monakov  changed:

   What|Removed |Added

 CC||amonakov at gcc dot gnu.org

--- Comment #8 from Alexander Monakov  ---
(In reply to Richard Biener from comment #5)
> 
> "extracting" the actual loops (inlined and all) in intrinsic form as a C
> testcase would be really really nice.

Something like the following?  Enjoy!

typedef unsigned int u32v4 __attribute__((vector_size(16)));
typedef unsigned short u16v16 __attribute__((vector_size(32)));
typedef unsigned char u8v16 __attribute__((vector_size(16)));

union vec128 {
  u8v16 u8;
  u32v4 u32;
};

#define memcpy __builtin_memcpy

u16v16 zxt(u8v16 x)
{
  return (u16v16) {
x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7],
x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
  };
}

u8v16 narrow(u16v16 x)
{
  return (u8v16) {
x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7],
x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
  };
}

void f(char *dst, char *src, unsigned long n, unsigned c)
{
  unsigned ia = 255 - (c >> 24);
  ia += ia >> 7;

  union vec128 c4 = {0}, ia16 = {0};
  c4.u32 += c;
  ia16.u8 += (unsigned char)ia;

  u16v16 c16 = (zxt(c4.u8) << 8) + 128;

  for (; n; src += 16, dst += 16, n -= 4) {
union vec128 s;
memcpy(&s, src, sizeof s);
s.u8 = narrow((zxt(s.u8)*zxt(ia16.u8) + c16) >> 8);
memcpy(dst, &s, sizeof s);
  }
}

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #7 from Richard Biener  ---
Kind-of a testcase for SSE2, but this has a matching BIT_FIELD_REF at least,
but still "fails" at the vector source.  Skia seems to pun to __int128
before doing the extracts somehow (maybe that's our intrinsics, who knows).

typedef unsigned short v8hi __attribute__((vector_size(16)));
typedef unsigned int v4si __attribute__((vector_size(16)));

void foo (v4si *dst, v8hi src)
{
  unsigned int tem[8];
  tem[0] = src[0];
  tem[1] = src[1];
  tem[2] = src[2];
  tem[3] = src[3];
  tem[4] = src[4];
  tem[5] = src[5];
  tem[6] = src[6];
  tem[7] = src[7];
  dst[0] = *(v4si *)tem;
  dst[1] = *(v4si *)&tem[4];
}

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Richard Biener  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-11-25
 Ever confirmed|0   |1

--- Comment #6 from Richard Biener  ---
Probably skvx::cast is the most intrusive one here ending up with

  _37 = MEM[(const struct Vec &)&D.98687 + 15].val;
  x_38 = (short unsigned int) _37;
  _39 = MEM[(const struct Vec &)&D.98687 + 14].val;
  x_40 = (short unsigned int) _39;
  _41 = MEM[(const struct Vec &)&D.98687 + 13].val;
  x_42 = (short unsigned int) _41;
...
  c.hi.lo.hi.hi.val = x_46;
  c.hi.hi.lo.lo.val = x_44;
  c.hi.hi.lo.hi.val = x_42;
  c.hi.hi.hi.lo.val = x_40;
  c.hi.hi.hi.hi.val = x_38;
  _73 = MEM  [(char * {ref-all})&c];

and expecting some kind of upack() to be used.  It's template magic though.
But yes, we're missing "patterns" to detect VEC_* tree codes like
VEC_UPACK_{HI,LO}_EXPR from straight-line code and basic-block vectorization
isn't tuned for multiple sizes / "unpacking reductions" and thus does't
work here either, more specifically it first fails at the appearant mismatch
here:

  _32 = (unsigned char) src_2;
  _33 = BIT_FIELD_REF ;

(BIT_FIELD_REF vs. cast).  But then it would fail at the common source
of the op:

  src_2 = MEM[(struct Vec *)&D.151762];

because that's not a grouped store (and it has a vector type, something
BB vectorization doesn't like too much either).

It does vectorize some stmts, but it only goes up to blind vector
construction for the uniform vector cases (at least that).

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

Richard Biener  changed:

   What|Removed |Added

   Keywords||missed-optimization
 CC||rguenth at gcc dot gnu.org

--- Comment #5 from Richard Biener  ---
What flags do I need?  Hmm, unincluding isn't very successful, with trunk it
seems to at least compile...

I see

   [local count: 955630224]:
  # ivtmp.13749_388 = PHI <0(4), ivtmp.13749_387(5)>
  _571 = {x_111, x_111, x_111, x_111, x_111, x_111, x_111, x_111, x_111, x_111,
x_111, x_111, x_111, x_111, x_111, x_111};
  _24 = {color_13(D), color_13(D), color_13(D), color_13(D)};
  _93 = MEM[base: src_15(D), index: ivtmp.13749_388, offset: 0B];
  _462 = (unsigned int) _93;
  _461 = BIT_FIELD_REF <_93, 32, 32>;
  _460 = BIT_FIELD_REF <_93, 32, 64>;
  _459 = BIT_FIELD_REF <_93, 32, 96>;
  MEM  [(struct Vec *)&D.151762] = _462;
  MEM  [(struct Vec *)&D.151762 + 4B] = _461;
  MEM  [(struct Vec *)&D.151762 + 8B] = _460;
  MEM  [(struct Vec *)&D.151762 + 12B] = _459;
  src_2 = MEM[(struct Vec *)&D.151762];
  _32 = (unsigned char) src_2;
  _33 = BIT_FIELD_REF ;
  _34 = BIT_FIELD_REF ;
  _35 = BIT_FIELD_REF ;
...

  _106 = (unsigned char) _455;
  _107 = (unsigned char) _456;
  _108 = (unsigned char) _457;
  _109 = (unsigned char) _458;
  _566 = {_109, _108, _107, _106, _105, _104, _103, _102, _101, _100, _99, _98,
_97, _96, _95, _94};
  _550 = VIEW_CONVERT_EXPR<__int128 unsigned>(_566);
  _89 = (unsigned int) _550;
  _90 = BIT_FIELD_REF <_566, 32, 32>;
  _91 = BIT_FIELD_REF <_566, 32, 64>;
  _92 = BIT_FIELD_REF <_566, 32, 96>;
  c ={v} {CLOBBER};
  D.98791.lo.lo.val = _89;
  D.98791.lo.hi.val = _90;
  D.98791.hi.lo.val = _91;
  D.98791.hi.hi.val = _92;
  _538 = MEM <__int128 unsigned> [(char * {ref-all})&D.98791];

so we're not able to "combine" through all sorts of reshuffling here
(FRE would be able to at least produce some vector CTOR for the final
one but it currently resists because of cost reasons in general).

This might be all because of stupid intrinsic use or because our intrinsic
[inline] expansion is stupid or ...

"extracting" the actual loops (inlined and all) in intrinsic form as a C
testcase would be really really nice.

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-24 Thread hubicka at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #4 from Jan Hubicka  ---
Created attachment 47343
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47343&action=edit
GCC 10 output

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-24 Thread hubicka at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #2 from Jan Hubicka  ---
Created attachment 47341
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47341&action=edit
clang output with -O2 -mavx2 -mf16c -mfma

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-24 Thread hubicka at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #3 from Jan Hubicka  ---
Created attachment 47342
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47342&action=edit
GCC source

[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang

2019-11-24 Thread hubicka at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92645

--- Comment #1 from Jan Hubicka  ---
Created attachment 47340
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47340&action=edit
Clang source