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

Reply via email to