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 @@ -1737,7 +1737,12 @@ } break; case Instruction::ShuffleVector: { - auto *Shuf = cast(I); + auto *Shuf = dyn_cast(I); + // FIXME: Do we need to handle ConstantExpr involving shufflevectors? + if (!Shuf) { + Known.resetAll(); + return; + } // For undef elements, we don't know anything about the common state of // the shuffle result. APInt DemandedLHS, DemandedRHS; @@ -1763,10 +1768,9 @@ break; } case Instruction::InsertElement: { - auto *IEI = cast(I); - Value *Vec = IEI->getOperand(0); - Value *Elt = IEI->getOperand(1); - auto *CIdx = dyn_cast(IEI->getOperand(2)); + const Value *Vec = I->getOperand(0); + const Value *Elt = I->getOperand(1); + auto *CIdx = dyn_cast(I->getOperand(2)); // Early out if the index is non-constant or out-of-range. unsigned NumElts = DemandedElts.getBitWidth(); if (!CIdx || CIdx->getValue().uge(NumElts)) { @@ -1796,9 +1800,8 @@ case Instruction::ExtractElement: { // Look through extract element. If the index is non-constant or // out-of-range demand all elements, otherwise just the extracted element. - auto* EEI = cast(I); - const Value* Vec = EEI->getVectorOperand(); - const Value* Idx = EEI->getIndexOperand(); + const Value *Vec = I->getOperand(0); + const Value *Idx = I->getOperand(1); auto *CIdx = dyn_cast(Idx); unsigned NumElts = Vec->getType()->getVectorNumElements(); APInt DemandedVecElts = APInt::getAllOnesValue(NumElts); diff --git a/llvm/test/Analysis/ValueTracking/known-bits-from-operator-constexpr.ll b/llvm/test/Analysis/ValueTracking/known-bits-from-operator-constexpr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/ValueTracking/known-bits-from-operator-constexpr.ll @@ -0,0 +1,15 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instsimplify -S | FileCheck %s + +; Reproducer for a crash in computeKnownBitsFromOperator due to blindly +; casting from llvm::Operator to ExtractElementInst. That does not work +; if the Operator is a ConstantExpr. +@g = global [21 x i32] zeroinitializer +define i32 @test1(i32 %a) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: [[T:%.*]] = sub i32 [[A:%.*]], extractelement (<4 x i32> ptrtoint (<4 x i32*> getelementptr inbounds ([21 x i32], [21 x i32]* @g, <4 x i32> zeroinitializer, <4 x i32> ) to <4 x i32>), i32 3) +; CHECK-NEXT: ret i32 [[T]] +; + %t = sub i32 %a, extractelement (<4 x i32> ptrtoint (<4 x i32 *> getelementptr inbounds ([21 x i32], [21 x i32] * @g, <4 x i32> zeroinitializer, <4 x i32> ) to <4 x i32>), i32 3) + ret i32 %t +}