[InstCombine] missed signbit comparisons -> copysign
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
found from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109843
https://github.com/gcc-mirror/gcc/commit/1c8ca0108746d3a7452134f9d1c2e5d89857fed7
>MATCH: fold signbit comparison and conditional negate to copysign [PR109843]
Fold (signbit (x) cmp1 0) cmp (signbit (y) cmp2 0) ? y : -y
to copysign (y, +-x). The result keeps the magnitude of Y and takes its
sign from X (or -X). Emitted as IFN_COPYSIGN when the target supports it.
```c
#include
/* Transforms to copysign (y, x) */
float copysign1 (float x, float y)
{
bool t = __builtin_signbit (x) == 0;
bool t1 = __builtin_signbit (y) == 0;
return (t == t1) ? y : -y;
}
float copysign2 (float x, float y)
{
bool t = __builtin_signbit (x) != 0;
bool t1 = __builtin_signbit (y) != 0;
return (t == t1) ? y : -y;
}
float copysign3 (float x, float y)
{
bool t = __builtin_signbit (x) != 0;
bool t1 = __builtin_signbit (y) == 0;
return (t != t1) ? y : -y;
}
float copysign4 (float x, float y)
{
bool t = __builtin_signbit (x) == 0;
bool t1 = __builtin_signbit (y) != 0;
return (t != t1) ? y : -y;
}
float copysign5 (float x, float y)
{
bool t = __builtin_signbit (y) == 0;
bool t1 = __builtin_signbit (x) == 0;
return (t == t1) ? y : -y;
}
/* Transforms to copysign (y, -x) */
float copysign6 (float x, float y)
{
bool t = __builtin_signbit (x) == 0;
bool t1 = __builtin_signbit (y) == 0;
return (t != t1) ? y : -y;
}
float copysign7 (float x, float y)
{
bool t = __builtin_signbit (x) != 0;
bool t1 = __builtin_signbit (y) == 0;
return (t == t1) ? y : -y;
}
float copysign8 (float x, float y)
{
bool t = __builtin_signbit (x) == 0;
bool t1 = __builtin_signbit (y) != 0;
return (t == t1) ? y : -y;
}
float copysign9 (float x, float y)
{
bool t = __builtin_signbit (x) != 0;
bool t1 = __builtin_signbit (y) != 0;
return (t != t1) ? y : -y;
}
```
gcc:
```asm
"copysign1":
vmovaps xmm2, xmm0
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign2":
vmovaps xmm2, xmm0
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign3":
vmovaps xmm2, xmm0
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign4":
vmovaps xmm2, xmm0
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign5":
vmovaps xmm2, xmm0
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign6":
vxorps xmm2, xmm0, XMMWORD PTR .LC3[rip]
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign7":
vxorps xmm2, xmm0, XMMWORD PTR .LC3[rip]
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign8":
vxorps xmm2, xmm0, XMMWORD PTR .LC3[rip]
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
"copysign9":
vxorps xmm2, xmm0, XMMWORD PTR .LC3[rip]
vmovaps xmm3, xmm1
vpternlogd xmm3, xmm2, DWORD PTR .LC2[rip]{1to4}, 228
vmovaps xmm0, xmm3
ret
.LC2:
.long 2147483647
.LC3:
.long -2147483648
.long 0
.long 0
.long 0
```
clang:
```asm
.LCPI0_0:
.long 0x80000000
copysign1:
vmovd eax, xmm0
vmovd ecx, xmm1
vpxord xmm0, xmm1, dword ptr [rip + .LCPI0_0]{1to4}
xor eax, ecx
sets al
kmovd k1, eax
vmovss xmm1 {k1}, xmm1, xmm0
vmovaps xmm0, xmm1
ret
.LCPI1_0:
.long 0x80000000
copysign2:
vmovd eax, xmm0
vmovd ecx, xmm1
vpxord xmm0, xmm1, dword ptr [rip + .LCPI1_0]{1to4}
xor eax, ecx
sets al
kmovd k1, eax
vmovss xmm1 {k1}, xmm1, xmm0
vmovaps xmm0, xmm1
ret
.LCPI2_0:
.long 0x80000000
copysign3:
vmovd eax, xmm0
vmovd ecx, xmm1
xor eax, ecx
sets al
vpxord xmm0, xmm1, dword ptr [rip + .LCPI2_0]{1to4}
kmovd k1, eax
vmovss xmm1 {k1}, xmm1, xmm0
vmovaps xmm0, xmm1
ret
.LCPI3_0:
.long 0x80000000
copysign4:
vmovd eax, xmm0
vmovd ecx, xmm1
xor eax, ecx
sets al
vpxord xmm0, xmm1, dword ptr [rip + .LCPI3_0]{1to4}
kmovd k1, eax
vmovss xmm1 {k1}, xmm1, xmm0
vmovaps xmm0, xmm1
ret
.LCPI4_0:
.long 0x80000000
copysign5:
vmovd eax, xmm1
vmovd ecx, xmm0
vpxord xmm0, xmm1, dword ptr [rip + .LCPI4_0]{1to4}
xor eax, ecx
sets al
kmovd k1, eax
vmovss xmm1 {k1}, xmm1, xmm0
vmovaps xmm0, xmm1
ret
.LCPI5_0:
.long 0x80000000
copysign6:
vmovd eax, xmm0
vmovd ecx, xmm1
vpxord xmm0, xmm1, dword ptr [rip + .LCPI5_0]{1to4}
xor eax, ecx
sets al
kmovd k1, eax
vmovss xmm0 {k1}, xmm0, xmm1
ret
.LCPI6_0:
.long 0x80000000
copysign7:
vmovd eax, xmm0
vmovd ecx, xmm1
xor eax, ecx
sets al
vpxord xmm0, xmm1, dword ptr [rip + .LCPI6_0]{1to4}
kmovd k1, eax
vmovss xmm0 {k1}, xmm0, xmm1
ret
.LCPI7_0:
.long 0x80000000
copysign8:
vmovd eax, xmm0
vmovd ecx, xmm1
xor eax, ecx
sets al
vpxord xmm0, xmm1, dword ptr [rip + .LCPI7_0]{1to4}
kmovd k1, eax
vmovss xmm0 {k1}, xmm0, xmm1
ret
.LCPI8_0:
.long 0x80000000
copysign9:
vmovd eax, xmm0
vmovd ecx, xmm1
vpxord xmm0, xmm1, dword ptr [rip + .LCPI8_0]{1to4}
xor eax, ecx
sets al
kmovd k1, eax
vmovss xmm0 {k1}, xmm0, xmm1
ret
```
https://godbolt.org/z/PEK59azfP
Contributor guide
Assessment
This issue has not been assessed yet.