llvm / llvm/llvm-project

[AArch64] `(fabs(a) >= fabs(b)) ? -1 : 0` => `facge`

Open
#217,666 2 comments 0 reactions 1 assignee Claimed by @Bagodiya View on GitHub
backend:AArch64 missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Clang is able to perform this optimization for `src16x4`, `src16x8`, `src32x2`, `src32x4` and `src64x2`, but not for `src16`, `src32`, `src64` or `src64x1`.

https://godbolt.org/z/v15hMzKvr

```c++
#include
#include

#define fabs __builtin_fabs

uint16_t src16(float16_t a, float16_t b) {
return (fabs(a) >= fabs(b)) ? -1 : 0;
}

uint32_t src32(float32_t a, float32_t b) {
return (fabs(a) >= fabs(b)) ? -1 : 0;
}

uint64_t src64(float64_t a, float64_t b) {
return (fabs(a) >= fabs(b)) ? -1 : 0;
}

uint16x4_t src16x4(float16x4_t a, float16x4_t b) {
return vabs_f16(a) >= vabs_f16(b);
}

uint16x8_t src16x8(float16x8_t a, float16x8_t b) {
return vabsq_f16(a) >= vabsq_f16(b);
}

uint32x2_t src32x2(float32x2_t a, float32x2_t b) {
return vabs_f32(a) >= vabs_f32(b);
}

uint32x4_t src32x4(float32x4_t a, float32x4_t b) {
return vabsq_f32(a) >= vabsq_f32(b);
}

uint64x1_t src64x1(float64x1_t a, float64x1_t b) {
return vabs_f64(a) >= vabs_f64(b);
}

uint64x2_t src64x2(float64x2_t a, float64x2_t b) {
return vabsq_f64(a) >= vabsq_f64(b);
}

uint16_t tgt16(float16_t a, float16_t b) { return vcageh_f16(a, b); }
uint32_t tgt32(float32_t a, float32_t b) { return vcages_f32(a, b); }
uint64_t tgt64(float64_t a, float64_t b) { return vcaged_f64(a, b); }
uint16x4_t tgt1616x4(float16x4_t a, float16x4_t b) { return vcage_f16(a, b); }
uint16x8_t tgt16x8(float16x8_t a, float16x8_t b) { return vcageq_f16(a, b); }
uint32x2_t tgt32x2(float32x2_t a, float32x2_t b) { return vcage_f32(a, b); }
uint32x4_t tgt32x4(float32x4_t a, float32x4_t b) { return vcageq_f32(a, b); }
uint64x1_t tgt64x1(float64x1_t a, float64x1_t b) { return vcage_f64(a, b); }
uint64x2_t tgt64x2(float64x2_t a, float64x2_t b) { return vcageq_f64(a, b); }
```

Assembly:
```asm
src16(half, half):
fabs h0, h0
fabs h1, h1
fcmp h0, h1
csetm w0, ge
ret

src32(float, float):
fabs s0, s0
fabs s1, s1
fcmp s0, s1
csetm w0, ge
ret

src64(double, double):
fabs d0, d0
fabs d1, d1
fcmp d0, d1
csetm x0, ge
ret

src16x4(__Float16x4_t, __Float16x4_t):
facge v0.4h, v0.4h, v1.4h
ret

src16x8(__Float16x8_t, __Float16x8_t):
facge v0.8h, v0.8h, v1.8h
ret

src32x2(__Float32x2_t, __Float32x2_t):
facge v0.2s, v0.2s, v1.2s
ret

src32x4(__Float32x4_t, __Float32x4_t):
facge v0.4s, v0.4s, v1.4s
ret

src64x1(__Float64x1_t, __Float64x1_t):
fabs d0, d0
fabs d1, d1
fcmge d0, d0, d1
ret

src64x2(__Float64x2_t, __Float64x2_t):
facge v0.2d, v0.2d, v1.2d
ret

tgt16(half, half):
facge h0, h0, h1
fmov w0, s0
ret

tgt32(float, float):
facge s0, s0, s1
fmov w0, s0
ret

tgt64(double, double):
facge d0, d0, d1
fmov x0, d0
ret

tgt1616x4(__Float16x4_t, __Float16x4_t):
facge v0.4h, v0.4h, v1.4h
ret

tgt16x8(__Float16x8_t, __Float16x8_t):
facge v0.8h, v0.8h, v1.8h
ret

tgt32x2(__Float32x2_t, __Float32x2_t):
facge v0.2s, v0.2s, v1.2s
ret

tgt32x4(__Float32x4_t, __Float32x4_t):
facge v0.4s, v0.4s, v1.4s
ret

tgt64x1(__Float64x1_t, __Float64x1_t):
facge d0, d0, d1
ret

tgt64x2(__Float64x2_t, __Float64x2_t):
facge v0.2d, v0.2d, v1.2d
ret
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.