[Bug tree-optimization/92645] Hand written vector code is 450 times slower when compiled with GCC compared to Clang
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
