[PATCH] D32725: [InstCombine] Apply deMorgan to (and/or (not cmp1), cmp2) when cmp1 has multiple uses, but cmp2 has a single use
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 3 15:57:10 PDT 2017
spatel added a comment.
In https://reviews.llvm.org/D32725#744881, @craig.topper wrote:
> should we also lift the one use check for compares in IsFreeToInvert?
Yes, I think that makes sense. @efriedma - do you foresee problems?
I forgot that I already filed this bug that will result if we lift the one-use restriction for // xor (cmp A, B), true = not (cmp A, B) = !cmp A, B :
https://bugs.llvm.org/show_bug.cgi?id=32791
> What about floating point compares? We probably don't have as many folds for them.
IMO, it's just a bonus that we have lots of icmp folds. The main reason we should not care about uses for these folds is that we always reduce the dependency chain by inverting the predicate. If we're missing folds based on inverted predicates, we can add those (and might need to do that first to avoid regressions). If either icmp or fcmp is less efficient than 'not' for some target, then it can invert this in the backend.
Examples:
declare void @bar(i1, i1)
define void @icmp_neg(i8 %a) {
%cmp = icmp eq i8 %a, 1
%neg = xor i1 %cmp, -1 <--- must wait for cmp
call void @bar(i1 %cmp, i1 %neg)
ret void
}
define void @icmp_inv(i8 %a) {
%cmp = icmp eq i8 %a, 1
%neg = icmp ne i8 %a, 1 <--- can execute immediately
call void @bar(i1 %cmp, i1 %neg)
ret void
}
define void @fcmp_neg(float %a) {
%cmp = fcmp oeq float %a, 1.0
%neg = xor i1 %cmp, -1
call void @bar(i1 %cmp, i1 %neg)
ret void
}
define void @fcmp_inv(float %a) {
%cmp = fcmp oeq float %a, 1.0
%neg = fcmp une float %a, 1.0
call void @bar(i1 %cmp, i1 %neg)
ret void
}
https://reviews.llvm.org/D32725
More information about the llvm-commits
mailing list