Open davidbolvansky opened 3 years ago
I don't think this fold should be performed in the middle end at all, as it breaks canonical comparison structure. I'm handling this special pattern in LVI, but many other places reasoning about conditions don't.
We should fold this in DAG instead.
Looks very similar to bug 51577
LLVM 14 fixed the regression.
Extended Description
x < C && y < C && z < C to (x | y | z) < C where C is power of two.
bool src1 (unsigned x, unsigned y, unsigned z, unsigned w) { return x < 1024 && y < 1024 && z < 1024 && w < 1024; }
bool tgt1 (unsigned x, unsigned y, unsigned z, unsigned w) { return (x | y | z | w) < 1024; }
GCC: src1(unsigned int, unsigned int, unsigned int, unsigned int): or edx, ecx or edx, esi or edx, edi cmp edx, 1023 setbe al ret tgt1(unsigned int, unsigned int, unsigned int, unsigned int): or edx, ecx or edx, esi or edx, edi cmp edx, 1023 setbe al ret
Clang trunk: src1(unsigned int, unsigned int, unsigned int, unsigned int): # @src1(unsigned int, unsigned int, unsigned int, unsigned int) cmp edi, 1024 setb al cmp esi, 1024 setb sil and sil, al cmp edx, 1024 setb dl cmp ecx, 1024 setb al and al, dl and al, sil ret tgt1(unsigned int, unsigned int, unsigned int, unsigned int): # @tgt1(unsigned int, unsigned int, unsigned int, unsigned int) or edi, esi or edx, ecx or edx, edi cmp edx, 1024 setb al ret
Regressed with LLVM 13 which disabled select-to-or optimization.