diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1685,7 +1685,8 @@ Known.Zero.setBitsFrom(31); break; case Intrinsic::vscale: { - if (!II->getFunction()->hasFnAttribute(Attribute::VScaleRange)) + if (!II->getParent() || + !II->getFunction()->hasFnAttribute(Attribute::VScaleRange)) break; auto VScaleRange = II->getFunction() diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -963,7 +963,8 @@ } if (match(Src, m_VScale(DL))) { - if (Trunc.getFunction()->hasFnAttribute(Attribute::VScaleRange)) { + if (Trunc.getFunction() && + Trunc.getFunction()->hasFnAttribute(Attribute::VScaleRange)) { unsigned MaxVScale = Trunc.getFunction() ->getFnAttribute(Attribute::VScaleRange) .getVScaleRangeArgs() @@ -1334,7 +1335,8 @@ } if (match(Src, m_VScale(DL))) { - if (CI.getFunction()->hasFnAttribute(Attribute::VScaleRange)) { + if (CI.getFunction() && + CI.getFunction()->hasFnAttribute(Attribute::VScaleRange)) { unsigned MaxVScale = CI.getFunction() ->getFnAttribute(Attribute::VScaleRange) .getVScaleRangeArgs() @@ -1604,7 +1606,8 @@ } if (match(Src, m_VScale(DL))) { - if (CI.getFunction()->hasFnAttribute(Attribute::VScaleRange)) { + if (CI.getFunction() && + CI.getFunction()->hasFnAttribute(Attribute::VScaleRange)) { unsigned MaxVScale = CI.getFunction() ->getFnAttribute(Attribute::VScaleRange) .getVScaleRangeArgs() diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -12,6 +12,7 @@ #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" @@ -1597,6 +1598,22 @@ EXPECT_EQ(Known.getMaxValue(), 131071); } +TEST_F(ComputeKnownBitsTest, ComputeKnownBitsUnknownVScale) { + Module M("", Context); + IRBuilder<> Builder(Context); + Function *TheFn = + Intrinsic::getDeclaration(&M, Intrinsic::vscale, {Builder.getInt32Ty()}); + CallInst *CI = Builder.CreateCall(TheFn, {}, {}, ""); + + KnownBits Known = computeKnownBits(CI, M.getDataLayout(), /* Depth */ 0); + delete CI; + + // There is no parent function so we cannot look up the vscale_range + // attribute to determine the number of bits. + EXPECT_EQ(Known.One.getZExtValue(), 0u); + EXPECT_EQ(Known.Zero.getZExtValue(), 0u); +} + // 512 + [32, 64) doesn't produce overlapping bits. // Make sure we get all the individual bits properly. TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAddWithRangeNoOverlap) {