[PATCH] D76564: [ValueTracking] Avoid blind cast from Operator to Instruction

Bjorn Pettersson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 22 04:47:36 PDT 2020


bjope created this revision.
bjope added reviewers: RKSimon, nikic, spatel, efriedma.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

Avoid blind cast from Operator to ExtractElementInst in
computeKnownBitsFromOperator. This resulted in some crashes
in downstream fuzzy testing. Instead we use getOperand directly
on the Operator when accessing the vector/index operands.

Haven't seen any problems with InsertElement and ShuffleVector,
but I believe those could be used in constant expressions as well.
So the same kind of fix as for ExtractElement was also applied for
InsertElement.

When it comes to ShuffleVector we now simply bail out if a dynamic
cast of the Operator to ShuffleVectorInst fails. I've got no
reproducer indicating problems for ShuffleVector, and a fix would be
slightly more complicated as getShuffleDemandedElts is involved.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76564

Files:
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/test/Analysis/ValueTracking/known-bits-from-operator-constexpr.ll


Index: llvm/test/Analysis/ValueTracking/known-bits-from-operator-constexpr.ll
===================================================================
--- /dev/null
+++ 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.
+ at 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> <i32 1, i32 2, i32 3, i32 17>) 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> <i32 1, i32 2, i32 3, i32 17>) to <4 x i32>), i32 3)
+  ret i32 %t
+}
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -1737,7 +1737,10 @@
     }
     break;
   case Instruction::ShuffleVector: {
-    auto *Shuf = cast<ShuffleVectorInst>(I);
+    auto *Shuf = dyn_cast<ShuffleVectorInst>(I);
+    // FIXME: Do we need to handle ConstantExpr involving shufflevectors?
+    if (!Shuf)
+      return;
     // For undef elements, we don't know anything about the common state of
     // the shuffle result.
     APInt DemandedLHS, DemandedRHS;
@@ -1763,10 +1766,9 @@
     break;
   }
   case Instruction::InsertElement: {
-    auto *IEI = cast<InsertElementInst>(I);
-    Value *Vec = IEI->getOperand(0);
-    Value *Elt = IEI->getOperand(1);
-    auto *CIdx = dyn_cast<ConstantInt>(IEI->getOperand(2));
+    Value *Vec = I->getOperand(0);
+    Value *Elt = I->getOperand(1);
+    auto *CIdx = dyn_cast<ConstantInt>(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 +1798,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<ExtractElementInst>(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<ConstantInt>(Idx);
     unsigned NumElts = Vec->getType()->getVectorNumElements();
     APInt DemandedVecElts = APInt::getAllOnesValue(NumElts);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76564.251883.patch
Type: text/x-patch
Size: 2939 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200322/bca2126f/attachment.bin>


More information about the llvm-commits mailing list