[PATCH] D41026: [InstComineLoadStoreAlloca] Optimize stores to GEP off null base

Anna Thomas via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 8 10:40:01 PST 2017


anna created this revision.

Currently, in InstCombineLoadStoreAlloca, we have simplification rules
for the following cases:

1. load off a null
2. load off a GEP with null base
3. store to a null

This patch adds support for the fourth case which is store into a GEP with null
base. Since this is UB as well (and directly analogous to the load off a
GEP with null base), we can substitute the stored val with
undef in instcombine, so that SimplifyCFG can optimize this code into
unreachable code.

Note: Right now, simplifyCFG hasn't been taught about optimizing this to
unreachable and adding an llvm.trap (this is already done for the above 3 cases).

I would like to confirm whether this is just a missed optimization, or
there is something fundamental that prevents this transformation.


https://reviews.llvm.org/D41026

Files:
  lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  test/Transforms/InstCombine/store.ll


Index: test/Transforms/InstCombine/store.ll
===================================================================
--- test/Transforms/InstCombine/store.ll
+++ test/Transforms/InstCombine/store.ll
@@ -20,6 +20,14 @@
 ; CHECK-NEXT: ret void
 }
 
+define void @store_at_gep_off_null(i64 %offset) {
+; CHECK-LABEL: @store_at_gep_off_null
+; CHECK: store i32 undef, i32* %ptr
+   %ptr = getelementptr i32, i32 *null, i64 %offset
+   store i32 24, i32* %ptr
+   ret void
+}
+
 ;; Simple sinking tests
 
 ; "if then else"
Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -931,6 +931,18 @@
   return nullptr;
 }
 
+static bool canSimplifyNullStoreOrGEP(StoreInst &SI) {
+  auto *Ptr = SI.getPointerOperand();
+  if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Ptr)) {
+    const Value *GEPI0 = GEPI->getOperand(0);
+    if (isa<ConstantPointerNull>(GEPI0) && GEPI->getPointerAddressSpace() == 0)
+      return true;
+  }
+  if (isa<ConstantPointerNull>(Ptr) && SI.getPointerAddressSpace() == 0)
+    return true;
+  return false;
+}
+
 static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) {
   if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op)) {
     const Value *GEPI0 = GEPI->getOperand(0);
@@ -1392,7 +1404,8 @@
   }
 
   // store X, null    -> turns into 'unreachable' in SimplifyCFG
-  if (isa<ConstantPointerNull>(Ptr) && SI.getPointerAddressSpace() == 0) {
+  // store X, GEP(null, Y) -> turns into 'unreachable' in SimplifyCFG
+  if (canSimplifyNullStoreOrGEP(SI)) {
     if (!isa<UndefValue>(Val)) {
       SI.setOperand(0, UndefValue::get(Val->getType()));
       if (Instruction *U = dyn_cast<Instruction>(Val))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41026.126183.patch
Type: text/x-patch
Size: 1856 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171208/e1118061/attachment.bin>


More information about the llvm-commits mailing list