[InstCombine] relax use constraint for min/max (~a, ~b) --> ~min/max(a, b)

In the minimal case, this won't remove instructions, but it still improves
uses of existing values.

In the motivating example from PR35834, it does remove instructions, and
sets that case up to be optimized by something like D41603:
https://reviews.llvm.org/D41603

llvm-svn: 321936
This commit is contained in:
Sanjay Patel 2018-01-06 17:34:22 +00:00
parent f7e775291e
commit 26a6fcde83
2 changed files with 11 additions and 13 deletions

View File

@ -1555,8 +1555,8 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
// MAX(~a, ~b) -> ~MIN(a, b)
// MIN(~a, ~b) -> ~MAX(a, b)
Value *A, *B;
if (match(LHS, m_Not(m_Value(A))) && LHS->getNumUses() <= 2 &&
match(RHS, m_Not(m_Value(B))) && RHS->getNumUses() <= 2) {
if (match(LHS, m_Not(m_Value(A))) && match(RHS, m_Not(m_Value(B))) &&
(LHS->getNumUses() <= 2 || RHS->getNumUses() <= 2)) {
CmpInst::Predicate InvertedPred =
getCmpPredicateForMinMax(getInverseMinMaxSelectPattern(SPF));
Value *InvertedCmp = Builder.CreateICmp(InvertedPred, A, B);

View File

@ -47,9 +47,9 @@ declare void @extra_use(i8)
define i8 @umin_not_1_extra_use(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_not_1_extra_use(
; CHECK-NEXT: [[NX:%.*]] = xor i8 %x, -1
; CHECK-NEXT: [[NY:%.*]] = xor i8 %y, -1
; CHECK-NEXT: [[CMPXY:%.*]] = icmp ult i8 [[NX]], [[NY]]
; CHECK-NEXT: [[MINXY:%.*]] = select i1 [[CMPXY]], i8 [[NX]], i8 [[NY]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 %x, %y
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 %x, i8 %y
; CHECK-NEXT: [[MINXY:%.*]] = xor i8 [[TMP2]], -1
; CHECK-NEXT: call void @extra_use(i8 [[NX]])
; CHECK-NEXT: ret i8 [[MINXY]]
;
@ -84,15 +84,13 @@ define i8 @umin_not_2_extra_use(i8 %x, i8 %y) {
define i8 @umin3_not(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @umin3_not(
; CHECK-NEXT: [[NX:%.*]] = xor i8 %x, -1
; CHECK-NEXT: [[NY:%.*]] = xor i8 %y, -1
; CHECK-NEXT: [[NZ:%.*]] = xor i8 %z, -1
; CHECK-NEXT: [[CMPYX:%.*]] = icmp ult i8 %y, %x
; CHECK-NEXT: [[CMPXZ:%.*]] = icmp ult i8 [[NX]], [[NZ]]
; CHECK-NEXT: [[MINXZ:%.*]] = select i1 [[CMPXZ]], i8 [[NX]], i8 [[NZ]]
; CHECK-NEXT: [[CMPYZ:%.*]] = icmp ult i8 [[NY]], [[NZ]]
; CHECK-NEXT: [[MINYZ:%.*]] = select i1 [[CMPYZ]], i8 [[NY]], i8 [[NZ]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMPYX]], i8 [[MINXZ]], i8 [[MINYZ]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 %x, %z
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 %x, i8 %z
; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i8 %y, %z
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i8 %y, i8 %z
; CHECK-NEXT: [[R_V:%.*]] = select i1 [[CMPYX]], i8 [[TMP2]], i8 [[TMP4]]
; CHECK-NEXT: [[R:%.*]] = xor i8 [[R:%.*]].v, -1
; CHECK-NEXT: ret i8 [[R]]
;
%nx = xor i8 %x, -1