[PATCH] D33172: [InstCombine] Simpify inverted predicates in 'or'
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 15 10:01:25 PDT 2017
spatel added a comment.
The problem may be more general than that. It's really about recognizing inverted compares, so let's take selects out of the equation (using div ops to thwart hoisting/sinking here, but that's just to produce a minimal IR example):
define i32 @inverted_compares(i32 %a, i32 %b, i32 %c) {
entry:
%cmp = icmp slt i32 %a, %b
br i1 %cmp, label %t1, label %f1
t1:
%div1 = sdiv i32 42, %c
br label %endif1
f1:
%div2 = srem i32 43, %c
br label %endif1
endif1:
%phi1 = phi i32 [ %div1, %t1 ], [ %div2, %f1 ]
%cmpnot = icmp sge i32 %a, %b
br i1 %cmpnot, label %t2, label %f2
t2:
%div3 = sdiv i32 44, %phi1
br label %endif2
f2:
%div4 = srem i32 45, %phi1
br label %endif2
endif2:
%phi2 = phi i32 [ %div3, %t2 ], [ %div4, %f2 ]
%call = call i32 @bar(i32 %phi1, i32 %phi2)
ret i32 %call
}
Because of instcombine predicate canonicalization rules, we optimize this to one compare:
define i32 @inverted_compares_optimized(i32 %a, i32 %b, i32 %c) {
entry:
%cmp = icmp slt i32 %a, %b
br i1 %cmp, label %f2, label %t2
t2:
%div2 = srem i32 43, %c
%div3 = udiv i32 44, %div2
br label %endif2
f2:
%div1 = sdiv i32 42, %c
%div4 = srem i32 45, %div1
br label %endif2
endif2:
%phi12 = phi i32 [ %div2, %t2 ], [ %div1, %f2 ]
%phi2 = phi i32 [ %div3, %t2 ], [ %div4, %f2 ]
%call = tail call i32 @bar(i32 %phi12, i32 %phi2)
ret i32 %call
}
But if the compare has an extra use, the instcombine doesn't fire, and this won't optimize at -O2:
define i32 @inverted_compares_and_one(i32 %a, i32 %b, i32 %c) {
entry:
%cmp = icmp slt i32 %a, %b
br i1 %cmp, label %t1, label %f1
t1:
%div1 = sdiv i32 42, %c
br label %endif1
f1:
%div2 = srem i32 43, %c
br label %endif1
endif1:
%phi1 = phi i32 [ %div1, %t1 ], [ %div2, %f1 ]
%cmpnot = icmp sge i32 %a, %b
br i1 %cmpnot, label %t2, label %f2
t2:
%div3 = sdiv i32 44, %phi1
br label %endif2
f2:
%div4 = srem i32 45, %phi1
br label %endif2
endif2:
%phi2 = phi i32 [ %div3, %t2 ], [ %div4, %f2 ]
%call = call i32 @bar_extra_cmp_use(i32 %phi1, i32 %phi2, i1 %cmpnot)
ret i32 %call
}
We could have gotten this to:
define i32 @inverted_compares_optimized(i32 %a, i32 %b, i32 %c) {
entry:
%cmp = icmp slt i32 %a, %b
br i1 %cmp, label %f2, label %t2
t2:
%div2 = srem i32 43, %c
%div3 = udiv i32 44, %div2
br label %endif2
f2:
%div1 = sdiv i32 42, %c
%div4 = srem i32 45, %div1
br label %endif2
endif2:
%phi12 = phi i32 [ %div2, %t2 ], [ %div1, %f2 ]
%phi2 = phi i32 [ %div3, %t2 ], [ %div4, %f2 ]
%cmpnot = icmp sge i32 %a, %b
%call = call i32 @bar_extra_cmp_use(i32 %phi1, i32 %phi2, i1 %cmpnot)
ret i32 %call
}
https://reviews.llvm.org/D33172
More information about the llvm-commits
mailing list