-
-
Save nikic/ce69a66fdc0985d1af7a56bf024bc860 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit a837a1a0a4b4d8ecdc0276abcf4082582546de7a | |
Author: Nikita Popov <npopov@redhat.com> | |
Date: Thu Jan 12 14:10:50 2023 +0100 | |
rebase | |
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | |
index c8226ce2816a..292bfc536811 100644 | |
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | |
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | |
@@ -261,7 +261,7 @@ class PointerReplacer { | |
public: | |
PointerReplacer(InstCombinerImpl &IC) : IC(IC) {} | |
- bool collectUsers(Instruction &I); | |
+ bool collectUsers(Instruction &I, MemTransferInst *Copy); | |
void replacePointer(Instruction &I, Value *V); | |
private: | |
@@ -274,16 +274,31 @@ private: | |
}; | |
} // end anonymous namespace | |
-bool PointerReplacer::collectUsers(Instruction &I) { | |
+bool PointerReplacer::collectUsers(Instruction &I, MemTransferInst *Copy) { | |
for (auto *U : I.users()) { | |
auto *Inst = cast<Instruction>(&*U); | |
if (auto *Load = dyn_cast<LoadInst>(Inst)) { | |
if (Load->isVolatile()) | |
return false; | |
Worklist.insert(Load); | |
- } else if (isa<GetElementPtrInst>(Inst) || isa<BitCastInst>(Inst)) { | |
+ } else if (auto *PHI = dyn_cast<PHINode>(Inst)) { | |
+ // Check if any of the incoming values of PHI is the destination of Copy | |
+ unsigned CopySrcAddrSpace = Copy->getSourceAddressSpace(); | |
+ unsigned PHIAddrSpace = PHI->getType()->getPointerAddressSpace(); | |
+ for (unsigned Idx = 0; Idx < PHI->getNumIncomingValues(); ++Idx) { | |
+ auto *V = PHI->getIncomingValue(Idx); | |
+ if (CopySrcAddrSpace != PHIAddrSpace && V == Copy->getDest()) | |
+ return false; | |
+ if (auto *Inst = dyn_cast<Instruction>(V)) | |
+ Worklist.insert(Inst); | |
+ } | |
+ | |
+ Worklist.insert(PHI); | |
+ if (!collectUsers(*PHI, Copy)) | |
+ return false; | |
+ } else if (isa<GetElementPtrInst, BitCastInst>(Inst)) { | |
Worklist.insert(Inst); | |
- if (!collectUsers(*Inst)) | |
+ if (!collectUsers(*Inst, Copy)) | |
return false; | |
} else if (auto *MI = dyn_cast<MemTransferInst>(Inst)) { | |
if (MI->isVolatile()) | |
@@ -318,6 +333,14 @@ void PointerReplacer::replace(Instruction *I) { | |
IC.InsertNewInstWith(NewI, *LT); | |
IC.replaceInstUsesWith(*LT, NewI); | |
WorkMap[LT] = NewI; | |
+ } else if (auto *PHI = dyn_cast<PHINode>(I)) { | |
+ Type *NewTy = getReplacement(PHI->getIncomingValue(0))->getType(); | |
+ auto *NewPHI = PHINode::Create(NewTy, PHI->getNumIncomingValues(), | |
+ PHI->getName(), PHI); | |
+ for (unsigned int I = 0; I < PHI->getNumIncomingValues(); ++I) | |
+ NewPHI->addIncoming(getReplacement(PHI->getIncomingValue(I)), | |
+ PHI->getIncomingBlock(I)); | |
+ WorkMap[PHI] = NewPHI; | |
} else if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) { | |
auto *V = getReplacement(GEP->getPointerOperand()); | |
assert(V && "Operand not replaced"); | |
@@ -452,10 +475,9 @@ Instruction *InstCombinerImpl::visitAllocaInst(AllocaInst &AI) { | |
} | |
PointerReplacer PtrReplacer(*this); | |
- if (PtrReplacer.collectUsers(AI)) { | |
+ if (PtrReplacer.collectUsers(AI, Copy)) { | |
for (Instruction *Delete : ToDelete) | |
eraseInstFromFunction(*Delete); | |
- | |
Value *Cast = Builder.CreateBitCast(TheSrc, DestTy); | |
PtrReplacer.replacePointer(AI, Cast); | |
++NumGlobalCopies; | |
diff --git a/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll b/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll | |
index ea9391717ce7..01dbd0dfeeb4 100644 | |
--- a/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll | |
+++ b/llvm/test/Transforms/InstCombine/replace-alloca-phi.ll | |
@@ -9,18 +9,14 @@ target datalayout="p5:32:32-A5" | |
define i8 @remove_alloca_use_arg(i1 %cond) { | |
; CHECK-LABEL: @remove_alloca_use_arg( | |
; CHECK-NEXT: entry: | |
-; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(1) | |
-; CHECK-NEXT: call void @llvm.memcpy.p1.p0.i64(ptr addrspace(1) noundef align 4 dereferenceable(256) [[ALLOCA]], ptr noundef nonnull align 16 dereferenceable(256) @g1, i64 256, i1 false) | |
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] | |
; CHECK: if: | |
-; CHECK-NEXT: [[VAL_IF:%.*]] = getelementptr inbounds [32 x i8], ptr addrspace(1) [[ALLOCA]], i64 0, i64 2 | |
; CHECK-NEXT: br label [[SINK:%.*]] | |
; CHECK: else: | |
-; CHECK-NEXT: [[VAL_ELSE:%.*]] = getelementptr inbounds [32 x i8], ptr addrspace(1) [[ALLOCA]], i64 0, i64 1 | |
; CHECK-NEXT: br label [[SINK]] | |
; CHECK: sink: | |
-; CHECK-NEXT: [[PTR:%.*]] = phi ptr addrspace(1) [ [[VAL_IF]], [[IF]] ], [ [[VAL_ELSE]], [[ELSE]] ] | |
-; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(1) [[PTR]], align 1 | |
+; CHECK-NEXT: [[PTR1:%.*]] = phi ptr [ getelementptr inbounds ([32 x i8], ptr @g1, i64 0, i64 2), [[IF]] ], [ getelementptr inbounds ([32 x i8], ptr @g1, i64 0, i64 1), [[ELSE]] ] | |
+; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[PTR1]], align 1 | |
; CHECK-NEXT: ret i8 [[LOAD]] | |
; | |
entry: | |
@@ -116,18 +112,14 @@ sink: | |
define i8 @loop_phi_remove_alloca(i1 %cond) { | |
; CHECK-LABEL: @loop_phi_remove_alloca( | |
; CHECK-NEXT: entry: | |
-; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(1) | |
-; CHECK-NEXT: call void @llvm.memcpy.p1.p0.i64(ptr addrspace(1) noundef align 4 dereferenceable(256) [[ALLOCA]], ptr noundef nonnull align 16 dereferenceable(256) @g1, i64 256, i1 false) | |
-; CHECK-NEXT: [[VAL1:%.*]] = getelementptr inbounds [32 x i8], ptr addrspace(1) [[ALLOCA]], i64 0, i64 1 | |
; CHECK-NEXT: br label [[BB_0:%.*]] | |
; CHECK: bb.0: | |
-; CHECK-NEXT: [[PTR:%.*]] = phi ptr addrspace(1) [ [[VAL1]], [[ENTRY:%.*]] ], [ [[VAL2:%.*]], [[BB_1:%.*]] ] | |
+; CHECK-NEXT: [[PTR1:%.*]] = phi ptr [ getelementptr inbounds ([32 x i8], ptr @g1, i64 0, i64 1), [[ENTRY:%.*]] ], [ getelementptr inbounds ([32 x i8], ptr @g1, i64 0, i64 2), [[BB_1:%.*]] ] | |
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB_1]], label [[EXIT:%.*]] | |
; CHECK: bb.1: | |
-; CHECK-NEXT: [[VAL2]] = getelementptr inbounds [32 x i8], ptr addrspace(1) [[ALLOCA]], i64 0, i64 2 | |
; CHECK-NEXT: br label [[BB_0]] | |
; CHECK: exit: | |
-; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(1) [[PTR]], align 1 | |
+; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[PTR1]], align 1 | |
; CHECK-NEXT: ret i8 [[LOAD]] | |
; | |
entry: | |
@@ -177,18 +169,14 @@ join: | |
define i8 @loop_phi_late_memtransfer(i1 %cond) { | |
; CHECK-LABEL: @loop_phi_late_memtransfer( | |
; CHECK-NEXT: entry: | |
-; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 4, addrspace(1) | |
-; CHECK-NEXT: [[VAL1:%.*]] = getelementptr inbounds [32 x i8], ptr addrspace(1) [[ALLOCA]], i64 0, i64 1 | |
; CHECK-NEXT: br label [[BB_0:%.*]] | |
; CHECK: bb.0: | |
-; CHECK-NEXT: [[PTR:%.*]] = phi ptr addrspace(1) [ [[VAL1]], [[ENTRY:%.*]] ], [ [[VAL2:%.*]], [[BB_1:%.*]] ] | |
+; CHECK-NEXT: [[PTR1:%.*]] = phi ptr [ getelementptr inbounds ([32 x i8], ptr @g1, i64 0, i64 1), [[ENTRY:%.*]] ], [ getelementptr inbounds ([32 x i8], ptr @g1, i64 0, i64 2), [[BB_1:%.*]] ] | |
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB_1]], label [[EXIT:%.*]] | |
; CHECK: bb.1: | |
-; CHECK-NEXT: [[VAL2]] = getelementptr inbounds [32 x i8], ptr addrspace(1) [[ALLOCA]], i64 0, i64 2 | |
-; CHECK-NEXT: call void @llvm.memcpy.p1.p0.i64(ptr addrspace(1) noundef align 4 dereferenceable(256) [[ALLOCA]], ptr noundef nonnull align 16 dereferenceable(256) @g1, i64 256, i1 false) | |
; CHECK-NEXT: br label [[BB_0]] | |
; CHECK: exit: | |
-; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(1) [[PTR]], align 1 | |
+; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[PTR1]], align 1 | |
; CHECK-NEXT: ret i8 [[LOAD]] | |
; | |
entry: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment