diff --git a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp --- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -397,6 +397,10 @@ uint64_t Shift = RHSKnown.getConstant().getZExtValue(); LLVM_DEBUG(dbgs() << '[' << Depth << "] Shift is " << Shift << '\n'); + // Guard against oversized shift amounts + if (Shift > MRI.getType(MI.getOperand(1).getReg()).getSizeInBits()) + break; + computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts, Depth + 1); diff --git a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp --- a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -725,3 +725,26 @@ EXPECT_EQ(0xffu, KnownUmax.Zero.getZExtValue()); EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue()); } + +TEST_F(AArch64GISelMITest, TestInvalidQueries) { + StringRef MIRString = R"( + %src:_(s32) = COPY $w0 + %thirty3:_(s32) = G_CONSTANT i32 33 + %shift:_(s32) = G_SHL %src, %thirty3 + %final_copy:_(s32) = COPY %shift +)"; + setUp(MIRString); + if (!TM) + return; + + Register CopyReg = Copies[Copies.size() - 1]; + MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); + Register ShlRes = FinalCopy->getOperand(1).getReg(); + + GISelKnownBits Info(*MF); + KnownBits Res = Info.getKnownBits(ShlRes); + + // We don't know what the result of the shift is, but we should not crash + EXPECT_TRUE(Res.One.isNullValue()); + EXPECT_TRUE(Res.Zero.isNullValue()); +} \ No newline at end of file