diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -445,6 +445,14 @@ return cst_pred_ty(); } +struct is_shifted_mask { + bool isValue(const APInt &C) { return C.isShiftedMask(); } +}; + +inline cst_pred_ty m_ShiftedMask() { + return cst_pred_ty(); +} + 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 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -955,6 +955,108 @@ 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(B) || + (BCst->countLeadingOnes() == DCst->countLeadingZeros())); + }; + + // Test vector type arguments for conversion. + if (const auto *BVTy = dyn_cast(B->getType())) { + const auto *BFVTy = dyn_cast(BVTy); + const auto *BConst = dyn_cast(B); + const auto *DConst = dyn_cast(D); + const auto *EConst = dyn_cast(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> 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 @@ 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 --- 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_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 @@ ; ((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_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 @@ ; ((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_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 @@ ; ((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_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 @@ ; ((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_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 @@ ; ((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_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 @@ ; 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <1 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <1 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <1 x i1> [[T1]], [[T3]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <1 x i32> [[X:%.*]], ; CHECK-NEXT: ret <1 x i1> [[T4]] ; %t1 = icmp ult <1 x i32> %x, @@ -424,10 +385,7 @@ 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <1 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <1 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <1 x i1> [[T3]], [[T1]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <1 x i32> [[X:%.*]], ; CHECK-NEXT: ret <1 x i1> [[T4]] ; %t1 = icmp ult <1 x i32> %x, @@ -440,10 +398,7 @@ ; 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], ; CHECK-NEXT: ret <2 x i1> [[T4]] ; %t1 = icmp ult <2 x i32> %x, @@ -455,10 +410,7 @@ 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T3]], [[T1]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], ; CHECK-NEXT: ret <2 x i1> [[T4]] ; %t1 = icmp ult <2 x i32> %x, @@ -471,10 +423,7 @@ ; 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], ; CHECK-NEXT: ret <2 x i1> [[T4]] ; %t1 = icmp ult <2 x i32> %x, @@ -486,10 +435,7 @@ 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T3]], [[T1]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], ; CHECK-NEXT: ret <2 x i1> [[T4]] ; %t1 = icmp ult <2 x i32> %x, @@ -502,10 +448,7 @@ ; 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T1]], [[T3]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], ; CHECK-NEXT: ret <2 x i1> [[T4]] ; %t1 = icmp ult <2 x i32> %x, @@ -517,10 +460,7 @@ 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <2 x i1> [[T3]], [[T1]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <2 x i32> [[X:%.*]], ; CHECK-NEXT: ret <2 x i1> [[T4]] ; %t1 = icmp ult <2 x i32> %x, @@ -533,10 +473,7 @@ ; 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <7 x i8> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <7 x i8> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <7 x i1> [[T1]], [[T3]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <7 x i8> [[X:%.*]], ; CHECK-NEXT: ret <7 x i1> [[T4]] ; %t1 = icmp ult <7 x i8> %x, @@ -548,10 +485,7 @@ 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <7 x i8> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <7 x i8> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <7 x i1> [[T3]], [[T1]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <7 x i8> [[X:%.*]], ; CHECK-NEXT: ret <7 x i1> [[T4]] ; %t1 = icmp ult <7 x i8> %x, @@ -564,10 +498,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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <6 x i8> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <6 x i8> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <6 x i1> [[T1]], [[T3]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <6 x i8> [[X:%.*]], ; CHECK-NEXT: ret <6 x i1> [[T4]] ; %t1 = icmp ult <6 x i8> %x, @@ -579,10 +510,7 @@ 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:%.*]], -; CHECK-NEXT: [[T2:%.*]] = and <6 x i8> [[X]], -; CHECK-NEXT: [[T3:%.*]] = icmp ne <6 x i8> [[T2]], -; CHECK-NEXT: [[T4:%.*]] = and <6 x i1> [[T1]], [[T3]] +; CHECK-NEXT: [[T4:%.*]] = icmp ult <6 x i8> [[X:%.*]], ; CHECK-NEXT: ret <6 x i1> [[T4]] ; %t1 = icmp ult <6 x i8> %x,