mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[InstCombine] Simplify gep (gep p, a), (b-a)
Patch by Andrea Canciani. Differential Revision: https://reviews.llvm.org/D27413 llvm-svn: 292506
This commit is contained in:
parent
915800c7e4
commit
97a0cbad8b
@ -1559,27 +1559,21 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
|||||||
// Replace: gep (gep %P, long B), long A, ...
|
// Replace: gep (gep %P, long B), long A, ...
|
||||||
// With: T = long A+B; gep %P, T, ...
|
// With: T = long A+B; gep %P, T, ...
|
||||||
//
|
//
|
||||||
Value *Sum;
|
|
||||||
Value *SO1 = Src->getOperand(Src->getNumOperands()-1);
|
Value *SO1 = Src->getOperand(Src->getNumOperands()-1);
|
||||||
Value *GO1 = GEP.getOperand(1);
|
Value *GO1 = GEP.getOperand(1);
|
||||||
if (SO1 == Constant::getNullValue(SO1->getType())) {
|
|
||||||
Sum = GO1;
|
// If they aren't the same type, then the input hasn't been processed
|
||||||
} else if (GO1 == Constant::getNullValue(GO1->getType())) {
|
// by the loop above yet (which canonicalizes sequential index types to
|
||||||
Sum = SO1;
|
// intptr_t). Just avoid transforming this until the input has been
|
||||||
} else {
|
// normalized.
|
||||||
// If they aren't the same type, then the input hasn't been processed
|
if (SO1->getType() != GO1->getType())
|
||||||
// by the loop above yet (which canonicalizes sequential index types to
|
return nullptr;
|
||||||
// intptr_t). Just avoid transforming this until the input has been
|
|
||||||
// normalized.
|
Value* Sum = SimplifyAddInst(GO1, SO1, false, false, DL, &TLI, &DT, &AC);
|
||||||
if (SO1->getType() != GO1->getType())
|
// Only do the combine when we are sure the cost after the
|
||||||
return nullptr;
|
// merge is never more than that before the merge.
|
||||||
// Only do the combine when GO1 and SO1 are both constants. Only in
|
if (Sum == nullptr)
|
||||||
// this case, we are sure the cost after the merge is never more than
|
return nullptr;
|
||||||
// that before the merge.
|
|
||||||
if (!isa<Constant>(GO1) || !isa<Constant>(SO1))
|
|
||||||
return nullptr;
|
|
||||||
Sum = Builder->CreateAdd(SO1, GO1, PtrOp->getName()+".sum");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the GEP in place if possible.
|
// Update the GEP in place if possible.
|
||||||
if (Src->getNumOperands() == 2) {
|
if (Src->getNumOperands() == 2) {
|
||||||
|
@ -883,6 +883,33 @@ define %struct.C* @test46(%struct.C* %c1, %struct.C* %c2, i64 %N) {
|
|||||||
; CHECK-NEXT: ret %struct.C* [[GEP]]
|
; CHECK-NEXT: ret %struct.C* [[GEP]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i32* @test47(i32* %I, i64 %C, i64 %D) {
|
||||||
|
%sub = sub i64 %D, %C
|
||||||
|
%A = getelementptr i32, i32* %I, i64 %C
|
||||||
|
%B = getelementptr i32, i32* %A, i64 %sub
|
||||||
|
ret i32* %B
|
||||||
|
; CHECK-LABEL: @test47(
|
||||||
|
; CHECK-NEXT: %B = getelementptr i32, i32* %I, i64 %D
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32* @test48(i32* %I, i64 %C, i64 %D) {
|
||||||
|
%sub = sub i64 %D, %C
|
||||||
|
%A = getelementptr i32, i32* %I, i64 %sub
|
||||||
|
%B = getelementptr i32, i32* %A, i64 %C
|
||||||
|
ret i32* %B
|
||||||
|
; CHECK-LABEL: @test48(
|
||||||
|
; CHECK-NEXT: %B = getelementptr i32, i32* %I, i64 %D
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32* @test49(i32* %I, i64 %C) {
|
||||||
|
%notC = xor i64 -1, %C
|
||||||
|
%A = getelementptr i32, i32* %I, i64 %C
|
||||||
|
%B = getelementptr i32, i32* %A, i64 %notC
|
||||||
|
ret i32* %B
|
||||||
|
; CHECK-LABEL: @test49(
|
||||||
|
; CHECK-NEXT: %B = getelementptr i32, i32* %I, i64 -1
|
||||||
|
}
|
||||||
|
|
||||||
define i32 addrspace(1)* @ascast_0_gep(i32* %p) nounwind {
|
define i32 addrspace(1)* @ascast_0_gep(i32* %p) nounwind {
|
||||||
; CHECK-LABEL: @ascast_0_gep(
|
; CHECK-LABEL: @ascast_0_gep(
|
||||||
; CHECK-NOT: getelementptr
|
; CHECK-NOT: getelementptr
|
||||||
|
Loading…
Reference in New Issue
Block a user