[PATCH] D96979: [DSE] Extending IsGuaranteedLoopInvariant to support a GetElementPtrInst defined in the entry block

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 23 04:01:17 PST 2021


This revision was automatically updated to reflect the committed changes.
Closed by commit rG633e090528db: [DSE] Allow ptrs defined in the entry block in IsGuaranteedLoopInvariant. (authored by fvrmatteo, committed by fhahn).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96979/new/

https://reviews.llvm.org/D96979

Files:
  llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
  llvm/test/Transforms/DeadStoreElimination/MSSA/loop-invariant-entry-block.ll


Index: llvm/test/Transforms/DeadStoreElimination/MSSA/loop-invariant-entry-block.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/DeadStoreElimination/MSSA/loop-invariant-entry-block.ll
@@ -0,0 +1,49 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -dse -S | FileCheck %s
+
+ at BUFFER = external dso_local local_unnamed_addr global [0 x i8], align 1
+
+define void @MissedDSEOpportunity(i64 %idx, i1* noalias %cc) {
+;
+; The DSE pass will try to kill the store in the loop exit block using the
+; store in the function exit block. The loop invariant check on the pointer
+; used by the stores should trivially return true because a pointer defined
+; in the entry block of a function is loop invariant by definition. In fact
+; the entry block of a function cannot have predecessors or be part of a loop.
+;
+; CHECK-LABEL: @MissedDSEOpportunity(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 [[IDX:%.*]]
+; CHECK-NEXT:    [[BC:%.*]] = bitcast i8* [[GEP]] to i64*
+; CHECK-NEXT:    [[CC0:%.*]] = load volatile i1, i1* [[CC:%.*]], align 1
+; CHECK-NEXT:    br i1 [[CC0]], label [[HEAD:%.*]], label [[EXIT:%.*]]
+; CHECK:       head:
+; CHECK-NEXT:    [[CC1:%.*]] = load volatile i1, i1* [[CC]], align 1
+; CHECK-NEXT:    br i1 [[CC1]], label [[HEAD]], label [[EXIT_LOOPEXIT:%.*]]
+; CHECK:       exit.loopexit:
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    store i64 0, i64* [[BC]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  ; The entry block cannot have predecessors or be part of a loop
+  %gep = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 %idx
+  %bc = bitcast i8* %gep to i64*
+  %cc0 = load volatile i1, i1* %cc, align 1
+  br i1 %cc0, label %head, label %exit
+
+head:                                             ; preds = %entry, %head
+  %cc1 = load volatile i1, i1* %cc, align 1
+  br i1 %cc1, label %head, label %exit.loopexit
+
+exit.loopexit:                                    ; preds = %head
+  ; Dead store
+  store i64 2, i64* %bc, align 4
+  br label %exit
+
+exit:                                             ; preds = %exit.loopexit, %entry
+  ; Killer store
+  store i64 0, i64* %bc, align 4
+  ret void
+}
\ No newline at end of file
Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1911,6 +1911,11 @@
     };
 
     Ptr = Ptr->stripPointerCasts();
+    if (auto *I = dyn_cast<Instruction>(Ptr)) {
+      if (I->getParent() == &I->getFunction()->getEntryBlock()) {
+        return true;
+      }
+    }
     if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
       return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) &&
              GEP->hasAllConstantIndices();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D96979.325736.patch
Type: text/x-patch
Size: 3020 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210223/56ec427e/attachment.bin>


More information about the llvm-commits mailing list