Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4824,6 +4824,11 @@ return nullptr; } +static unsigned getVectorNumElementsOrZero(Type *T) +{ + return T->isVectorTy() ? T->getVectorNumElements() : 0; +} + Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { bool Changed = false; Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -4947,7 +4952,9 @@ // Zero-equality and sign-bit checks are preserved through sitofp + bitcast. Value *X; - if (match(Op0, m_BitCast(m_SIToFP(m_Value(X))))) { + if (match(Op0, m_BitCast(m_SIToFP(m_Value(X)))) && + getVectorNumElementsOrZero(X->getType()) == + getVectorNumElementsOrZero(I.getType())) { // icmp eq (bitcast (sitofp X)), 0 --> icmp eq X, 0 // icmp ne (bitcast (sitofp X)), 0 --> icmp ne X, 0 // icmp slt (bitcast (sitofp X)), 0 --> icmp slt X, 0 @@ -4970,8 +4977,10 @@ // icmp eq (bitcast (uitofp X)), 0 --> icmp eq X, 0 // icmp ne (bitcast (uitofp X)), 0 --> icmp ne X, 0 if (match(Op0, m_BitCast(m_UIToFP(m_Value(X))))) - if (I.isEquality() && match(Op1, m_Zero())) - return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); + if (getVectorNumElementsOrZero(X->getType()) == + getVectorNumElementsOrZero(I.getType())) + if (I.isEquality() && match(Op1, m_Zero())) + return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); // Test to see if the operands of the icmp are casted versions of other // values. If the ptr->ptr cast can be stripped off both arguments, we do so Index: test/Transforms/InstCombine/cast-int-icmp-eq-0.ll =================================================================== --- test/Transforms/InstCombine/cast-int-icmp-eq-0.ll +++ test/Transforms/InstCombine/cast-int-icmp-eq-0.ll @@ -651,3 +651,34 @@ ret <3 x i1> %cmp } +; Verify that the various forms of this transform are not applied when the +; bitcast changes the number of vector elements: +; icmp (bitcast ([su]itofp X)), Y -> icmp X, Y + +define <6 x i1> @i16_cast_cmp_sgt_int_m1_bitcast_vector_num_elements_sitofp(<3 x i16> %i) { +; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_bitcast_vector_num_elements_sitofp( +; CHECK-NEXT: [[SITOFP:%.*]] = sitofp <3 x i16> [[I:%.*]] to <3 x float> +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <3 x float> [[SITOFP]] to <6 x i16> +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <6 x i16> [[BITCAST]], +; CHECK-NEXT: ret <6 x i1> [[CMP]] +; + %f = sitofp <3 x i16> %i to <3 x float> + %b = bitcast <3 x float> %f to <6 x i16> + %cmp = icmp sgt <6 x i16> %b, + ret <6 x i1> %cmp +} + + +define <6 x i1> @i16_cast_cmp_eq_int_0_bitcast_vector_num_elements_uitofp(<3 x i16> %i) { +; CHECK-LABEL: @i16_cast_cmp_eq_int_0_bitcast_vector_num_elements_uitofp( +; CHECK-NEXT: [[UITOFP:%.*]] = uitofp <3 x i16> [[I:%.*]] to <3 x float> +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <3 x float> [[UITOFP]] to <6 x i16> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <6 x i16> [[BITCAST]], zeroinitializer +; CHECK-NEXT: ret <6 x i1> [[CMP]] +; + %f = uitofp <3 x i16> %i to <3 x float> + %b = bitcast <3 x float> %f to <6 x i16> + %cmp = icmp eq <6 x i16> %b, + ret <6 x i1> %cmp +} +