https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101806
Bug ID: 101806 Summary: Extra zero extends for some arguments in some cases Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: enhancement Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: pinskia at gcc dot gnu.org Target Milestone: --- Target: aarch64-*-* Take: bool g(bool a, bool b) { return ~a & b; } ---- CUT --- Currently we produce: and w1, w1, 255 and w0, w0, 255 bic w0, w1, w0 and w0, w0, 1 ---- CUT --- But we should produce: bic w0, w1, w0 and w0, w0, 1 The zero extends are not needed. This happens because combine does the correct thing until it tries to figure out the cutting point:Trying 2, 8 -> 16: 2: r98:SI=zero_extend(x0:QI) REG_DEAD x0:QI 8: r102:SI=~r98:SI&r99:SI REG_DEAD r98:SI REG_DEAD r99:SI 16: x0:SI=r102:SI&0x1 REG_DEAD r102:SI Failed to match this instruction: (set (reg:SI 0 x0) (and:SI (and:SI (not:SI (reg:SI 0 x0 [ a ])) (reg/v:SI 99 [ b ])) (const_int 1 [0x1]))) Successfully matched this instruction: (set (reg:SI 102) (not:SI (reg:SI 0 x0 [ a ]))) Failed to match this instruction: (set (reg:SI 0 x0) (and:SI (and:SI (reg:SI 102) (reg/v:SI 99 [ b ])) (const_int 1 [0x1]))) If we had chose (and:SI (not:SI (reg:SI 0 x0 [ a ])) (reg/v:SI 99 [ b ])) instead, we would have gotten the correct thing.