https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116896
--- Comment #16 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Jakub Jelinek from comment #15) > Created attachment 59272 [details] > gcc15-pr116896-inc.patch > > Incremental patch which performs the subtraction in QImode and then > sign-extends. > Though, not sure if that results in better code. > float case: > comiss %xmm1, %xmm0 > jp .L2 > seta %al > sbbb $0, %al > ret > .L2: > movl $2, %eax > ret > float -ffast-math > comiss %xmm1, %xmm0 > seta %al > sbbb $0, %al > ret > int case > cmpl %esi, %edi > setl %dl > setg %al > subl %edx, %eax > ret > unsigned case > cmpl %edi, %esi > setg %al > sbbb $0, %al > ret > Note, std::partial_ordering or std::strong_ordering are classes with signed > char member. > > Another option might be to just emit the code we'd like to see after the > optimizations right away if that is possible, so emit the clearing > instructions before the actual comparison, and emit whatever combine etc. > will turn those into. This looks pretty optimal to me, but I don't know about: > setl %dl > setg %al > subl %edx, %eax The mode change of the register access (QImode -> SImode) can create problems. Please note that SETc insns (and MOVB, FWIW) on x86 insert LSB into wide SImode register, so there could be some sync uops emitted to handle the transition. We are spared of this detail with clearing XORs and using SImode instructions.