https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122286
Bug ID: 122286
Summary: fold (a < b) ? -1 : (a > b ? 1 : 0) into (a < b) - (a
> b) or the other way around
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: manu at gcc dot gnu.org
Target Milestone: ---
These 3 functions generate completely different assembler:
__attribute__((optimize("-ffinite-math-only","-fno-signaling-nans",
"-fno-trapping-math"))) int cmp_double_asc(double a, double b) { return (a
< b) ? -1 : (a > b ? 1 : 0); } int cmp_double_asc_2(double a, double b) {
return (a < b) ? -1 : (a > b
__attribute__((optimize("-ffinite-math-only","-fno-signaling-nans",
"-fno-trapping-math")))
int cmp_double_asc(double a, double b) {
return (a < b) ? -1 : (a > b ? 1 : 0);
}
int cmp_double_asc_2(double a, double b) {
return (a < b) ? -1 : (a > b ? 1 : 0);
}
__attribute__((optimize("-ffinite-math-only","-fno-signaling-nans",
"-fno-trapping-math")))
int cmp_double_asc_branchless(double a, double b) {
return (a < b) - (a > b);
}
with gcc -O3 -march=x86-64-v4
"cmp_double_asc":
xor eax, eax
vcomisd xmm0, xmm1
mov edx, -1
seta al
cmovb eax, edx
ret
"cmp_double_asc_2":
vcomisd xmm1, xmm0
mov eax, -1
ja .L7
xor eax, eax
vcomisd xmm0, xmm1
seta al
.L7:
ret
"cmp_double_asc_branchless":
xor eax, eax
vcomisd xmm1, xmm0
seta al
xor edx, edx
vcomisd xmm0, xmm1
seta dl
sub eax, edx
ret
I can understand why the second function without extra optimize options may be
different, but the first and third functions should generate the same code, no?
https://godbolt.org/z/oT7jc7Thd