This is a fix for PR22723:
https://llvm.org/bugs/show_bug.cgi?id=22723
My first attempt at this was to change what I thought was the root problem:
xor (zext i1 X to i32), 1 --> zext (xor i1 X, true) to i32
...but we create the opposite pattern in InstCombiner::visitZExt(), so infinite loop!
My next idea was to fix the matchIfNot() implementation in PatternMatch, but that would mean potentially returning a different size for the match than what was input. I think this would require all users of m_Not to check the size of the returned match, so I abandoned that idea.
I settled on just fixing the exact case presented in the PR. I hope this limited patch is acceptable if not the most general. It does allow the 2 functions in PR22723 to compile identically (x86):
bool test(bool x, bool y) { return !x | !y; } bool test(bool x, bool y) { return !x || !y; } ... andb %sil, %dil xorb $1, %dil movb %dil, %al retq
Do you need to check if C1 fits in an uint64_t? Or is that checked earlier?
Actually, I think it'll be easier to just use C1->isOne().