[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