https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104950

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #1)
> Confirmed, reduced testcase:
> struct Node{
>     int i, l,r;
> };
> int eval(int t, struct Node *a)  {
>     return t == 0 ? a->r : a->l;
> }
> 
> Note on aarch64, if we remove the i field, then ifcvt on the RTL level is
> able to catch it but it does not do it for x86_64 (maybe a cost issue).

I think it's for the fear of one of a->r / a->l trapping while the other is
not.  With

struct Node{
    int i, l,r;
};
int eval(int t, struct Node *a)  {
    int r = a->r;
    int l = a->l;
    return t == 0 ? r : l;
}

and using -fno-tree-sink we get branchless code on x86_64.

I think we can use TBAA to argue that *a should be valid to dereference here.
What Andrew shows with removing 'i' is likely struct Node then having
large enough alignment guarantees(?) or a bug in the aarch64 backend.

Reply via email to