[PATCH] D136201: [InstCombine] Replace alloca with phi uses

Anshil Gandhi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 18 13:38:18 PDT 2022


gandhi21299 created this revision.
gandhi21299 added reviewers: majnemer, yaxunl, arsenm.
Herald added a subscriber: hiraditya.
Herald added a project: All.
gandhi21299 requested review of this revision.
Herald added subscribers: llvm-commits, wdng.
Herald added a project: LLVM.

This patch allows iterating over PHI uses of an alloca when
determining whether an alloca is only ever modified by a
copy from global constant. Since PHI does not modify the
memory allocated by the alloca instruction in question,
we can safely add the incoming values of the PHI to the
worklist for replacement and furthermore, the PHI itself
as well. Define a new PHI as a copy of the old PHI except
with its operands replaced according the WorkMap.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136201

Files:
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/test/Transforms/InstCombine/replace-alloca-phi.ll


Index: llvm/test/Transforms/InstCombine/replace-alloca-phi.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/replace-alloca-phi.ll
@@ -0,0 +1,21 @@
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -passes=instcombine -S -o - %s | FileCheck %s
+
+; CHECK-LABEL: @remove_alloca
+define i8 @remove_alloca(i1 %flag, i32 %idx, [32 x i8] addrspace(4)* align 8 %arg) {
+entry:
+  %xp = alloca [32 x i8], align 8, addrspace(5)
+  call void @llvm.memcpy.p5.p4.i64([32 x i8] addrspace(5)* align 8 %xp, [32 x i8] addrspace(4)* align 8 %arg, i64 1360, i1 false)
+  br i1 %flag, label %true, label %false
+true:
+  %gep.true = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %xp, i32 0, i32 0
+  br label %sink
+false:
+  %gep.false = getelementptr inbounds [32 x i8], [32 x i8] addrspace(5)* %xp, i32 0, i32 0
+  br label %sink
+sink:
+  %x.2 = phi i8 addrspace(5)* [%gep.true, %true], [%gep.false, %false]
+  %x.3 = load i8, i8 addrspace(5)* %x.2, align 4
+  ret i8 %x.3
+}
+
+declare void @llvm.memcpy.p5.p4.i64([32 x i8] addrspace(5)* align 8, [32 x i8] addrspace(4)* align 8, i64, i1)
Index: llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -53,7 +53,8 @@
     const bool IsOffset = ValuePair.second;
     for (auto &U : ValuePair.first->uses()) {
       auto *I = cast<Instruction>(U.getUser());
-
+      if (isa<PHINode>(I))
+        continue;
       if (auto *LI = dyn_cast<LoadInst>(I)) {
         // Ignore non-volatile loads, they are always ok.
         if (!LI->isSimple()) return false;
@@ -256,6 +257,10 @@
       if (Load->isVolatile())
         return false;
       Worklist.insert(Load);
+    } else if (auto *PHI = dyn_cast<PHINode>(Inst)) {
+      for (unsigned int I = 0; I < PHI->getNumOperands(); ++I)
+        Worklist.insert(cast<Instruction>(PHI->getOperand(I)));
+      Worklist.insert(PHI);
     } else if (isa<GetElementPtrInst>(Inst) || isa<BitCastInst>(Inst)) {
       Worklist.insert(Inst);
       if (!collectUsers(*Inst))
@@ -293,6 +298,18 @@
     IC.InsertNewInstWith(NewI, *LT);
     IC.replaceInstUsesWith(*LT, NewI);
     WorkMap[LT] = NewI;
+  } else if (auto *PHI = dyn_cast<PHINode>(I)) {
+    SmallVector<Value *, 8> ReplacedOperands;
+    for (unsigned int I = 0; I < PHI->getNumOperands(); ++I) {
+      ReplacedOperands.push_back(getReplacement(PHI->getOperand(I)));
+      assert(ReplacedOperands.back() && "Operand not replaced");
+    }
+    auto *NewPHI = PHINode::Create(PHI->getType(), PHI->getNumIncomingValues(),
+                                   PHI->getName());
+    NewPHI->takeName(PHI);
+    IC.InsertNewInstWith(NewPHI, *PHI);
+    IC.replaceInstUsesWith(*PHI, NewPHI);
+    WorkMap[PHI] = NewPHI;
   } else if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
     auto *V = getReplacement(GEP->getPointerOperand());
     assert(V && "Operand not replaced");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D136201.468678.patch
Type: text/x-patch
Size: 3109 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221018/39d17a98/attachment.bin>


More information about the llvm-commits mailing list