mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 23:48:56 +00:00
Fixed GEP visitor in the InstCombine pass.
The current implementation of GEP visitor in InstCombine fails with assertion on Vector GEP with mix of scalar and vector types, like this: getelementptr double, double* %a, <8 x i32> %i (It fails to create a "sext" from <8 x i32> to <8 x i64>) I fixed it and added some tests. Differential Revision: http://reviews.llvm.org/D14485 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253162 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
42aedb2949
commit
f79c5ce90b
@ -1355,7 +1355,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
// Eliminate unneeded casts for indices, and replace indices which displace
|
||||
// by multiples of a zero size type with zero.
|
||||
bool MadeChange = false;
|
||||
Type *IntPtrTy = DL.getIntPtrType(GEP.getPointerOperandType());
|
||||
Type *IntPtrTy =
|
||||
DL.getIntPtrType(GEP.getPointerOperandType()->getScalarType());
|
||||
|
||||
gep_type_iterator GTI = gep_type_begin(GEP);
|
||||
for (User::op_iterator I = GEP.op_begin() + 1, E = GEP.op_end(); I != E;
|
||||
@ -1365,21 +1366,25 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
if (!SeqTy)
|
||||
continue;
|
||||
|
||||
// Index type should have the same width as IntPtr
|
||||
Type *IndexTy = (*I)->getType();
|
||||
Type *NewIndexType = IndexTy->isVectorTy() ?
|
||||
VectorType::get(IntPtrTy, IndexTy->getVectorNumElements()) : IntPtrTy;
|
||||
|
||||
// If the element type has zero size then any index over it is equivalent
|
||||
// to an index of zero, so replace it with zero if it is not zero already.
|
||||
if (SeqTy->getElementType()->isSized() &&
|
||||
DL.getTypeAllocSize(SeqTy->getElementType()) == 0)
|
||||
if (!isa<Constant>(*I) || !cast<Constant>(*I)->isNullValue()) {
|
||||
*I = Constant::getNullValue(IntPtrTy);
|
||||
*I = Constant::getNullValue(NewIndexType);
|
||||
MadeChange = true;
|
||||
}
|
||||
|
||||
Type *IndexTy = (*I)->getType();
|
||||
if (IndexTy != IntPtrTy) {
|
||||
if (IndexTy != NewIndexType) {
|
||||
// If we are using a wider index than needed for this platform, shrink
|
||||
// it to what we need. If narrower, sign-extend it to what we need.
|
||||
// This explicit cast can make subsequent optimizations more obvious.
|
||||
*I = Builder->CreateIntCast(*I, IntPtrTy, true);
|
||||
*I = Builder->CreateIntCast(*I, NewIndexType, true);
|
||||
MadeChange = true;
|
||||
}
|
||||
}
|
||||
|
@ -9,3 +9,26 @@ define <2 x i8*> @testa(<2 x i8*> %a) {
|
||||
; CHECK: getelementptr i8, <2 x i8*> %a, <2 x i64> <i64 0, i64 1>
|
||||
ret <2 x i8*> %g
|
||||
}
|
||||
|
||||
define <8 x double*> @vgep_s_v8i64(double* %a, <8 x i64>%i) {
|
||||
; CHECK-LABEL: @vgep_s_v8i64
|
||||
; CHECK: getelementptr double, double* %a, <8 x i64> %i
|
||||
%VectorGep = getelementptr double, double* %a, <8 x i64> %i
|
||||
ret <8 x double*> %VectorGep
|
||||
}
|
||||
|
||||
define <8 x double*> @vgep_s_v8i32(double* %a, <8 x i32>%i) {
|
||||
; CHECK-LABEL: @vgep_s_v8i32
|
||||
; CHECK: %1 = sext <8 x i32> %i to <8 x i64>
|
||||
; CHECK: getelementptr double, double* %a, <8 x i64> %1
|
||||
%VectorGep = getelementptr double, double* %a, <8 x i32> %i
|
||||
ret <8 x double*> %VectorGep
|
||||
}
|
||||
|
||||
define <8 x i8*> @vgep_v8iPtr_i32(<8 x i8*> %a, i32 %i) {
|
||||
; CHECK-LABEL: @vgep_v8iPtr_i32
|
||||
; CHECK: %1 = sext i32 %i to i64
|
||||
; CHECK: %VectorGep = getelementptr i8, <8 x i8*> %a, i64 %1
|
||||
%VectorGep = getelementptr i8, <8 x i8*> %a, i32 %i
|
||||
ret <8 x i8*> %VectorGep
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user