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.

I compiled the reduced testcase with:
-O2 -march=rv64gc_zicond -mabi=lp64d
With max-rtl-if-conversion-unpredictable-cost set to 47, the conversion
does not happen and GCC emits a conditional branch followed by three
moves.

With the value set to 48, the ce1 dump reports:
if-conversion succeeded through noce_convert_multiple_sets
and GCC emits one comparison, six czero instructions and three adds,
with no remaining conditional branch in the function.

So this appears to be different from the 1/-1 case you described. The
1/-1 and spaceship improvements may still help the original comparator
before inlining, but the specific if-conversion decision here is for a
multiple-set pointer selection.


Best regards,
Wang Jue









Reply via email to