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.