Re: Re:Re:[RFC] RISC-V: Raise noce if- conversion cost limit

Jeffrey Law <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>

On 8/8/2026 4:57 PM, wangjue wrote:
> Hi Jeff
>
>> Yea, that could well be the one I was looking at fairly recently. At
>> the point where you're considering if-conversion, what values are you
>> selecting across?
> Thanks for the explanation and the commit reference.
> I reduced the MCF case to a small testcase. At the point where RTL
> if-conversion is considered, it is not selecting across 1 and -1.
> Instead, the same condition controls three pairs of pointer values:
> extern void consume (void *, void *, void *);
>
> __attribute__ ((noinline, noclone))
> void
> select_three_pointers (long x, long y,
>                         void *a0, void *a1,
>                         void *b0, void *b1,
>                         void *c0, void *c1)
> {
>    if (x > y)
>      {
>        a0 = a1;
>        b0 = b1;
>        c0 = c1;
>      }
>
>    consume (a0, b0, c0);
> }
>
> In other words, the three selections are:
> a0 = condition ? a1 : a0;
> b0 = condition ? b1 : b0;
> c0 = condition ? c1 : c0;
>
> The original comparator in MCF returns 1 or -1, but after med3 and the
> comparator are inlined into spec_qsort, that intermediate result is
> eliminated. The ID comparison directly controls the three pointer
> selections.
Ah.  It's a series of two-way selects.  Essentially 3 generalized 
conditional moves.  It only seems to if-convert at an absurdly high 
branch cost value (-mbranch-cost=9).

The if-converted sequence looks like:

> (insn 59 0 60 (set (reg:DI 160)
>         (gt:DI (reg/v:DI 134 [ x ])
>             (reg/v:DI 135 [ y ]))) -1
>      (nil))
>
> (insn 60 59 61 (set (reg:DI 162)
>         (if_then_else:DI (eq:DI (reg:DI 160)
>                 (const_int 0 [0]))
>             (const_int 0 [0])
>             (reg/v/f:DI 141 [ c1 ]))) -1
>      (nil))
>
> (insn 61 60 62 (set (reg:DI 161)
>         (if_then_else:DI (ne:DI (reg:DI 160)
>                 (const_int 0 [0]))
>             (const_int 0 [0])
>             (reg/v/f:DI 140 [ c0 ]))) -1
>      (nil))
>
> (insn 62 61 69 (set (reg/v/f:DI 141 [ c1 ])
>         (plus:DI (reg:DI 161)
>             (reg:DI 162))) -1
>      (nil))

Which gets repeated 2 more times for the other values.  The sgt insn is 
repeated and the only obvious redundancy.  Avoiding the redundancy would 
help, but likely would only bring the required cost down to 7 to trigger 
if-conversion (which still seems quite high). However, it may still be 
worth eliminating that redundancy as doing so would likely result 
if-converting cases where we need two generalized conditional moves at 
just a branch cost of 4.  I'll probably file that as a PR momentarily.

For the 3+ case I think we are going to need to do something with the 
cost model, possibly along the lines of what you did.  I think I've got 
enough info now to dive into what you did and draw some conclusions.

Thanks, this has been really helpful in understanding why you tackled 
this problem in the way you did!

jeff
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.