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 @@ -953,10 +953,14 @@ Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) { assert(Instruction::isUnaryOp(Opcode) && "Non-unary instruction detected"); - // Handle scalar UndefValue. Vectors are always evaluated per element. - bool HasScalarUndef = !C->getType()->isVectorTy() && isa(C); + // Handle scalar UndefValue and scalable vector UndefValue. Fixed-length + // vectors are always evaluated per element. + bool IsScalableVector = + C->getType()->isVectorTy() && C->getType()->getVectorIsScalable(); + bool HasScalarUndefOrScalableVectorUndef = + (!C->getType()->isVectorTy() || IsScalableVector) && isa(C); - if (HasScalarUndef) { + if (HasScalarUndefOrScalableVectorUndef) { switch (static_cast(Opcode)) { case Instruction::FNeg: return C; // -undef -> undef @@ -966,7 +970,7 @@ } // Constant should not be UndefValue, unless these are vector constants. - assert(!HasScalarUndef && "Unexpected UndefValue"); + assert(!HasScalarUndefOrScalableVectorUndef && "Unexpected UndefValue"); // We only have FP UnaryOps right now. assert(!isa(C) && "Unexpected Integer UnaryOp"); @@ -979,6 +983,11 @@ return ConstantFP::get(C->getContext(), neg(CV)); } } else if (VectorType *VTy = dyn_cast(C->getType())) { + // Do not iterate on scalable vector. The number of elements is unknown at + // compile-time. + if (IsScalableVector) + return nullptr; + // Fold each element and create a vector constant from those constants. SmallVector Result; Type *Ty = IntegerType::get(VTy->getContext(), 32); 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 @@ -1,6 +1,17 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -constprop -S | FileCheck %s +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Unary Operations +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +define @fneg( %val) { +; CHECK-LABEL: @fneg( +; CHECK-NEXT: ret undef +; + %r = fneg undef + ret %r +} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Binary Operations