summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-10-30 12:51:58 -0400
committerAlexey Bataev <a.bataev@hotmail.com>2019-11-04 10:36:26 -0500
commitb80c41cd3c095c8c4fa739130b560b15bda4bbd0 (patch)
treeaeb8f054edeea8209f818b1d49194311b9036028
parent9ad9d1531b96242bedce3e7f101689bc46322fd2 (diff)
downloadbcm5719-llvm-b80c41cd3c095c8c4fa739130b560b15bda4bbd0.tar.gz
bcm5719-llvm-b80c41cd3c095c8c4fa739130b560b15bda4bbd0.zip
[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
-rw-r--r--llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp24
-rw-r--r--llvm/test/Transforms/SLPVectorizer/X86/crash_gep.ll23
2 files changed, 45 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 986b6be135a..94392ca6a4a 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 eca21e7d3a1..8fdc72396dd 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
+}
OpenPOWER on IntegriCloud