diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1830,15 +1830,18 @@ Type *ResultTy; if (VectorType *VT = dyn_cast(C1->getType())) ResultTy = VectorType::get(Type::getInt1Ty(C1->getContext()), - VT->getNumElements()); + VT->getElementCount()); else ResultTy = Type::getInt1Ty(C1->getContext()); + bool IsScalableVector = + C1->getType()->isVectorTy() && C1->getType()->getVectorIsScalable(); + // Fold FCMP_FALSE/FCMP_TRUE unconditionally. if (pred == FCmpInst::FCMP_FALSE) return Constant::getNullValue(ResultTy); - if (pred == FCmpInst::FCMP_TRUE) + if (!IsScalableVector && pred == FCmpInst::FCMP_TRUE) return Constant::getAllOnesValue(ResultTy); // Handle some degenerate cases first @@ -1851,14 +1854,16 @@ if (ICmpInst::isEquality(Predicate) || (isIntegerPredicate && C1 == C2)) return UndefValue::get(ResultTy); - // Otherwise, for integer compare, pick the same value as the non-undef - // operand, and fold it to true or false. - if (isIntegerPredicate) - return ConstantInt::get(ResultTy, CmpInst::isTrueWhenEqual(Predicate)); + if (!IsScalableVector) { + // Otherwise, for integer compare, pick the same value as the non-undef + // operand, and fold it to true or false. + if (isIntegerPredicate) + return ConstantInt::get(ResultTy, CmpInst::isTrueWhenEqual(Predicate)); - // Choosing NaN for the undef will always make unordered comparison succeed - // and ordered comparison fails. - return ConstantInt::get(ResultTy, CmpInst::isUnordered(Predicate)); + // Choosing NaN for the undef will always make unordered comparison + // succeed and ordered comparison fails. + return ConstantInt::get(ResultTy, CmpInst::isUnordered(Predicate)); + } } // icmp eq/ne(null,GV) -> false/true @@ -1961,6 +1966,11 @@ R==APFloat::cmpEqual); } } else if (C1->getType()->isVectorTy()) { + // Do not iterate on scalable vector. The number of elements is unknown at + // compile-time. + if (IsScalableVector) + return nullptr; + // If we can constant fold the comparison of each element, constant fold // the whole vector comparison. SmallVector ResElts; diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -2155,7 +2155,7 @@ Type *ResultTy = Type::getInt1Ty(LHS->getContext()); if (VectorType *VT = dyn_cast(LHS->getType())) - ResultTy = VectorType::get(ResultTy, VT->getNumElements()); + ResultTy = VectorType::get(ResultTy, VT->getElementCount()); LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ResultTy, Key); @@ -2180,7 +2180,7 @@ Type *ResultTy = Type::getInt1Ty(LHS->getContext()); if (VectorType *VT = dyn_cast(LHS->getType())) - ResultTy = VectorType::get(ResultTy, VT->getNumElements()); + ResultTy = VectorType::get(ResultTy, VT->getElementCount()); LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ResultTy, Key); diff --git a/llvm/test/Analysis/ConstantFolding/vscale.ll b/llvm/test/Analysis/ConstantFolding/vscale.ll --- a/llvm/test/Analysis/ConstantFolding/vscale.ll +++ b/llvm/test/Analysis/ConstantFolding/vscale.ll @@ -176,3 +176,51 @@ %r = select undef, zeroinitializer, undef ret %r } + +define @icmp_undef() { +; CHECK-LABEL: @icmp_undef( +; CHECK-NEXT: ret undef +; + %r = icmp eq undef, undef + ret %r +} + +define @icmp_zero() { +; CHECK-LABEL: @icmp_zero( +; CHECK-NEXT: ret icmp eq ( zeroinitializer, zeroinitializer) +; + %r = icmp eq zeroinitializer, zeroinitializer + ret %r +} + +define @fcmp_true() { +; CHECK-LABEL: @fcmp_true( +; CHECK-NEXT: ret fcmp true ( undef, undef) +; + %r = fcmp true undef, undef + ret %r +} + +define @fcmp_false() { +; CHECK-LABEL: @fcmp_false( +; CHECK-NEXT: ret zeroinitializer +; + %r = fcmp false undef, undef + ret %r +} + +define @fcmp_undef() { +; CHECK-LABEL: @fcmp_undef( +; CHECK-NEXT: ret undef +; + %r = icmp ne undef, undef + ret %r +} + +define @fcmp_not_equality() { +; CHECK-LABEL: @fcmp_not_equality( +; CHECK-NEXT: ret icmp ule ( undef, zeroinitializer) +; + %r = icmp ule undef, zeroinitializer + ret %r +}