[PATCH] D39467: PR34603 Fix by Early-CSE extension

Evgeny Stupachenko via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 31 11:56:17 PDT 2017


evstupac created this revision.

This is an alternative patch that solves PR34603:
https://bugs.llvm.org/show_bug.cgi?id=34603

Even if it is fixed by https://reviews.llvm.org/D38566 the patch Early-CSE extension could be useful for some cases.


Repository:
  rL LLVM

https://reviews.llvm.org/D39467

Files:
  lib/Transforms/Scalar/EarlyCSE.cpp
  test/Transforms/EarlyCSE/select_load.ll


Index: lib/Transforms/Scalar/EarlyCSE.cpp
===================================================================
--- lib/Transforms/Scalar/EarlyCSE.cpp
+++ lib/Transforms/Scalar/EarlyCSE.cpp
@@ -834,6 +834,62 @@
           continue;
         }
       }
+      // Special replace for a load with selected address:
+      //   a = select p, a1, a2
+      //   b = load a
+      //
+      // if there are existing loads from (or store to) "a1" and "a2":
+      //   b1 = load a1 (store b1 to a1)
+      //   b2 = load a2 (store b2 to a2)
+      //
+      // The load "b = load a" could be replaced with just:
+      //   b = select p, b1, b2
+
+      Value *IP = MemInst.getPointerOperand();
+      if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(IP)) {
+        if (SelectInst *IS = dyn_cast<SelectInst>(GEP->getOperand(0))) {
+          Instruction *IP1 = GEP->clone();
+          Instruction *IP2 = GEP->clone();
+          IP1->setOperand(0, IS->getOperand(1));
+          IP2->setOperand(0, IS->getOperand(2));
+          Value *VPP1 = AvailableValues.lookup(IP1);
+          Value *VPP2 = AvailableValues.lookup(IP2);
+          IP1->deleteValue();
+          IP2->deleteValue();
+          if (VPP1 && VPP2 && IS->hasOneUse()) {
+            LoadValue InVal1 = AvailableLoads.lookup(VPP1);
+            LoadValue InVal2 = AvailableLoads.lookup(VPP2);
+            if (InVal1.DefInst && InVal2.DefInst &&
+                InVal1.MatchingId == MemInst.getMatchingId() &&
+                InVal2.MatchingId == MemInst.getMatchingId() &&
+                !MemInst.isVolatile() && MemInst.isUnordered() &&
+                InVal1.IsAtomic >= MemInst.isAtomic() &&
+                InVal2.IsAtomic >= MemInst.isAtomic() &&
+                ((InVal1.IsInvariant && InVal2.IsInvariant) ||
+                 MemInst.isInvariantLoad() ||
+                 (isSameMemGeneration(InVal1.Generation, CurrentGeneration,
+                                      InVal1.DefInst, Inst) &&
+                  isSameMemGeneration(InVal2.Generation, CurrentGeneration,
+                                      InVal2.DefInst, Inst)))) {
+              Value *Op1 = getOrCreateResult(InVal1.DefInst, Inst->getType());
+              Value *Op2 = getOrCreateResult(InVal2.DefInst, Inst->getType());
+              if (Op1 && Op2) {
+                Value *VV = SelectInst::Create(IS->getOperand(0),
+                                               Op1, Op2, "", Inst);
+                DEBUG(dbgs() << "EarlyCSE CSE LOAD: " << *Inst
+                             << "  to: " << *VV << '\n');
+                if (!Inst->use_empty())
+                  Inst->replaceAllUsesWith(VV);
+                removeMSSA(Inst);
+                Inst->eraseFromParent();
+                Changed = true;
+                ++NumCSELoad;
+                continue;
+              }
+            }
+          }
+        }
+      }
 
       // Otherwise, remember that we have this instruction.
       AvailableLoads.insert(
Index: test/Transforms/EarlyCSE/select_load.ll
===================================================================
--- test/Transforms/EarlyCSE/select_load.ll
+++ test/Transforms/EarlyCSE/select_load.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -S -early-cse | FileCheck %s
+
+; Check that load (with selected address) is deleted
+
+; CHECK-LABEL: @min(
+; CHECK: load i32
+; CHECK: load i32
+; CHECK-NOT: load i32
+
+; Function Attrs: norecurse nounwind readonly uwtable
+define i32 @min(i32* nocapture readonly, i32* nocapture readonly, i32) local_unnamed_addr {
+  %4 = sext i32 %2 to i64
+  %5 = getelementptr inbounds i32, i32* %0, i64 %4
+  %6 = load i32, i32* %5, align 4
+  %7 = getelementptr inbounds i32, i32* %1, i64 %4
+  %8 = load i32, i32* %7, align 4
+  %9 = icmp slt i32 %6, %8
+  %10 = select i1 %9, i32* %0, i32* %1
+  %11 = getelementptr inbounds i32, i32* %10, i64 %4
+  %12 = load i32, i32* %11, align 4
+  ret i32 %12
+}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39467.121030.patch
Type: text/x-patch
Size: 3925 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171031/75ac3d06/attachment.bin>


More information about the llvm-commits mailing list