[llvm] 861adaf - [InstCombine] Support splat vectors in some and of icmp folds
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 10 13:40:39 PST 2021
Author: Nikita Popov
Date: 2021-11-10T22:37:54+01:00
New Revision: 861adaf2ad20e13df0209c39bddacd16b78e3bb2
URL: https://github.com/llvm/llvm-project/commit/861adaf2ad20e13df0209c39bddacd16b78e3bb2
DIFF: https://github.com/llvm/llvm-project/commit/861adaf2ad20e13df0209c39bddacd16b78e3bb2.diff
LOG: [InstCombine] Support splat vectors in some and of icmp folds
Replace m_ConstantInt() with m_APInt() to support splat vectors
in addition to scalar integers.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/and.ll
llvm/test/Transforms/InstCombine/and2.ll
llvm/test/Transforms/InstCombine/merge-icmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 26983cf15801..fae19549f081 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1310,19 +1310,20 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
Value *LHS0 = LHS->getOperand(0), *RHS0 = RHS->getOperand(0);
- ConstantInt *LHSC, *RHSC;
- if (!match(LHS->getOperand(1), m_ConstantInt(LHSC)) ||
- !match(RHS->getOperand(1), m_ConstantInt(RHSC)))
+ const APInt *LHSC, *RHSC;
+ if (!match(LHS->getOperand(1), m_APInt(LHSC)) ||
+ !match(RHS->getOperand(1), m_APInt(RHSC)))
return nullptr;
if (LHSC == RHSC && PredL == PredR) {
// (icmp ult A, C) & (icmp ult B, C) --> (icmp ult (A|B), C)
// where C is a power of 2 or
// (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0)
- if ((PredL == ICmpInst::ICMP_ULT && LHSC->getValue().isPowerOf2()) ||
+ if ((PredL == ICmpInst::ICMP_ULT && LHSC->isPowerOf2()) ||
(PredL == ICmpInst::ICMP_EQ && LHSC->isZero())) {
Value *NewOr = Builder.CreateOr(LHS0, RHS0);
- return Builder.CreateICmp(PredL, NewOr, LHSC);
+ return Builder.CreateICmp(PredL, NewOr,
+ ConstantInt::get(NewOr->getType(), *LHSC));
}
}
@@ -1332,38 +1333,36 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
if (PredL == ICmpInst::ICMP_EQ && PredL == PredR && LHS->hasOneUse() &&
RHS->hasOneUse()) {
Value *V;
- ConstantInt *AndC, *SmallC = nullptr, *BigC = nullptr;
+ const APInt *AndC, *SmallC = nullptr, *BigC = nullptr;
// (trunc x) == C1 & (and x, CA) == C2
// (and x, CA) == C2 & (trunc x) == C1
if (match(RHS0, m_Trunc(m_Value(V))) &&
- match(LHS0, m_And(m_Specific(V), m_ConstantInt(AndC)))) {
+ match(LHS0, m_And(m_Specific(V), m_APInt(AndC)))) {
SmallC = RHSC;
BigC = LHSC;
} else if (match(LHS0, m_Trunc(m_Value(V))) &&
- match(RHS0, m_And(m_Specific(V), m_ConstantInt(AndC)))) {
+ match(RHS0, m_And(m_Specific(V), m_APInt(AndC)))) {
SmallC = LHSC;
BigC = RHSC;
}
if (SmallC && BigC) {
- unsigned BigBitSize = BigC->getType()->getBitWidth();
- unsigned SmallBitSize = SmallC->getType()->getBitWidth();
+ unsigned BigBitSize = BigC->getBitWidth();
+ unsigned SmallBitSize = SmallC->getBitWidth();
// Check that the low bits are zero.
APInt Low = APInt::getLowBitsSet(BigBitSize, SmallBitSize);
- if ((Low & AndC->getValue()).isZero() &&
- (Low & BigC->getValue()).isZero()) {
- Value *NewAnd = Builder.CreateAnd(V, Low | AndC->getValue());
- APInt N = SmallC->getValue().zext(BigBitSize) | BigC->getValue();
- Value *NewVal = ConstantInt::get(AndC->getType()->getContext(), N);
+ if ((Low & *AndC).isZero() && (Low & *BigC).isZero()) {
+ Value *NewAnd = Builder.CreateAnd(V, Low | *AndC);
+ APInt N = SmallC->zext(BigBitSize) | *BigC;
+ Value *NewVal = ConstantInt::get(NewAnd->getType(), N);
return Builder.CreateICmp(PredL, NewAnd, NewVal);
}
}
}
- return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHSC->getValue(),
- PredR, RHS0, RHSC->getValue(),
+ return foldAndOrOfICmpsUsingRanges(PredL, LHS0, *LHSC, PredR, RHS0, *RHSC,
Builder, /* IsAnd */ true);
}
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index 0e25d2d47103..392d752e40a7 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -307,13 +307,10 @@ define i1 @test23_logical(i32 %A) {
ret i1 %D
}
-; FIXME: Vectors should fold too.
define <2 x i1> @test23vec(<2 x i32> %A) {
; CHECK-LABEL: @test23vec(
-; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i32> [[A:%.*]], <i32 1, i32 1>
-; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A]], <i32 3, i32 3>
-; CHECK-NEXT: [[D:%.*]] = and <2 x i1> [[B]], [[C]]
-; CHECK-NEXT: ret <2 x i1> [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 2, i32 2>
+; CHECK-NEXT: ret <2 x i1> [[TMP1]]
;
%B = icmp sgt <2 x i32> %A, <i32 1, i32 1>
%C = icmp sle <2 x i32> %A, <i32 2, i32 2>
@@ -369,13 +366,11 @@ define i1 @test25_logical(i32 %A) {
ret i1 %D
}
-; FIXME: Vectors should fold too.
define <2 x i1> @test25vec(<2 x i32> %A) {
; CHECK-LABEL: @test25vec(
-; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i32> [[A:%.*]], <i32 49, i32 49>
-; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A]], <i32 100, i32 100>
-; CHECK-NEXT: [[D:%.*]] = and <2 x i1> [[B]], [[C]]
-; CHECK-NEXT: ret <2 x i1> [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], <i32 -50, i32 -50>
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 50, i32 50>
+; CHECK-NEXT: ret <2 x i1> [[TMP2]]
;
%B = icmp sge <2 x i32> %A, <i32 50, i32 50>
%C = icmp slt <2 x i32> %A, <i32 100, i32 100>
diff --git a/llvm/test/Transforms/InstCombine/and2.ll b/llvm/test/Transforms/InstCombine/and2.ll
index 03be031e930e..bb8776a970ee 100644
--- a/llvm/test/Transforms/InstCombine/and2.ll
+++ b/llvm/test/Transforms/InstCombine/and2.ll
@@ -83,13 +83,11 @@ define i1 @test8_logical(i32 %i) {
ret i1 %cond
}
-; FIXME: Vectors should fold too.
define <2 x i1> @test8vec(<2 x i32> %i) {
; CHECK-LABEL: @test8vec(
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i32> [[I:%.*]], zeroinitializer
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[I]], <i32 14, i32 14>
-; CHECK-NEXT: [[COND:%.*]] = and <2 x i1> [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret <2 x i1> [[COND]]
+; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[I:%.*]], <i32 -1, i32 -1>
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 13, i32 13>
+; CHECK-NEXT: ret <2 x i1> [[TMP2]]
;
%cmp1 = icmp ne <2 x i32> %i, zeroinitializer
%cmp2 = icmp ult <2 x i32> %i, <i32 14, i32 14>
diff --git a/llvm/test/Transforms/InstCombine/merge-icmp.ll b/llvm/test/Transforms/InstCombine/merge-icmp.ll
index 2a1ddf5e69f2..1202324333d8 100644
--- a/llvm/test/Transforms/InstCombine/merge-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/merge-icmp.ll
@@ -34,12 +34,8 @@ define i1 @test1_logical(i16* %x) {
define <2 x i1> @test1_vector(<2 x i16>* %x) {
; CHECK-LABEL: @test1_vector(
; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i16>, <2 x i16>* [[X:%.*]], align 4
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i16> [[LOAD]] to <2 x i8>
-; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i8> [[TRUNC]], <i8 127, i8 127>
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i16> [[LOAD]], <i16 -256, i16 -256>
-; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i16> [[AND]], <i16 17664, i16 17664>
-; CHECK-NEXT: [[OR:%.*]] = and <2 x i1> [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret <2 x i1> [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i16> [[LOAD]], <i16 17791, i16 17791>
+; CHECK-NEXT: ret <2 x i1> [[TMP1]]
;
%load = load <2 x i16>, <2 x i16>* %x, align 4
%trunc = trunc <2 x i16> %load to <2 x i8>
@@ -83,12 +79,8 @@ define i1 @test2_logical(i16* %x) {
define <2 x i1> @test2_vector(<2 x i16>* %x) {
; CHECK-LABEL: @test2_vector(
; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i16>, <2 x i16>* [[X:%.*]], align 4
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i16> [[LOAD]], <i16 -256, i16 -256>
-; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i16> [[AND]], <i16 32512, i16 32512>
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i16> [[LOAD]] to <2 x i8>
-; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i8> [[TRUNC]], <i8 69, i8 69>
-; CHECK-NEXT: [[OR:%.*]] = and <2 x i1> [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret <2 x i1> [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i16> [[LOAD]], <i16 32581, i16 32581>
+; CHECK-NEXT: ret <2 x i1> [[TMP1]]
;
%load = load <2 x i16>, <2 x i16>* %x, align 4
%and = and <2 x i16> %load, <i16 -256, i16 -256>
More information about the llvm-commits
mailing list