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.

Reply via email to