forked from OSchip/llvm-project
[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
This commit is contained in:
parent
9ad9d1531b
commit
b80c41cd3c
|
@ -2638,9 +2638,14 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't combine GEPs with non-constant indexes.
|
// We don't combine GEPs with non-constant indexes.
|
||||||
|
Type *Ty1 = VL0->getOperand(1)->getType();
|
||||||
for (Value *V : VL) {
|
for (Value *V : VL) {
|
||||||
auto Op = cast<Instruction>(V)->getOperand(1);
|
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()
|
LLVM_DEBUG(dbgs()
|
||||||
<< "SLP: not-vectorizable GEP (non-constant indexes).\n");
|
<< "SLP: not-vectorizable GEP (non-constant indexes).\n");
|
||||||
BS.cancelScheduling(VL, VL0);
|
BS.cancelScheduling(VL, VL0);
|
||||||
|
@ -4156,7 +4161,22 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
|
||||||
std::vector<Value *> OpVecs;
|
std::vector<Value *> OpVecs;
|
||||||
for (int j = 1, e = cast<GetElementPtrInst>(VL0)->getNumOperands(); j < e;
|
for (int j = 1, e = cast<GetElementPtrInst>(VL0)->getNumOperands(); j < e;
|
||||||
++j) {
|
++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);
|
OpVecs.push_back(OpVec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,3 +29,26 @@ entry:
|
||||||
store i64 %2, i64* %add.ptr, align 8
|
store i64 %2, i64* %add.ptr, align 8
|
||||||
ret i32 undef
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue