[PATCH] D34311: [InstCombine] Don't replace allocas with globals if we can't prove that it's large enough.

Vitaly Buka via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 20 14:12:25 PDT 2017


vitalybuka updated this revision to Diff 103266.
vitalybuka added a comment.

Removed assert and getZExtValue


https://reviews.llvm.org/D34311

Files:
  lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  test/Transforms/InstCombine/memcpy-from-global.ll


Index: test/Transforms/InstCombine/memcpy-from-global.ll
===================================================================
--- test/Transforms/InstCombine/memcpy-from-global.ll
+++ test/Transforms/InstCombine/memcpy-from-global.ll
@@ -204,3 +204,34 @@
 ; CHECK-NEXT: call void @bar(i8* bitcast (%U* getelementptr inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*))
   ret void
 }
+
+ at bbb = local_unnamed_addr global [1000000 x i8] zeroinitializer, align 16
+ at _ZL3KKK = internal unnamed_addr constant [3 x i8] c"\01\01\02", align 1
+
+; Should not replace alloca with global because of size mismatch.
+define void @test9_small_global() {
+; CHECK-LABEL: @test9_small_global(
+; CHECK-NOT: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}@bbb,{{.*}}@_ZL3KKK, 
+; CHECK: alloca [1000000 x i8]
+entry:
+  %cc = alloca [1000000 x i8], align 16
+  %cc.0..sroa_idx = getelementptr inbounds [1000000 x i8], [1000000 x i8]* %cc, i64 0, i64 0
+  %arraydecay = getelementptr inbounds [1000000 x i8], [1000000 x i8]* %cc, i32 0, i32 0
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %arraydecay, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZL3KKK, i32 0, i32 0), i64 3, i32 1, i1 false)
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([1000000 x i8], [1000000 x i8]* @bbb, i32 0, i32 0), i8* %arraydecay, i64 1000000, i32 16, i1 false)
+  ret void
+}
+
+; Should replace alloca with global as they have exactly the same size.
+define void @test10_same_global() {
+; CHECK-LABEL: @test10_same_global(
+; CHECK-NOT: alloca
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}@bbb,{{.*}}@_ZL3KKK,{{.*}}, i64 3, i32 1, i1 false)
+entry:
+  %cc = alloca [3 x i8], align 1
+  %cc.0..sroa_idx = getelementptr inbounds [3 x i8], [3 x i8]* %cc, i64 0, i64 0
+  %arraydecay = getelementptr inbounds [3 x i8], [3 x i8]* %cc, i32 0, i32 0
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %arraydecay, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZL3KKK, i32 0, i32 0), i64 3, i32 1, i1 false)
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([1000000 x i8], [1000000 x i8]* @bbb, i32 0, i32 0), i8* %arraydecay, i64 3, i32 1, i1 false)
+  ret void
+}
Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -157,14 +157,37 @@
   return true;
 }
 
+/// Returns true if MemTransferInst overwrites entire alloca.
+static bool isCompletelyOverwritten(const AllocaInst &AI,
+                                    const MemTransferInst &TheCopy) {
+  if (AI.isArrayAllocation())
+    return false;
+
+  const DataLayout &DL = AI.getModule()->getDataLayout();
+  uint64_t AllocaSize = DL.getTypeStoreSize(AI.getAllocatedType());
+  if (!AllocaSize)
+    return false;
+
+  ConstantInt *CopyLength = dyn_cast<ConstantInt>(TheCopy.getLength());
+  if (!CopyLength)
+    return false;
+
+  uint64_t CopySize = CopyLength->getLimitedValue();
+  if (CopySize < AllocaSize)
+    return false;
+
+  return true;
+}
+
 /// isOnlyCopiedFromConstantGlobal - Return true if the specified alloca is only
 /// modified by a copy from a constant global.  If we can prove this, we can
 /// replace any uses of the alloca with uses of the global directly.
 static MemTransferInst *
 isOnlyCopiedFromConstantGlobal(AllocaInst *AI,
                                SmallVectorImpl<Instruction *> &ToDelete) {
   MemTransferInst *TheCopy = nullptr;
-  if (isOnlyCopiedFromConstantGlobal(AI, TheCopy, ToDelete))
+  if (isOnlyCopiedFromConstantGlobal(AI, TheCopy, ToDelete) && TheCopy &&
+      isCompletelyOverwritten(*AI, *TheCopy))
     return TheCopy;
   return nullptr;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34311.103266.patch
Type: text/x-patch
Size: 3771 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170620/da388f97/attachment.bin>


More information about the llvm-commits mailing list