[llvm] 1001f90 - [InstCombine] Optimize and of icmps with power-of-2 and contiguous masks
John McIver via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 9 15:10:49 PDT 2023
Author: John McIver
Date: 2023-06-09T16:07:01-06:00
New Revision: 1001f9031f3ed0ca2ff146889bf82c10cea149d5
URL: https://github.com/llvm/llvm-project/commit/1001f9031f3ed0ca2ff146889bf82c10cea149d5
DIFF: https://github.com/llvm/llvm-project/commit/1001f9031f3ed0ca2ff146889bf82c10cea149d5.diff
LOG: [InstCombine] Optimize and of icmps with power-of-2 and contiguous masks
Add an instance combine optimization for expressions of the form:
(%arg u< C1) & ((%arg & C2) != C2) -> %arg u< C2
Where C1 is a power-of-2 and C2 is a contiguous mask starting 1 bit below
C1. This commit resolves GitHub missed-optimization issue #54856.
Validation of scalar tests:
- https://alive2.llvm.org/ce/z/JfKjiU
- https://alive2.llvm.org/ce/z/AruHY_
- https://alive2.llvm.org/ce/z/JAiR6t
- https://alive2.llvm.org/ce/z/S2X2e5
- https://alive2.llvm.org/ce/z/4cycdE
- https://alive2.llvm.org/ce/z/NcDiLP
Validation of vector tests:
- https://alive2.llvm.org/ce/z/ABY6tE
- https://alive2.llvm.org/ce/z/BTJi3s
- https://alive2.llvm.org/ce/z/3BKWpu
- https://alive2.llvm.org/ce/z/RrAbkj
- https://alive2.llvm.org/ce/z/nM6fsN
Reviewed By: goldstein.w.n
Differential Revision: https://reviews.llvm.org/D125717
Added:
Modified:
llvm/include/llvm/IR/PatternMatch.h
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index e141a96049162..5a4c67744a5cb 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -445,6 +445,14 @@ inline cst_pred_ty<is_any_apint> m_AnyIntegralConstant() {
return cst_pred_ty<is_any_apint>();
}
+struct is_shifted_mask {
+ bool isValue(const APInt &C) { return C.isShiftedMask(); }
+};
+
+inline cst_pred_ty<is_shifted_mask> m_ShiftedMask() {
+ return cst_pred_ty<is_shifted_mask>();
+}
+
struct is_all_ones {
bool isValue(const APInt &C) { return C.isAllOnes(); }
};
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index d9fab3f2a6b5a..791dc87ffdc94 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -955,6 +955,108 @@ static Value *foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd,
return nullptr;
}
+/// Try to fold (icmp(A & B) == 0) & (icmp(A & D) != E) into (icmp A u< D) iff
+/// B is a contiguous set of ones starting from the most significant bit
+/// (negative power of 2), D and E are equal, and D is a contiguous set of ones
+/// starting at the most significant zero bit in B. Parameter B supports masking
+/// using undef/poison in either scalar or vector values.
+static Value *foldNegativePower2AndShiftedMask(
+ Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL,
+ ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder) {
+ assert(ICmpInst::isEquality(PredL) && ICmpInst::isEquality(PredR) &&
+ "Expected equality predicates for masked type of icmps.");
+ if (PredL != ICmpInst::ICMP_EQ || PredR != ICmpInst::ICMP_NE)
+ return nullptr;
+
+ if (!match(B, m_NegatedPower2()) || !match(D, m_ShiftedMask()) ||
+ !match(E, m_ShiftedMask()))
+ return nullptr;
+
+ // Test scalar arguments for conversion. B has been validated earlier to be a
+ // negative power of two and thus is guaranteed to have one or more contiguous
+ // ones starting from the MSB followed by zero or more contiguous zeros. D has
+ // been validated earlier to be a shifted set of one or more contiguous ones.
+ // In order to match, B leading ones and D leading zeros should be equal. The
+ // predicate that B be a negative power of 2 prevents the condition of there
+ // ever being zero leading ones. Thus 0 == 0 cannot occur. The predicate that
+ // D always be a shifted mask prevents the condition of D equaling 0. This
+ // prevents matching the condition where B contains the maximum number of
+ // leading one bits (-1) and D contains the maximum number of leading zero
+ // bits (0).
+ auto isReducible = [](const Value *B, const Value *D, const Value *E) {
+ const APInt *BCst, *DCst, *ECst;
+ return match(B, m_APIntAllowUndef(BCst)) && match(D, m_APInt(DCst)) &&
+ match(E, m_APInt(ECst)) && *DCst == *ECst &&
+ (isa<UndefValue>(B) ||
+ (BCst->countLeadingOnes() == DCst->countLeadingZeros()));
+ };
+
+ // Test vector type arguments for conversion.
+ if (const auto *BVTy = dyn_cast<VectorType>(B->getType())) {
+ const auto *BFVTy = dyn_cast<FixedVectorType>(BVTy);
+ const auto *BConst = dyn_cast<Constant>(B);
+ const auto *DConst = dyn_cast<Constant>(D);
+ const auto *EConst = dyn_cast<Constant>(E);
+
+ if (!BFVTy || !BConst || !DConst || !EConst)
+ return nullptr;
+
+ for (unsigned I = 0; I != BFVTy->getNumElements(); ++I) {
+ const auto *BElt = BConst->getAggregateElement(I);
+ const auto *DElt = DConst->getAggregateElement(I);
+ const auto *EElt = EConst->getAggregateElement(I);
+
+ if (!BElt || !DElt || !EElt)
+ return nullptr;
+ if (!isReducible(BElt, DElt, EElt))
+ return nullptr;
+ }
+ } else {
+ // Test scalar type arguments for conversion.
+ if (!isReducible(B, D, E))
+ return nullptr;
+ }
+ return Builder.CreateICmp(ICmpInst::ICMP_ULT, A, D);
+}
+
+/// Try to fold ((icmp X u< P) & (icmp(X & M) != M)) or ((icmp X s> -1) &
+/// (icmp(X & M) != M)) into (icmp X u< M). Where P is a power of 2, M < P, and
+/// M is a contiguous shifted mask starting at the right most significant zero
+/// bit in P. SGT is supported as when P is the largest representable power of
+/// 2, an earlier optimization converts the expression into (icmp X s> -1).
+/// Parameter P supports masking using undef/poison in either scalar or vector
+/// values.
+static Value *foldPowerOf2AndShiftedMask(ICmpInst *Cmp0, ICmpInst *Cmp1,
+ bool JoinedByAnd,
+ InstCombiner::BuilderTy &Builder) {
+ if (!JoinedByAnd)
+ return nullptr;
+ Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr, *E = nullptr;
+ ICmpInst::Predicate CmpPred0 = Cmp0->getPredicate(),
+ CmpPred1 = Cmp1->getPredicate();
+ // Assuming P is a 2^n, getMaskedTypeForICmpPair will normalize (icmp X u<
+ // 2^n) into (icmp (X & ~(2^n-1)) == 0) and (icmp X s> -1) into (icmp (X &
+ // SignMask) == 0).
+ std::optional<std::pair<unsigned, unsigned>> MaskPair =
+ getMaskedTypeForICmpPair(A, B, C, D, E, Cmp0, Cmp1, CmpPred0, CmpPred1);
+ if (!MaskPair)
+ return nullptr;
+
+ const auto compareBMask = BMask_NotMixed | BMask_NotAllOnes;
+ unsigned CmpMask0 = MaskPair->first;
+ unsigned CmpMask1 = MaskPair->second;
+ if ((CmpMask0 & Mask_AllZeros) && (CmpMask1 == compareBMask)) {
+ if (Value *V = foldNegativePower2AndShiftedMask(A, B, D, E, CmpPred0,
+ CmpPred1, Builder))
+ return V;
+ } else if ((CmpMask0 == compareBMask) && (CmpMask1 & Mask_AllZeros)) {
+ if (Value *V = foldNegativePower2AndShiftedMask(A, D, B, C, CmpPred1,
+ CmpPred0, Builder))
+ return V;
+ }
+ return nullptr;
+}
+
/// Commuted variants are assumed to be handled by calling this function again
/// with the parameters swapped.
static Value *foldUnsignedUnderflowCheck(ICmpInst *ZeroICmp,
@@ -2925,6 +3027,9 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
if (Value *V = foldIsPowerOf2(LHS, RHS, IsAnd, Builder))
return V;
+ if (Value *V = foldPowerOf2AndShiftedMask(LHS, RHS, IsAnd, Builder))
+ return V;
+
// TODO: Verify whether this is safe for logical and/or.
if (!IsLogical) {
if (Value *X = foldUnsignedUnderflowCheck(LHS, RHS, IsAnd, Q, Builder))
diff --git a/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll b/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll
index e52c153fff516..82fcca07a00ac 100644
--- a/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-power2-and-icmp-shifted-mask.ll
@@ -6,10 +6,7 @@
; ((X u< 0x8000000) & ((X & 0x60000000) != 0x60000000)) -> X u< 0x60000000
define i1 @icmp_power2_and_icmp_shifted_mask_2147483648_1610612736(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_2147483648_1610612736(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 1610612736
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 1610612736
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 1610612736
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 2147483648
@@ -21,10 +18,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_2147483648_1610612736(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_1610612736(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_1610612736(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 1610612736
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 1610612736
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 1610612736
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 2147483648
@@ -37,10 +31,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_1610612736(i32 %
; ((X u< 0x8000000) & ((X & 0x7FFFFFFF) != 0x7FFFFFFF)) -> X u< 0x7FFFFFFF
define i1 @icmp_power2_and_icmp_shifted_mask_2147483648_2147483647(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_2147483648_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 2147483647
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 2147483647
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 2147483647
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 2147483648
@@ -52,10 +43,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_2147483648_2147483647(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_2147483647(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 2147483647
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 2147483647
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 2147483647
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 2147483648
@@ -68,10 +56,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_2147483647(i32 %
; ((X u< 0x4000000) & ((X & 0x30000000) != 0x30000000)) -> X u< 0x30000000
define i1 @icmp_power2_and_icmp_shifted_mask_2147483648_805306368(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_2147483648_805306368(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 1073741824
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 805306368
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 805306368
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 805306368
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 1073741824
@@ -83,10 +68,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_2147483648_805306368(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_805306368(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_805306368(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 1073741824
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 805306368
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 805306368
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 805306368
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 1073741824
@@ -99,10 +81,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_2147483648_805306368(i32 %x
; ((X u< 0x40000000) & ((X & 0x3FFFFFFF) != 0x3FFFFFFF)) -> X u< 0x3FFFFFFF
define i1 @icmp_power2_and_icmp_shifted_mask_1073741824_1073741823(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_1073741824_1073741823(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 1073741824
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 1073741823
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 1073741823
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 1073741823
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 1073741824
@@ -114,10 +93,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_1073741824_1073741823(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 1073741824
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 1073741823
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 1073741823
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 1073741823
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 1073741824
@@ -130,10 +106,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823(i32 %
; ((X u< 8) & ((X & 7) != 7)) -> X u< 7
define i1 @icmp_power2_and_icmp_shifted_mask_8_7(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_8_7(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 7
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 7
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 7
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 8
@@ -145,10 +118,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_8_7(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_7(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_8_7(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 7
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 7
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 7
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 8
@@ -161,10 +131,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_7(i32 %x) {
; ((X u< 8) & ((X & 6) != 6)) -> X u< 6
define i1 @icmp_power2_and_icmp_shifted_mask_8_6(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_8_6(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 6
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 6
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 6
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 8
@@ -176,10 +143,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_8_6(i32 %x) {
define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_6(i32 %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_swapped_8_6(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 8
-; CHECK-NEXT: [[T2:%.*]] = and i32 [[X]], 6
-; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 6
-; CHECK-NEXT: [[T4:%.*]] = and i1 [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[X:%.*]], 6
; CHECK-NEXT: ret i1 [[T4]]
;
%t1 = icmp ult i32 %x, 8
@@ -409,10 +373,7 @@ define i1 @icmp_power2_and_icmp_shifted_mask_swapped_8_12_mask_overlap_fail(i32
; Vector of 1 reduction
define <1 x i1> @icmp_power2_and_icmp_shifted_mask_vector_2147483648_2147483647(<1 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_2147483648_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt <1 x i32> [[X:%.*]], <i32 -1>
-; CHECK-NEXT: [[T2:%.*]] = and <1 x i32> [[X]], <i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <1 x i32> [[T2]], <i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <1 x i1> [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <1 x i32> [[X:%.*]], <i32 2147483647>
; CHECK-NEXT: ret <1 x i1> [[T4]]
;
%t1 = icmp ult <1 x i32> %x, <i32 2147483648>
@@ -424,10 +385,7 @@ define <1 x i1> @icmp_power2_and_icmp_shifted_mask_vector_2147483648_2147483647(
define <1 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_2147483648_2147483647(<1 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_swapped_2147483648_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt <1 x i32> [[X:%.*]], <i32 -1>
-; CHECK-NEXT: [[T2:%.*]] = and <1 x i32> [[X]], <i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <1 x i32> [[T2]], <i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <1 x i1> [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <1 x i32> [[X:%.*]], <i32 2147483647>
; CHECK-NEXT: ret <1 x i1> [[T4]]
;
%t1 = icmp ult <1 x i32> %x, <i32 2147483648>
@@ -440,10 +398,7 @@ define <1 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_2147483648_214
; Vector of 2 reduction
define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_2147483648_1610612736_2147483647(<2 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_2147483648_1610612736_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
-; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 1610612736, i32 2147483647>
; CHECK-NEXT: ret <2 x i1> [[T4]]
;
%t1 = icmp ult <2 x i32> %x, <i32 2147483648, i32 2147483648>
@@ -455,10 +410,7 @@ define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_2147483648_1610612736_
define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_2147483648_1610612736_2147483647(<2 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_swapped_2147483648_1610612736_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
-; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 1610612736, i32 2147483647>
; CHECK-NEXT: ret <2 x i1> [[T4]]
;
%t1 = icmp ult <2 x i32> %x, <i32 2147483648, i32 2147483648>
@@ -471,10 +423,7 @@ define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_2147483648_161
; Vector of 2 reduction with splat containing poison
define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_splat_poison_2147483648_1610612736_2147483647(<2 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_splat_poison_2147483648_1610612736_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -2147483648, i32 poison>
-; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 1610612736, i32 2147483647>
; CHECK-NEXT: ret <2 x i1> [[T4]]
;
%t1 = icmp ult <2 x i32> %x, <i32 2147483648, i32 poison>
@@ -486,10 +435,7 @@ define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_splat_poison_214748364
define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_splat_poison_2147483648_1610612736_2147483647(<2 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_swapped_splat_poison_2147483648_1610612736_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -2147483648, i32 poison>
-; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 1610612736, i32 2147483647>
; CHECK-NEXT: ret <2 x i1> [[T4]]
;
%t1 = icmp ult <2 x i32> %x, <i32 2147483648, i32 poison>
@@ -502,10 +448,7 @@ define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_splat_poison_2
; Vector of 2 reduction with splat containing undef
define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_splat_undef_2147483648_1610612736_2147483647(<2 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_splat_undef_2147483648_1610612736_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -2147483648, i32 undef>
-; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 1610612736, i32 2147483647>
; CHECK-NEXT: ret <2 x i1> [[T4]]
;
%t1 = icmp ult <2 x i32> %x, <i32 2147483648, i32 undef>
@@ -517,10 +460,7 @@ define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_splat_undef_2147483648
define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_splat_undef_2147483648_1610612736_2147483647(<2 x i32> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_swapped_splat_undef_2147483648_1610612736_2147483647(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -2147483648, i32 undef>
-; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], <i32 1610612736, i32 2147483647>
-; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 1610612736, i32 2147483647>
; CHECK-NEXT: ret <2 x i1> [[T4]]
;
%t1 = icmp ult <2 x i32> %x, <i32 2147483648, i32 undef>
@@ -533,10 +473,7 @@ define <2 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_splat_undef_21
; Vector of 7 reduction
define <7 x i1> @icmp_power2_and_icmp_shifted_mask_vector_128_others(<7 x i8> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_128_others(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt <7 x i8> [[X:%.*]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
-; CHECK-NEXT: [[T2:%.*]] = and <7 x i8> [[X]], <i8 127, i8 126, i8 124, i8 120, i8 112, i8 96, i8 64>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <7 x i8> [[T2]], <i8 127, i8 126, i8 124, i8 120, i8 112, i8 96, i8 64>
-; CHECK-NEXT: [[T4:%.*]] = and <7 x i1> [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <7 x i8> [[X:%.*]], <i8 127, i8 126, i8 124, i8 120, i8 112, i8 96, i8 64>
; CHECK-NEXT: ret <7 x i1> [[T4]]
;
%t1 = icmp ult <7 x i8> %x, <i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128>
@@ -548,10 +485,7 @@ define <7 x i1> @icmp_power2_and_icmp_shifted_mask_vector_128_others(<7 x i8> %x
define <7 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_128_others(<7 x i8> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_swapped_128_others(
-; CHECK-NEXT: [[T1:%.*]] = icmp sgt <7 x i8> [[X:%.*]], <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
-; CHECK-NEXT: [[T2:%.*]] = and <7 x i8> [[X]], <i8 127, i8 126, i8 124, i8 120, i8 112, i8 96, i8 64>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <7 x i8> [[T2]], <i8 127, i8 126, i8 124, i8 120, i8 112, i8 96, i8 64>
-; CHECK-NEXT: [[T4:%.*]] = and <7 x i1> [[T3]], [[T1]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <7 x i8> [[X:%.*]], <i8 127, i8 126, i8 124, i8 120, i8 112, i8 96, i8 64>
; CHECK-NEXT: ret <7 x i1> [[T4]]
;
%t1 = icmp ult <7 x i8> %x, <i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128>
@@ -564,10 +498,7 @@ define <7 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_128_others(<7
; Vector of 6 reduction
define <6 x i1> @icmp_power2_and_icmp_shifted_mask_vector_64_others(<6 x i8> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_64_others(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult <6 x i8> [[X:%.*]], <i8 64, i8 64, i8 64, i8 64, i8 64, i8 64>
-; CHECK-NEXT: [[T2:%.*]] = and <6 x i8> [[X]], <i8 63, i8 62, i8 60, i8 56, i8 48, i8 32>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <6 x i8> [[T2]], <i8 63, i8 62, i8 60, i8 56, i8 48, i8 32>
-; CHECK-NEXT: [[T4:%.*]] = and <6 x i1> [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <6 x i8> [[X:%.*]], <i8 63, i8 62, i8 60, i8 56, i8 48, i8 32>
; CHECK-NEXT: ret <6 x i1> [[T4]]
;
%t1 = icmp ult <6 x i8> %x, <i8 64, i8 64, i8 64, i8 64, i8 64, i8 64>
@@ -579,10 +510,7 @@ define <6 x i1> @icmp_power2_and_icmp_shifted_mask_vector_64_others(<6 x i8> %x)
define <6 x i1> @icmp_power2_and_icmp_shifted_mask_vector_swapped_64_others(<6 x i8> %x) {
; CHECK-LABEL: @icmp_power2_and_icmp_shifted_mask_vector_swapped_64_others(
-; CHECK-NEXT: [[T1:%.*]] = icmp ult <6 x i8> [[X:%.*]], <i8 64, i8 64, i8 64, i8 64, i8 64, i8 64>
-; CHECK-NEXT: [[T2:%.*]] = and <6 x i8> [[X]], <i8 63, i8 62, i8 60, i8 56, i8 48, i8 32>
-; CHECK-NEXT: [[T3:%.*]] = icmp ne <6 x i8> [[T2]], <i8 63, i8 62, i8 60, i8 56, i8 48, i8 32>
-; CHECK-NEXT: [[T4:%.*]] = and <6 x i1> [[T1]], [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = icmp ult <6 x i8> [[X:%.*]], <i8 63, i8 62, i8 60, i8 56, i8 48, i8 32>
; CHECK-NEXT: ret <6 x i1> [[T4]]
;
%t1 = icmp ult <6 x i8> %x, <i8 64, i8 64, i8 64, i8 64, i8 64, i8 64>
More information about the llvm-commits
mailing list