mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[NaryReassociate] allow candidate to have a different type
Summary: If Candiadte may have a different type from GEP, we should bitcast or pointer cast it to GEP's type so that the later RAUW doesn't complain. Added a test in nary-gep.ll Reviewers: tra, meheff Subscribers: mcrosier, llvm-commits, jholewinski Differential Revision: http://reviews.llvm.org/D15618 llvm-svn: 256035
This commit is contained in:
parent
0cdfda8077
commit
6c0c800317
@ -421,19 +421,20 @@ GetElementPtrInst *NaryReassociate::tryReassociateGEPAtIndex(
|
|||||||
GEP->getSourceElementType(), SE->getSCEV(GEP->getPointerOperand()),
|
GEP->getSourceElementType(), SE->getSCEV(GEP->getPointerOperand()),
|
||||||
IndexExprs, GEP->isInBounds());
|
IndexExprs, GEP->isInBounds());
|
||||||
|
|
||||||
auto *Candidate = findClosestMatchingDominator(CandidateExpr, GEP);
|
Value *Candidate = findClosestMatchingDominator(CandidateExpr, GEP);
|
||||||
if (Candidate == nullptr)
|
if (Candidate == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
PointerType *TypeOfCandidate = dyn_cast<PointerType>(Candidate->getType());
|
IRBuilder<> Builder(GEP);
|
||||||
// Pretty rare but theoretically possible when a numeric value happens to
|
// Candidate does not necessarily have the same pointer type as GEP. Use
|
||||||
// share CandidateExpr.
|
// bitcast or pointer cast to make sure they have the same type, so that the
|
||||||
if (TypeOfCandidate == nullptr)
|
// later RAUW doesn't complain.
|
||||||
return nullptr;
|
Candidate = Builder.CreateBitOrPointerCast(Candidate, GEP->getType());
|
||||||
|
assert(Candidate->getType() == GEP->getType());
|
||||||
|
|
||||||
// NewGEP = (char *)Candidate + RHS * sizeof(IndexedType)
|
// NewGEP = (char *)Candidate + RHS * sizeof(IndexedType)
|
||||||
uint64_t IndexedSize = DL->getTypeAllocSize(IndexedType);
|
uint64_t IndexedSize = DL->getTypeAllocSize(IndexedType);
|
||||||
Type *ElementType = TypeOfCandidate->getElementType();
|
Type *ElementType = GEP->getType()->getElementType();
|
||||||
uint64_t ElementSize = DL->getTypeAllocSize(ElementType);
|
uint64_t ElementSize = DL->getTypeAllocSize(ElementType);
|
||||||
// Another less rare case: because I is not necessarily the last index of the
|
// Another less rare case: because I is not necessarily the last index of the
|
||||||
// GEP, the size of the type at the I-th index (IndexedSize) is not
|
// GEP, the size of the type at the I-th index (IndexedSize) is not
|
||||||
@ -453,8 +454,7 @@ GetElementPtrInst *NaryReassociate::tryReassociateGEPAtIndex(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// NewGEP = &Candidate[RHS * (sizeof(IndexedType) / sizeof(Candidate[0])));
|
// NewGEP = &Candidate[RHS * (sizeof(IndexedType) / sizeof(Candidate[0])));
|
||||||
IRBuilder<> Builder(GEP);
|
Type *IntPtrTy = DL->getIntPtrType(GEP->getType());
|
||||||
Type *IntPtrTy = DL->getIntPtrType(TypeOfCandidate);
|
|
||||||
if (RHS->getType() != IntPtrTy)
|
if (RHS->getType() != IntPtrTy)
|
||||||
RHS = Builder.CreateSExtOrTrunc(RHS, IntPtrTy);
|
RHS = Builder.CreateSExtOrTrunc(RHS, IntPtrTy);
|
||||||
if (IndexedSize != ElementSize) {
|
if (IndexedSize != ElementSize) {
|
||||||
|
@ -123,4 +123,21 @@ define void @reassociate_gep_128(float* %a, i128 %i, i128 %j) {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%struct.complex = type { float, float }
|
||||||
|
|
||||||
|
declare void @bar(%struct.complex*)
|
||||||
|
|
||||||
|
define void @different_types(%struct.complex* %input, i64 %i) {
|
||||||
|
; CHECK-LABEL: @different_types(
|
||||||
|
%t1 = getelementptr %struct.complex, %struct.complex* %input, i64 %i
|
||||||
|
call void @bar(%struct.complex* %t1)
|
||||||
|
%j = add i64 %i, 5
|
||||||
|
%t2 = getelementptr %struct.complex, %struct.complex* %input, i64 %j, i32 0
|
||||||
|
; CHECK: [[cast:[^ ]+]] = bitcast %struct.complex* %t1 to float*
|
||||||
|
; CHECK-NEXT: %t2 = getelementptr float, float* [[cast]], i64 10
|
||||||
|
; CHECK-NEXT: call void @foo(float* %t2)
|
||||||
|
call void @foo(float* %t2)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
declare void @llvm.assume(i1)
|
declare void @llvm.assume(i1)
|
||||||
|
Loading…
Reference in New Issue
Block a user