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();
}
}