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

            Bug ID: 111949
           Summary: combine split points are not so good with targets that
                    have (and (not x) y)
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pinskia at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64

Take:
```
bool f1(int a, bool b)
{
        int c = a & b;
        return (c ^ a)&1;
}
```
Currently GCC produces:
```
        and     w1, w1, 255
        bic     w0, w0, w1
        and     w0, w0, 1
```

Notice how there are 2 and.

If we look at combine dumps we will see:
Trying 3, 8 -> 10:
    3: r98:SI=zero_extend(x1:QI)
      REG_DEAD x1:QI
    8: r101:SI=~r98:SI&r103:SI
      REG_DEAD r98:SI
      REG_DEAD r103:SI
   10: r102:SI=r101:SI&0x1
      REG_DEAD r101:SI
Failed to match this instruction:
(set (reg:SI 102)
    (and:SI (and:SI (not:SI (reg:SI 1 x1 [ b ]))
            (reg:SI 103))
        (const_int 1 [0x1])))
Successfully matched this instruction:
(set (reg:SI 101)
    (not:SI (reg:SI 1 x1 [ b ])))
Failed to match this instruction:
(set (reg:SI 102)
    (and:SI (and:SI (reg:SI 101)
            (reg:SI 103))
        (const_int 1 [0x1])))

The first part is good but the second part is not so good and shows that
combine not finding a good split point and using:
(and:SI (not:SI (reg:SI 1 x1 [ b ])) (reg:SI 103))
as the point how to split the above instruction.

(note I don't know if this should be a generic change or a target specific one
off hand, just filing it to keep track of what missed optimization I found).

Reply via email to