forked from OSchip/llvm-project
[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:
parent
f7e775291e
commit
26a6fcde83
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue