forked from OSchip/llvm-project
Fix assert with GEP ptr vector indexing structs
Also fix it calculating the wrong value. The struct index is not a ConstantInt, so it was being interpreted as an array index. llvm-svn: 188713
This commit is contained in:
parent
9309322454
commit
74742a1bb0
|
@ -203,12 +203,17 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
|
||||||
++i, ++GTI) {
|
++i, ++GTI) {
|
||||||
Value *Op = *i;
|
Value *Op = *i;
|
||||||
uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
|
uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
|
||||||
if (ConstantInt *OpC = dyn_cast<ConstantInt>(Op)) {
|
if (Constant *OpC = dyn_cast<Constant>(Op)) {
|
||||||
if (OpC->isZero()) continue;
|
if (OpC->isZeroValue())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Handle a struct index, which adds its field offset to the pointer.
|
// Handle a struct index, which adds its field offset to the pointer.
|
||||||
if (StructType *STy = dyn_cast<StructType>(*GTI)) {
|
if (StructType *STy = dyn_cast<StructType>(*GTI)) {
|
||||||
Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
|
if (OpC->getType()->isVectorTy())
|
||||||
|
OpC = OpC->getSplatValue();
|
||||||
|
|
||||||
|
uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue();
|
||||||
|
Size = TD.getStructLayout(STy)->getElementOffset(OpValue);
|
||||||
|
|
||||||
if (Size)
|
if (Size)
|
||||||
Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
|
Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
|
||||||
|
|
|
@ -629,9 +629,19 @@ void llvm::ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
|
||||||
Value *Index = I->getOperand(i);
|
Value *Index = I->getOperand(i);
|
||||||
if (StructType *STy = dyn_cast<StructType>(*GTI)) {
|
if (StructType *STy = dyn_cast<StructType>(*GTI)) {
|
||||||
// Handle struct member offset arithmetic.
|
// Handle struct member offset arithmetic.
|
||||||
if (!TD) return;
|
if (!TD)
|
||||||
const StructLayout *SL = TD->getStructLayout(STy);
|
return;
|
||||||
|
|
||||||
|
// Handle case when index is vector zeroinitializer
|
||||||
|
Constant *CIndex = cast<Constant>(Index);
|
||||||
|
if (CIndex->isZeroValue())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (CIndex->getType()->isVectorTy())
|
||||||
|
Index = CIndex->getSplatValue();
|
||||||
|
|
||||||
unsigned Idx = cast<ConstantInt>(Index)->getZExtValue();
|
unsigned Idx = cast<ConstantInt>(Index)->getZExtValue();
|
||||||
|
const StructLayout *SL = TD->getStructLayout(STy);
|
||||||
uint64_t Offset = SL->getElementOffset(Idx);
|
uint64_t Offset = SL->getElementOffset(Idx);
|
||||||
TrailZ = std::min<unsigned>(TrailZ,
|
TrailZ = std::min<unsigned>(TrailZ,
|
||||||
countTrailingZeros(Offset));
|
countTrailingZeros(Offset));
|
||||||
|
|
|
@ -129,6 +129,17 @@ define i1 @test13(i64 %X, %S* %P) {
|
||||||
; CHECK: %C = icmp eq i64 %X, -1
|
; CHECK: %C = icmp eq i64 %X, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define <2 x i1> @test13_vector(<2 x i64> %X, <2 x %S*> %P) nounwind {
|
||||||
|
; CHECK-LABEL: @test13_vector(
|
||||||
|
; CHECK-NEXT: shl nuw <2 x i64> %X, <i64 2, i64 2>
|
||||||
|
; CHECK-NEXT: add <2 x i64> %A.idx, <i64 4, i64 4>
|
||||||
|
; CHECK-NEXT: icmp eq <2 x i64> %A.offs, zeroinitializer
|
||||||
|
%A = getelementptr inbounds <2 x %S*> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, <2 x i64> %X
|
||||||
|
%B = getelementptr inbounds <2 x %S*> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>
|
||||||
|
%C = icmp eq <2 x i32*> %A, %B
|
||||||
|
ret <2 x i1> %C
|
||||||
|
}
|
||||||
|
|
||||||
define i1 @test13_i32(i32 %X, %S* %P) {
|
define i1 @test13_i32(i32 %X, %S* %P) {
|
||||||
; CHECK-LABEL: @test13_i32(
|
; CHECK-LABEL: @test13_i32(
|
||||||
; CHECK: %C = icmp eq i32 %X, -1
|
; CHECK: %C = icmp eq i32 %X, -1
|
||||||
|
|
Loading…
Reference in New Issue