On Wed, Sep 16, 2026 at 1:29 PM H.J. Lu <[email protected]> wrote:
>
> On Mon, Sep 14, 2026 at 7:59 PM Richard Biener
> <[email protected]> wrote:
> >
> > On Mon, Sep 14, 2026 at 11:52 AM Liu, Hongtao <[email protected]> wrote:
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Liu, Hongtao <[email protected]>
> > > > Sent: Monday, September 14, 2026 5:45 PM
> > > > To: H.J. Lu <[email protected]>; GCC Patches 
> > > > <[email protected]>;
> > > > Uros Bizjak <[email protected]>
> > > > Subject: RE: [PATCH v3] x86: Adjust cost for vector integer conversion 
> > > > without
> > > > SSE4.1
> > > >
> > > > > +      int scale = 0;
> > > > > +      if (scalar_p)
> > > > > +   {
> > > > > +     if (stmt_info
> > > > > +         && stmt_info->stmt
> > > > > +         && gimple_code (stmt_info->stmt) == GIMPLE_ASSIGN)
> > > > > +       {
> > > > > +         tree lhs = gimple_assign_lhs (stmt_info->stmt);
> > > > > +         if (TREE_CODE (lhs) == ARRAY_REF)
> > > > > +           {
> > > > > +             tree index = TREE_OPERAND (lhs, 1);
> > > > > +             /* Two more instructions are needed to access non-zero
> > > > > +                array element.  */
> > > > > +             if (TREE_CODE (index) != INTEGER_CST
> > > > > +                 || compare_tree_int (index, 0) != 0)
> > > > > +               scale = 2;
> > > > > +           }
> > > > > +       }
> > > > > +   }
> > > >
> > > > Not fully understand this part, why access non-zero array elements 
> > > > should be
> > > > penalized with additional cost, is it testcase specific or it's general?
>
> Without it, I got
>
> FAIL: gcc.target/i386/pr111023-2.c scan-assembler (?:pcmpgtd|psrad)
> FAIL: gcc.target/i386/pr111023-2.c scan-assembler punpckldq
> FAIL: gcc.target/i386/pr111023-4b.c scan-assembler punpcklbw
> FAIL: gcc.target/i386/pr111023-8b.c scan-assembler punpcklwd
> FAIL: gcc.target/i386/pr111023.c scan-assembler punpckldq
>
> It is
>
>         pxor    %xmm1, %xmm1
>         punpckldq       %xmm1, %xmm0
>         movaps  %xmm0, (%rdi)
>
> vs
>
>         movd    %xmm0, %eax
>         pshufd  $85, %xmm0, %xmm0
>         movd    %xmm0, %edx
>         movq    %rax, (%rdi)
>         movq    %rdx, 8(%rdi)

After increase cost for conversion w/o sse4.1, 2-element vectorization
in pr111023-*.c testcases now failed, to fix the regression you're
adding cost to the scalar part to make it vectorized again. But the
cost added is testcase specific, in general I didn't see addition cost
is needed for non-zero array elements.
The edge case we're currently facing is that vectorization of some
2-element operations is still worthwhile, while for others it's not
cost-effictive. we currently have no good way to fine-tune thsese
scenarios by adjusting the per-statement cost.
One possible solution would be to introduce some heuristics -- trackng
the number of loads,stores,general ops, and in finish_costs, lower the
scalar cost when the vectorization case is very small. But it's still
uncerntain whether this would just be a whack-a-mole fix, where
solving one problem inadvertently creates another.
>
> > > >
> > > > > +      else if (vector_int_conversion_p && !TARGET_SSE4_1)
> > > > > +   {
> > > > > +     /* Two instructions are needed to emulate vector integer
> > > > > +        conversions.  One more instruction is needed to emulate
> > > > > +        2-element vector conversion of QImode and HImode.  */
> > > > > +     machine_mode rhs_mode = TYPE_MODE (rhs_type);
> > > > > +     rhs_mode = GET_MODE_INNER (rhs_mode);
> > > > > +     scale = (rhs_mode == SImode || GET_MODE_NUNITS (mode) != 2
> > > > > +              ? 2 : 3);
> > > > > +   }
> > > >
> > > > It's reasonable to increase cost for signed conversion w/o sse4.1,  but 
> > > > for
> > > > unsigned conversion it's not needed, also I don't think GET_MODE_NUNITS
> > > > (mode) == 2 makes difference from 4/8, it looks tricky.
>
> Without SSE4.1,  ix86_expand_sse_extend generates more instructions for
> unsigned vector extension for
>
> extern unsigned char *var1;
> extern unsigned short var2;
>
> void
> func (void)
> {
>   var2 = var1[1] + var1[0];
> }
>
>         movq    var1(%rip), %rax
>         pxor    %xmm1, %xmm1
>         pinsrw  $0, (%rax), %xmm0
>         punpcklbw       %xmm1, %xmm0


pinsrw is vector load for v2qi, the unsigned convert is pxor +
punpcklbw, pxor is cheap and can be hoist out of loop/hotspot, so the
meaningful comparison between w/ sse4.1 and w/o sse4.1 for unsigned
conversion is
punpcklbw vs pmovzxbw, no additional cost is needed.

>         pextrw  $0, %xmm0, %edx
>         pextrw  $1, %xmm0, %eax
>         addl    %edx, %eax
>         movw    %ax, var2(%rip)
>         ret
>
> > > >
> > > > For the original PR, you're trying to prevent vectorization for 
> > > > 2-elemenet
> > > > reduction.
> > > > Revising per-stmt cost to prevent 2-element integer vectorization may 
> > > > hurt
> > > > others.
> > > > Maybe we can add a specific heuristic to add additional cost for 
> > > > 2-element
> > > > integer vectorization when vector width is less equal WORD, and this 
> > > > should
> > > > solve the issue in the PR and don't regress others.
> > > When VF is 2, vector width <= WORD, and there're cross-unit movement in 
> > > the vectorization(i.e 
> > > vec_contruct/vec_deconstruct/vec_to_scalar/scalar_to_vec.)
> > > Pentise the vectorization with extra cost
> >
> > Or have something like an effective integer issue width and require
> > the vector cost
> > to be better than scalar cost / issue width in the finish_cost hook.
> > I'll note that
> > for the small testcases it's the high scalar load/store cost that
> > gives us that much budget
> > to eat from.
> >
>
>
> --
> H.J.



-- 
BR,
Hongtao

Reply via email to