forked from OSchip/llvm-project
[ValueTracking] fix matchSelectPattern to allow vector splat folds of min/max/abs/nabs
llvm-svn: 285303
This commit is contained in:
parent
0eae9eccdf
commit
e372aecb8a
|
@ -3951,27 +3951,29 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConstantInt *C1 = dyn_cast<ConstantInt>(CmpRHS)) {
|
const APInt *C1;
|
||||||
|
if (match(CmpRHS, m_APInt(C1))) {
|
||||||
if ((CmpLHS == TrueVal && match(FalseVal, m_Neg(m_Specific(CmpLHS)))) ||
|
if ((CmpLHS == TrueVal && match(FalseVal, m_Neg(m_Specific(CmpLHS)))) ||
|
||||||
(CmpLHS == FalseVal && match(TrueVal, m_Neg(m_Specific(CmpLHS))))) {
|
(CmpLHS == FalseVal && match(TrueVal, m_Neg(m_Specific(CmpLHS))))) {
|
||||||
|
|
||||||
// ABS(X) ==> (X >s 0) ? X : -X and (X >s -1) ? X : -X
|
// ABS(X) ==> (X >s 0) ? X : -X and (X >s -1) ? X : -X
|
||||||
// NABS(X) ==> (X >s 0) ? -X : X and (X >s -1) ? -X : X
|
// NABS(X) ==> (X >s 0) ? -X : X and (X >s -1) ? -X : X
|
||||||
if (Pred == ICmpInst::ICMP_SGT && (C1->isZero() || C1->isMinusOne())) {
|
if (Pred == ICmpInst::ICMP_SGT && (*C1 == 0 || C1->isAllOnesValue())) {
|
||||||
return {(CmpLHS == TrueVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
|
return {(CmpLHS == TrueVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ABS(X) ==> (X <s 0) ? -X : X and (X <s 1) ? -X : X
|
// ABS(X) ==> (X <s 0) ? -X : X and (X <s 1) ? -X : X
|
||||||
// NABS(X) ==> (X <s 0) ? X : -X and (X <s 1) ? X : -X
|
// NABS(X) ==> (X <s 0) ? X : -X and (X <s 1) ? X : -X
|
||||||
if (Pred == ICmpInst::ICMP_SLT && (C1->isZero() || C1->isOne())) {
|
if (Pred == ICmpInst::ICMP_SLT && (*C1 == 0 || *C1 == 1)) {
|
||||||
return {(CmpLHS == FalseVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
|
return {(CmpLHS == FalseVal) ? SPF_ABS : SPF_NABS, SPNB_NA, false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Y >s C ? ~Y : ~C == ~Y <s ~C ? ~Y : ~C = SMIN(~Y, ~C)
|
// Y >s C ? ~Y : ~C == ~Y <s ~C ? ~Y : ~C = SMIN(~Y, ~C)
|
||||||
if (const auto *C2 = dyn_cast<ConstantInt>(FalseVal)) {
|
const APInt *C2;
|
||||||
if (Pred == ICmpInst::ICMP_SGT && C1->getType() == C2->getType() &&
|
if (match(FalseVal, m_APInt(C2))) {
|
||||||
~C1->getValue() == C2->getValue() &&
|
if (Pred == ICmpInst::ICMP_SGT &&
|
||||||
|
CmpRHS->getType() == FalseVal->getType() && ~(*C1) == *C2 &&
|
||||||
(match(TrueVal, m_Not(m_Specific(CmpLHS))) ||
|
(match(TrueVal, m_Not(m_Specific(CmpLHS))) ||
|
||||||
match(CmpLHS, m_Not(m_Specific(TrueVal))))) {
|
match(CmpLHS, m_Not(m_Specific(TrueVal))))) {
|
||||||
LHS = TrueVal;
|
LHS = TrueVal;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||||
|
|
||||||
define i32 @abs_abs_x01(i32 %x) {
|
define i32 @abs_abs_x01(i32 %x) {
|
||||||
|
@ -16,16 +15,12 @@ define i32 @abs_abs_x01(i32 %x) {
|
||||||
; CHECK-NEXT: ret i32 [[SEL]]
|
; CHECK-NEXT: ret i32 [[SEL]]
|
||||||
}
|
}
|
||||||
|
|
||||||
; FIXME - vectors should get the same folds
|
|
||||||
define <2 x i32> @abs_abs_x01_vec(<2 x i32> %x) {
|
define <2 x i32> @abs_abs_x01_vec(<2 x i32> %x) {
|
||||||
; CHECK-LABEL: @abs_abs_x01_vec(
|
; CHECK-LABEL: @abs_abs_x01_vec(
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %x
|
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %x
|
||||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> %x, <2 x i32> [[SUB]]
|
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> %x, <2 x i32> [[SUB]]
|
||||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt <2 x i32> [[COND]], <i32 -1, i32 -1>
|
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||||
; CHECK-NEXT: [[SUB16:%.*]] = sub nsw <2 x i32> zeroinitializer, [[COND]]
|
|
||||||
; CHECK-NEXT: [[COND18:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[COND]], <2 x i32> [[SUB16]]
|
|
||||||
; CHECK-NEXT: ret <2 x i32> [[COND18]]
|
|
||||||
;
|
;
|
||||||
%cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
%cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
||||||
%sub = sub nsw <2 x i32> zeroinitializer, %x
|
%sub = sub nsw <2 x i32> zeroinitializer, %x
|
||||||
|
@ -81,16 +76,12 @@ define i32 @abs_abs_x04(i32 %x) {
|
||||||
; CHECK-NEXT: ret i32 [[SEL]]
|
; CHECK-NEXT: ret i32 [[SEL]]
|
||||||
}
|
}
|
||||||
|
|
||||||
; FIXME - vectors should get the same folds
|
|
||||||
define <2 x i32> @abs_abs_x04_vec(<2 x i32> %x) {
|
define <2 x i32> @abs_abs_x04_vec(<2 x i32> %x) {
|
||||||
; CHECK-LABEL: @abs_abs_x04_vec(
|
; CHECK-LABEL: @abs_abs_x04_vec(
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> %x, <i32 1, i32 1>
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> %x, <i32 1, i32 1>
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %x
|
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %x
|
||||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> %x
|
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> %x
|
||||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt <2 x i32> [[COND]], <i32 -1, i32 -1>
|
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||||
; CHECK-NEXT: [[SUB16:%.*]] = sub nsw <2 x i32> zeroinitializer, [[COND]]
|
|
||||||
; CHECK-NEXT: [[COND18:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[COND]], <2 x i32> [[SUB16]]
|
|
||||||
; CHECK-NEXT: ret <2 x i32> [[COND18]]
|
|
||||||
;
|
;
|
||||||
%cmp = icmp slt <2 x i32> %x, <i32 1, i32 1>
|
%cmp = icmp slt <2 x i32> %x, <i32 1, i32 1>
|
||||||
%sub = sub nsw <2 x i32> zeroinitializer, %x
|
%sub = sub nsw <2 x i32> zeroinitializer, %x
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||||
|
|
||||||
; PR1822
|
; PR1822
|
||||||
|
@ -1724,15 +1723,9 @@ define i32 @test_max_of_min(i32 %a) {
|
||||||
ret i32 %s1
|
ret i32 %s1
|
||||||
}
|
}
|
||||||
|
|
||||||
; FIXME - vectors should get the same folds
|
|
||||||
define <2 x i32> @test_max_of_min_vec(<2 x i32> %a) {
|
define <2 x i32> @test_max_of_min_vec(<2 x i32> %a) {
|
||||||
; CHECK-LABEL: @test_max_of_min_vec(
|
; CHECK-LABEL: @test_max_of_min_vec(
|
||||||
; CHECK-NEXT: [[NOT_A:%.*]] = xor <2 x i32> %a, <i32 -1, i32 -1>
|
; CHECK-NEXT: ret <2 x i32> <i32 -1, i32 -1>
|
||||||
; CHECK-NEXT: [[C0:%.*]] = icmp sgt <2 x i32> %a, zeroinitializer
|
|
||||||
; CHECK-NEXT: [[S0:%.*]] = select <2 x i1> [[C0]], <2 x i32> [[NOT_A]], <2 x i32> <i32 -1, i32 -1>
|
|
||||||
; CHECK-NEXT: [[C1:%.*]] = icmp sgt <2 x i32> [[S0]], <i32 -1, i32 -1>
|
|
||||||
; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[C1]], <2 x i32> [[S0]], <2 x i32> <i32 -1, i32 -1>
|
|
||||||
; CHECK-NEXT: ret <2 x i32> [[S1]]
|
|
||||||
;
|
;
|
||||||
%not_a = xor <2 x i32> %a, <i32 -1, i32 -1>
|
%not_a = xor <2 x i32> %a, <i32 -1, i32 -1>
|
||||||
%c0 = icmp sgt <2 x i32> %a, zeroinitializer
|
%c0 = icmp sgt <2 x i32> %a, zeroinitializer
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||||
|
|
||||||
define i32 @foo(i32) local_unnamed_addr #0 {
|
define i32 @foo(i32) local_unnamed_addr #0 {
|
||||||
|
@ -81,16 +80,12 @@ define i32 @abs_nabs_x01(i32 %x) {
|
||||||
; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]], !prof ![[MD1]]
|
; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]], !prof ![[MD1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
; FIXME - vectors should get the same folds
|
|
||||||
define <2 x i32> @abs_nabs_x01_vec(<2 x i32> %x) {
|
define <2 x i32> @abs_nabs_x01_vec(<2 x i32> %x) {
|
||||||
; CHECK-LABEL: @abs_nabs_x01_vec(
|
; CHECK-LABEL: @abs_nabs_x01_vec(
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %x
|
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, %x
|
||||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> %x, !prof !0
|
; CHECK-NEXT: [[COND1:%.*]] = select <2 x i1> [[CMP]], <2 x i32> %x, <2 x i32> [[SUB]], !prof ![[MD1]]
|
||||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt <2 x i32> [[COND]], <i32 -1, i32 -1>
|
; CHECK-NEXT: ret <2 x i32> [[COND1]]
|
||||||
; CHECK-NEXT: [[SUB16:%.*]] = sub nsw <2 x i32> zeroinitializer, [[COND]]
|
|
||||||
; CHECK-NEXT: [[COND18:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[COND]], <2 x i32> [[SUB16]], !prof !2
|
|
||||||
; CHECK-NEXT: ret <2 x i32> [[COND18]]
|
|
||||||
;
|
;
|
||||||
%cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
%cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
|
||||||
%sub = sub nsw <2 x i32> zeroinitializer, %x
|
%sub = sub nsw <2 x i32> zeroinitializer, %x
|
||||||
|
|
Loading…
Reference in New Issue