[llvm-dev] failing to optimize boolean ops on cmps
Sanjay Patel via llvm-dev
llvm-dev at lists.llvm.org
Thu Jul 13 14:12:21 PDT 2017
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:
define i8 @or_and_not(i8 %a, i8 %b) {
%nota = xor i8 %a, -1
%and = and i8 %nota, %b
%res = or i8 %and, %a
ret i8 %res
}
define i1 @or_and_cmp_not(i32 %a, i32 %b, i1 %c) {
%cmp = icmp sgt i32 %a, %b
%cmp_inv = icmp sle i32 %a, %b ; this is 'not' of %cmp
%and = and i1 %c, %cmp_inv
%res = or i1 %cmp, %and
ret i1 %res
}
$ ./opt -instcombine hidden_not.ll -S
define i8 @or_and_not(i8 %a, i8 %b) {
%res = or i8 %b, %a
ret i8 %res
}
define i1 @or_and_cmp_not(i32 %a, i32 %b, i1 %c) {
%cmp = icmp sgt i32 %a, %b
%cmp_inv = icmp sle i32 %a, %b
%and = and i1 %cmp_inv, %c
%res = or i1 %cmp, %and
ret i1 %res
}
---------------------------------------------------------------------
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:
// ((~A & B) | A) -> (A | B)
if (match(Op0, m_c_And(m_Not(m_Specific(Op1)), m_Value(A))))
return BinaryOperator::CreateOr(A, Op1);
Is there a way to make "m_Not(m_Specific())" match an inverted compare?
This optimization hole can manifest in strange ways:
https://godbolt.org/g/gjpAVo
We got it right for C++, but C managed to fall through the cracks!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170713/d96f9cef/attachment.html>
More information about the llvm-dev
mailing list