https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126480
Bug ID: 126480
Summary: Pessimistic costing of truncating stores causes
unwanted vectorisation
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: Chris.Bazley at arm dot com
Target Milestone: ---
The vectorizer estimates unrealistically high costs for some scalar code: a
cost is charged for each narrowing conversion, even though those conversions
are effectively free as part of the associated stores. Consequently, the
vectorizer sometimes decide to vectorize code that probably should not have
been vectorized.
See https://godbolt.org/z/aoT6MEhYT
Example source code:
void
foo (unsigned int *foo, unsigned long *a, unsigned long *b)
{
foo[0] = a[0] >> 33;
foo[1] = a[0] >> 44;
}
Command to invoke the compiler:
/work/gcc/build-debug/gcc/xgcc -B/work/gcc/build-debug/gcc/ test.c
-fdiagnostics-plain-output -march=armv8.2-a+sve -O2 -march=armv8.2-a+sve -S
-o test.s -fdump-tree-slp2-details
Compiler output:
foo:
.LFB0:
.cfi_startproc
ld1r {v31.2d}, [x1]
adrp x1, .LC1
ldr q30, [x1, #:lo12:.LC1]
ushl v30.2d, v31.2d, v30.2d
xtn v30.2s, v30.2d
str d30, [x0]
ret
.cfi_endproc
Expected output:
foo:
.LFB0:
.cfi_startproc
ldr x1, [x1]
lsr x2, x1, 33
lsr x1, x1, 44
stp w2, w1, [x0]
ret
.cfi_endproc
Reasoning of the vectoriser (from the slp2 dump):
***** Analysis succeeded with vector mode V16QI
SLPing BB part
Costing subgraph:
node 0x539fea0 (max_nunits=2, refcnt=1) vector(2) unsigned int
op template: *foo_8(D) = _3;
stmt 0 *foo_8(D) = _3;
stmt 1 MEM[(uint32_t *)foo_8(D) + 4B] = _5;
children 0x539ff58
node 0x539ff58 (max_nunits=2, refcnt=1) vector(2) unsigned int
op template: _3 = (unsigned int) _2;
stmt 0 _3 = (unsigned int) _2;
stmt 1 _5 = (unsigned int) _4;
children 0x53a0010
node 0x53a0010 (max_nunits=2, refcnt=1) vector(2) long unsigned int
op template: _2 = _1 >> 33;
stmt 0 _2 = _1 >> 33;
stmt 1 _4 = _1 >> 44;
children 0x53a00c8 0x53a0180
node (external) 0x53a00c8 (max_nunits=1, refcnt=1) vector(2) long unsigned int
{ _1, _1 }
node (constant) 0x53a0180 (max_nunits=1, refcnt=1) vector(2) long unsigned int
{ 33, 44 }
Cost model analysis:
Scalar cost for part in loop 0
_5 1 times scalar_store costs 1 in body
(unsigned int) _4 1 times scalar_stmt costs 1 in body
_1 >> 44 1 times scalar_stmt costs 1 in body
_3 1 times scalar_store costs 1 in body
(unsigned int) _2 1 times scalar_stmt costs 1 in body
_1 >> 33 1 times scalar_stmt costs 1 in body
Vector cost for part in loop 0
_1 >> 33 1 times vector_stmt costs 1 in body
node 0x53a00c8 1 times scalar_to_vec costs 1 in prologue
<unknown> 1 times vector_load costs 1 in prologue
(unsigned int) _2 1 times vector_stmt costs 1 in body
_3 1 times unaligned_store (misalign -1) costs 1 in body
Cost model analysis for part in loop 0:
Vector cost: 5
Scalar cost: 6
Basic block will be vectorized using SLP