<div dir="ltr"><div><div><div><div>We have several optimizations in InstCombine for bitwise logic ops (and/or/xor) that fail to handle compare patterns with the equivalent bitwise logic. Example:<br><br>define i8 @or_and_not(i8 %a, i8 %b) {<br>  %nota = xor i8 %a, -1<br>  %and = and i8 %nota, %b<br>  %res = or i8 %and, %a<br>  ret i8 %res<br>}<br><br>define i1 @or_and_cmp_not(i32 %a, i32 %b, i1 %c) {<br>  %cmp = icmp sgt i32 %a, %b<br>  %cmp_inv = icmp sle i32 %a, %b ; this is 'not' of %cmp<br>  %and = and i1 %c, %cmp_inv<br>  %res = or i1 %cmp, %and<br>  ret i1 %res<br>}<br><br>$ ./opt -instcombine hidden_not.ll -S<br><br>define i8 @or_and_not(i8 %a, i8 %b) {<br>  %res = or i8 %b, %a<br>  ret i8 %res<br>}<br><br>define i1 @or_and_cmp_not(i32 %a, i32 %b, i1 %c) {<br>  %cmp = icmp sgt i32 %a, %b<br>  %cmp_inv = icmp sle i32 %a, %b<br>  %and = and i1 %cmp_inv, %c<br>  %res = or i1 %cmp, %and<br>  ret i1 %res<br>}<br><br>---------------------------------------------------------------------<br></div><br>Would adding to the existing InstCombine logic folds to handle this kind of pattern be a welcome enhancement? I don't know if it's possible to make the matchers handle this case without adding a new matcher. Eg:<br><br>  // ((~A & B) | A) -> (A | B)<br>  if (match(Op0, m_c_And(m_Not(m_Specific(Op1)), m_Value(A))))<br>    return BinaryOperator::CreateOr(A, Op1);<br><br></div>Is there a way to make "m_Not(m_Specific())" match an inverted compare?<br><br></div>This optimization hole can manifest in strange ways:<br><a href="https://godbolt.org/g/gjpAVo">https://godbolt.org/g/gjpAVo</a><br><br></div>We got it right for C++, but C managed to fall through the cracks!<br></div>