Skip to content

Commit b80c41c

Browse files
committed
[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
1 parent 9ad9d15 commit b80c41c

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,9 +2638,14 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
26382638
}
26392639

26402640
// We don't combine GEPs with non-constant indexes.
2641+
Type *Ty1 = VL0->getOperand(1)->getType();
26412642
for (Value *V : VL) {
26422643
auto Op = cast<Instruction>(V)->getOperand(1);
2643-
if (!isa<ConstantInt>(Op)) {
2644+
if (!isa<ConstantInt>(Op) ||
2645+
(Op->getType() != Ty1 &&
2646+
Op->getType()->getScalarSizeInBits() >
2647+
DL->getIndexSizeInBits(
2648+
V->getType()->getPointerAddressSpace()))) {
26442649
LLVM_DEBUG(dbgs()
26452650
<< "SLP: not-vectorizable GEP (non-constant indexes).\n");
26462651
BS.cancelScheduling(VL, VL0);
@@ -4156,7 +4161,22 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
41564161
std::vector<Value *> OpVecs;
41574162
for (int j = 1, e = cast<GetElementPtrInst>(VL0)->getNumOperands(); j < e;
41584163
++j) {
4159-
Value *OpVec = vectorizeTree(E->getOperand(j));
4164+
ValueList &VL = E->getOperand(j);
4165+
// Need to cast all elements to the same type before vectorization to
4166+
// avoid crash.
4167+
Type *VL0Ty = VL0->getOperand(j)->getType();
4168+
Type *Ty = llvm::all_of(
4169+
VL, [VL0Ty](Value *V) { return VL0Ty == V->getType(); })
4170+
? VL0Ty
4171+
: DL->getIndexType(cast<GetElementPtrInst>(VL0)
4172+
->getPointerOperandType()
4173+
->getScalarType());
4174+
for (Value *&V : VL) {
4175+
auto *CI = cast<ConstantInt>(V);
4176+
V = ConstantExpr::getIntegerCast(CI, Ty,
4177+
CI->getValue().isSignBitSet());
4178+
}
4179+
Value *OpVec = vectorizeTree(VL);
41604180
OpVecs.push_back(OpVec);
41614181
}
41624182

llvm/test/Transforms/SLPVectorizer/X86/crash_gep.ll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,26 @@ entry:
2929
store i64 %2, i64* %add.ptr, align 8
3030
ret i32 undef
3131
}
32+
33+
define void @PR43799() {
34+
; CHECK-LABEL: @PR43799(
35+
; CHECK-NEXT: entry:
36+
; CHECK-NEXT: br label [[BODY:%.*]]
37+
; CHECK: body:
38+
; CHECK-NEXT: br label [[BODY]]
39+
; CHECK: epilog:
40+
; CHECK-NEXT: ret void
41+
;
42+
entry:
43+
br label %body
44+
45+
body:
46+
%p.1.i19 = phi i8* [ undef, %entry ], [ %incdec.ptr.i.7, %body ]
47+
%lsr.iv17 = phi i8* [ undef, %entry ], [ %scevgep113.7, %body ]
48+
%incdec.ptr.i.7 = getelementptr inbounds i8, i8* undef, i32 1
49+
%scevgep113.7 = getelementptr i8, i8* undef, i64 1
50+
br label %body
51+
52+
epilog:
53+
ret void
54+
}

0 commit comments

Comments
 (0)