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.