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

            Bug ID: 114732
           Summary: ge can't be reversed to unlt for bcd compares
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: guihaoc at gcc dot gnu.org
  Target Milestone: ---

//test.c
int
foo (vector unsigned char a, vector unsigned char b)
{
  return __builtin_vec_bcdsub_ge (a, b, 0) != 1;
}

//assembly
        bcdsub. 2,2,3,0
        cror 26,24,27
        mfcr 3,2
        rlwinm 3,3,27,1
        blr


Here ge is reversed to unlt in combine pass. 
Trying 9 -> 10:
    9: r128:SI=%6:CCFP>=0
      REG_DEAD %6:CCFP
   10: r127:SI=r128:SI^0x1
      REG_DEAD r128:SI
Successfully matched this instruction:
(set (reg:SI 127)
    (unlt:SI (reg:CCFP 106 6)
        (const_int 0 [0])))
allowing combination of insns 9 and 10
original costs 12 + 4 = 16
replacement cost 12
deferring deletion of insn with uid = 9.
modifying insn i3    10: r127:SI=unlt(%6:CCFP,0)
      REG_DEAD %6:CCFP
deferring rescan insn with uid = 10.

But it's wrong for bcd. The ge should be reversed to lt for bcd. The unorder
bit (actually it's overflow) doesn't matter. The root cause is bcd operations
use CCFP and CCFP allows reverse ge to unlt. So the bcd operations should use a
seperate CCmode.

Reply via email to