[llvm] b80c41c - [SLP]Fix PR43799: Crash on different sizes of GEP indices.

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 4 07:48:11 PST 2019


Author: Alexey Bataev
Date: 2019-11-04T10:36:26-05:00
New Revision: b80c41cd3c095c8c4fa739130b560b15bda4bbd0

URL: https://github.com/llvm/llvm-project/commit/b80c41cd3c095c8c4fa739130b560b15bda4bbd0
DIFF: https://github.com/llvm/llvm-project/commit/b80c41cd3c095c8c4fa739130b560b15bda4bbd0.diff

LOG: [SLP]Fix PR43799: Crash on different sizes of GEP indices.

Summary:
If the GEP instructions are going to be vectorized, the indices in those
GEP instructions must be of the same type. Otherwise, the compiler may
crash when trying to build the vector constant.

Reviewers: RKSimon, spatel

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D69627

Added: 
    

Modified: 
    llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
    llvm/test/Transforms/SLPVectorizer/X86/crash_gep.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 986b6be135a9..94392ca6a4a5 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -2638,9 +2638,14 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
       }
 
       // We don't combine GEPs with non-constant indexes.
+      Type *Ty1 = VL0->getOperand(1)->getType();
       for (Value *V : VL) {
         auto Op = cast<Instruction>(V)->getOperand(1);
-        if (!isa<ConstantInt>(Op)) {
+        if (!isa<ConstantInt>(Op) ||
+            (Op->getType() != Ty1 &&
+             Op->getType()->getScalarSizeInBits() >
+                 DL->getIndexSizeInBits(
+                     V->getType()->getPointerAddressSpace()))) {
           LLVM_DEBUG(dbgs()
                      << "SLP: not-vectorizable GEP (non-constant indexes).\n");
           BS.cancelScheduling(VL, VL0);
@@ -4156,7 +4161,22 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
       std::vector<Value *> OpVecs;
       for (int j = 1, e = cast<GetElementPtrInst>(VL0)->getNumOperands(); j < e;
            ++j) {
-        Value *OpVec = vectorizeTree(E->getOperand(j));
+        ValueList &VL = E->getOperand(j);
+        // Need to cast all elements to the same type before vectorization to
+        // avoid crash.
+        Type *VL0Ty = VL0->getOperand(j)->getType();
+        Type *Ty = llvm::all_of(
+                       VL, [VL0Ty](Value *V) { return VL0Ty == V->getType(); })
+                       ? VL0Ty
+                       : DL->getIndexType(cast<GetElementPtrInst>(VL0)
+                                              ->getPointerOperandType()
+                                              ->getScalarType());
+        for (Value *&V : VL) {
+          auto *CI = cast<ConstantInt>(V);
+          V = ConstantExpr::getIntegerCast(CI, Ty,
+                                           CI->getValue().isSignBitSet());
+        }
+        Value *OpVec = vectorizeTree(VL);
         OpVecs.push_back(OpVec);
       }
 

diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/crash_gep.ll b/llvm/test/Transforms/SLPVectorizer/X86/crash_gep.ll
index eca21e7d3a1a..8fdc72396dd4 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/crash_gep.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/crash_gep.ll
@@ -29,3 +29,26 @@ entry:
   store i64 %2, i64* %add.ptr, align 8
   ret i32 undef
 }
+
+define void @PR43799() {
+; CHECK-LABEL: @PR43799(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[BODY:%.*]]
+; CHECK:       body:
+; CHECK-NEXT:    br label [[BODY]]
+; CHECK:       epilog:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %body
+
+body:
+  %p.1.i19 = phi i8* [ undef, %entry ], [ %incdec.ptr.i.7, %body ]
+  %lsr.iv17 = phi i8* [ undef, %entry ], [ %scevgep113.7, %body ]
+  %incdec.ptr.i.7 = getelementptr inbounds i8, i8* undef, i32 1
+  %scevgep113.7 = getelementptr i8, i8* undef, i64 1
+  br label %body
+
+epilog:
+  ret void
+}


        


More information about the llvm-commits mailing list