Author: Sam Elliott
Date: 2019-11-15T17:44:02-08:00
New Revision: 8af4ee9ff003eba3dfe06d999bab047a9539c473

URL: 
https://github.com/llvm/llvm-project/commit/8af4ee9ff003eba3dfe06d999bab047a9539c473
DIFF: 
https://github.com/llvm/llvm-project/commit/8af4ee9ff003eba3dfe06d999bab047a9539c473.diff

LOG: Merging r375403:

------------------------------------------------------------------------
r375403 | lenary | 2019-10-21 03:00:34 -0700 (Mon, 21 Oct 2019) | 30 lines

[MemCpyOpt] Fixing Incorrect Code Motion while Handling Aggregate Type Values

Summary:
When MemCpyOpt is handling aggregate type values, if an instruction (let's call 
it P) between the targeting load (L) and store (S) clobbers the source pointer 
of L, it will try to hoist S before P. This process will also hoist S's data 
dependency instructions.

However, the current implementation has a bug that if one of S's dependency 
instructions is //also// a user of P, MemCpyOpt will not prevent it from being 
hoisted above P and cause a use-before-define error. For example, in the newly 
added test file (i.e. `aggregate-type-crash.ll`), it will try to hoist both 
`store %my_struct %1, %my_struct* %3` and its dependent, `%3 = bitcast i8* %2 
to %my_struct*`, above `%2 = call i8* @my_malloc(%my_struct* %0)`. Creating the 
following BB:
```
entry:
  %1 = bitcast i8* %4 to %my_struct*
  %2 = bitcast %my_struct* %1 to i8*
  %3 = bitcast %my_struct* %0 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, 
i1 false)
  %4 = call i8* @my_malloc(%my_struct* %0)
  ret void
```
Where there is a use-before-define error between `%1` and `%4`.

Update: The compiler for the Pony Programming Language [also encounter the same 
bug](https://github.com/ponylang/ponyc/issues/3140)

Patch by Min-Yih Hsu (myhsu)

Reviewers: eugenis, pcc, dblaikie, dneilson, t.p.northover, lattner

Reviewed By: eugenis

Subscribers: lenary, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66060
------------------------------------------------------------------------

Added: 
    llvm/test/Transforms/MemCpyOpt/aggregate-type-crash.ll

Modified: 
    llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp 
b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 5a055139be4f..bb5ec253cbf2 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -597,9 +597,13 @@ static bool moveUp(AliasAnalysis &AA, StoreInst *SI, 
Instruction *P,
 
     ToLift.push_back(C);
     for (unsigned k = 0, e = C->getNumOperands(); k != e; ++k)
-      if (auto *A = dyn_cast<Instruction>(C->getOperand(k)))
-        if (A->getParent() == SI->getParent())
+      if (auto *A = dyn_cast<Instruction>(C->getOperand(k))) {
+        if (A->getParent() == SI->getParent()) {
+          // Cannot hoist user of P above P
+          if(A == P) return false;
           Args.insert(A);
+        }
+      }
   }
 
   // We made it, we need to lift

diff  --git a/llvm/test/Transforms/MemCpyOpt/aggregate-type-crash.ll 
b/llvm/test/Transforms/MemCpyOpt/aggregate-type-crash.ll
new file mode 100644
index 000000000000..d97202e82501
--- /dev/null
+++ b/llvm/test/Transforms/MemCpyOpt/aggregate-type-crash.ll
@@ -0,0 +1,30 @@
+; RUN: opt -memcpyopt -S -o - < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.14.0"
+
+%my_struct = type { i8, i32 }
+
+; Function Attrs: inaccessiblemem_or_argmemonly
+declare noalias i8* @my_malloc(%my_struct*) #0
+
+define void @my_func(%my_struct*) {
+entry:
+; CHECK: entry:
+  %1 = load %my_struct, %my_struct* %0
+  %2 = call i8* @my_malloc(%my_struct* %0)
+  %3 = bitcast i8* %2 to %my_struct*
+  store %my_struct %1, %my_struct* %3
+; CHECK-NOT: call void @llvm.memcpy.{{.*}}.{{.*}}.{{.*}}
+  ret void
+}
+
+attributes #0 = { inaccessiblemem_or_argmemonly }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 14]}
+!1 = !{i32 1, !"wchar_size", i32 4}
+!2 = !{i32 7, !"PIC Level", i32 2}
+!3 = !{!"Apple LLVM version 10.0.1 (clang-1001.0.46.4)"}


        
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to