https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92281
Bug ID: 92281 Summary: Inconsistent canonicalization of (minus (minus A B) C) Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: rearnsha at gcc dot gnu.org CC: segher at kernel dot crashing.org Target Milestone: --- Here are two combine attempts from a simple testcase: arm-none-eabi-gcc -O2 -marm -mcpu=arm7tdmi typedef unsigned long long t64; t64 f1(t64 a, t64 b) { return a + ~b; } Trying 19 -> 8: 19: r119:SI=r127:SI REG_DEAD r127:SI 8: r125:SI=r119:SI-ltu(cc:CC,0)-r121:SI REG_DEAD r121:SI REG_DEAD r119:SI REG_DEAD cc:CC Failed to match this instruction: (set (reg:SI 125 [+4 ]) (minus:SI (minus:SI (reg:SI 127) (reg:SI 121 [ b+4 ])) (ltu:SI (reg:CC 100 cc) (const_int 0 [0])))) Trying 21 -> 8: 21: r121:SI=r129:SI REG_DEAD r129:SI 8: r125:SI=r119:SI-ltu(cc:CC,0)-r121:SI REG_DEAD r121:SI REG_DEAD r119:SI REG_DEAD cc:CC Successfully matched this instruction: (set (reg:SI 125 [+4 ]) (minus:SI (minus:SI (reg:SI 119 [ a+4 ]) (ltu:SI (reg:CC 100 cc) (const_int 0 [0]))) (reg:SI 129))) These are mathematically equivalent, but because we do not produce consistent RTL for them we need two patterns if we are to match both alternatives. I think both should be canonicalized with the LTU inside the inner MINUS expression, but I wouldn't mind if the other were chosen, as long as we were consistent.