Issue 100875
Summary Suboptimal codegen for `std::midpoint`
Labels missed-optimization
Assignees
Reporter Kmeakin
    https://godbolt.org/z/dx5TY9WxY

The reference implementation of `std::midpoint` provided in [P0811R3](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0811r3.html) produces better assembly than either libc++'s or libstdc++'s implementations, at least for u32, i32, u64 and i64. For u8, i8, u16 and i16, LLVM is unable to remove the unnecessary extensions and truncations

```c++
// taken from https://github.com/llvm/llvm-project/blob/main/libcxx/include/__numeric/midpoint.h#L36
template <typename T>
T libcpp(T a, T b) {
    using U = std::make_unsigned_t<T>;
    constexpr U bitshift = std::numeric_limits<U>::digits - 1;

    U diff = U(b) - U(a);
    U sign_bit = b < a;

    U half_diff = (diff / 2) + (sign_bit << bitshift) + (sign_bit & diff);

    return a + half_diff;
}

// taken from https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/numeric#L217
template <typename T>
T libstdcpp(T a, T b) {
    using U = std::make_unsigned_t<T>;

    int k = 1;
    U m = a;
    U M = b;
    if (a > b) {
        k = -1;
        m = b;
        M = a;
    }
    return a + k * T(U(M - m) / 2);
}

// taken from https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0811r3.html
template <typename Integer>
Integer P0811R3(Integer a, Integer b) noexcept {
 using U = std::make_unsigned_t<Integer>;
    U x = a - (U(a) - b) / 2;
 U y = a + (U(b) - a) / 2;
    return a > b ? x : y;
}
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to