https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80517

Matthias Kretz <kretz at kde dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|8.0                         |9.0

--- Comment #3 from Matthias Kretz <kretz at kde dot org> ---
GCC 9 almost resolves this. However, for some reason this extended test case is
not fully optimized: https://gcc.godbolt.org/z/jRrHth
i.e. the call to dont_call_me() should be eliminated as dead code

#include <x86intrin.h>

inline __m128i cmp(__m128i x, __m128i y) {
    return _mm_cmpeq_epi16(x, y);
}
inline unsigned to_bits(__m128i mask0) {
    return _pext_u32(_mm_movemask_epi8(mask0), 0xaaaa);
}

inline __m128i to_vmask(unsigned bits) {
    __m128i mask = _mm_set1_epi16(bits);
    mask = _mm_and_si128(mask, _mm_setr_epi16(1, 2, 4, 8, 16, 32, 64, 128));
    mask = _mm_cmpeq_epi16(mask, _mm_setzero_si128());
    mask = _mm_xor_si128(mask, _mm_cmpeq_epi16(mask, mask));
    return mask;
}

inline bool is_eq(unsigned bits, __m128i vmask) {
    return to_bits(vmask) == bits;
}

extern const auto a = __m128i{0x0001'0002'0004'0003, 0x0009'0008'0007'0006};
extern const auto b = __m128i{0x0001'0002'0005'0003, 0x0000'0008'0007'0006};
extern const auto c = cmp(a, b);
extern const auto d = to_bits(c);

void call_me();
void dont_call_me();
void f() {
    if (is_eq(d, cmp(b, a))) {
        call_me();
    } else {
        dont_call_me();
    }
}

Reply via email to