Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4945,34 +4945,6 @@ return New; } - // Zero-equality and sign-bit checks are preserved through sitofp + bitcast. - Value *X; - if (match(Op0, m_BitCast(m_SIToFP(m_Value(X))))) { - // 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 - // icmp sgt (bitcast (sitofp X)), 0 --> icmp sgt X, 0 - if ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_SLT || - Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SGT) && - match(Op1, m_Zero())) - return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); - - // icmp slt (bitcast (sitofp X)), 1 --> icmp slt X, 1 - if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_One())) - return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), 1)); - - // icmp sgt (bitcast (sitofp X)), -1 --> icmp sgt X, -1 - if (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes())) - return new ICmpInst(Pred, X, ConstantInt::getAllOnesValue(X->getType())); - } - - // Zero-equality checks are preserved through unsigned floating-point casts: - // 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())); - // 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 // now. @@ -4999,6 +4971,40 @@ } return new ICmpInst(I.getPredicate(), Op0, Op1); } + + // Make sure the bitcast doesn't change the number of vector elements. + if (CI->getSrcTy()->getScalarSizeInBits() == + CI->getDestTy()->getScalarSizeInBits()) { + // Zero-equality and sign-bit checks are preserved through sitofp + + // bitcast. + Value *X; + if (match(Op0, m_BitCast(m_SIToFP(m_Value(X))))) { + // 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 + // icmp sgt (bitcast (sitofp X)), 0 --> icmp sgt X, 0 + if ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_SLT || + Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SGT) && + match(Op1, m_Zero())) + return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); + + // icmp slt (bitcast (sitofp X)), 1 --> icmp slt X, 1 + if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_One())) + return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), 1)); + + // icmp sgt (bitcast (sitofp X)), -1 --> icmp sgt X, -1 + if (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes())) + return new ICmpInst(Pred, X, + ConstantInt::getAllOnesValue(X->getType())); + } + + // Zero-equality checks are preserved through unsigned floating-point + // casts: 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 (isa(Op0)) { 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,60 @@ 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 i1 @i16_cast_cmp_sgt_int_m1_bitcast_vector_to_scalar_sitofp(<3 x i16> %i) { +; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_bitcast_vector_to_scalar_sitofp( +; CHECK-NEXT: [[SITOFP:%.*]] = sitofp <3 x i16> [[I:%.*]] to <3 x float> +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <3 x float> [[SITOFP]] to i96 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i96 [[BITCAST]], -1 +; CHECK-NEXT: ret i1 [[CMP]] +; + %f = sitofp <3 x i16> %i to <3 x float> + %b = bitcast <3 x float> %f to i96 + %cmp = icmp sgt i96 %b, -1 + ret 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 +} + +define i1 @i16_cast_cmp_eq_int_0_bitcast_vector_to_scalar_uitofp(<3 x i16> %i) { +; CHECK-LABEL: @i16_cast_cmp_eq_int_0_bitcast_vector_to_scalar_uitofp( +; CHECK-NEXT: [[UITOFP:%.*]] = uitofp <3 x i16> [[I:%.*]] to <3 x float> +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <3 x float> [[UITOFP]] to i96 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i96 [[BITCAST]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %f = uitofp <3 x i16> %i to <3 x float> + %b = bitcast <3 x float> %f to i96 + %cmp = icmp eq i96 %b, 0 + ret i1 %cmp +} +