Skip to content

Commit 8af4ee9

Browse files
lenarytstellar
authored andcommitted
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](ponylang/ponyc#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 ------------------------------------------------------------------------
1 parent 0ec4a87 commit 8af4ee9

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,13 @@ static bool moveUp(AliasAnalysis &AA, StoreInst *SI, Instruction *P,
597597

598598
ToLift.push_back(C);
599599
for (unsigned k = 0, e = C->getNumOperands(); k != e; ++k)
600-
if (auto *A = dyn_cast<Instruction>(C->getOperand(k)))
601-
if (A->getParent() == SI->getParent())
600+
if (auto *A = dyn_cast<Instruction>(C->getOperand(k))) {
601+
if (A->getParent() == SI->getParent()) {
602+
// Cannot hoist user of P above P
603+
if(A == P) return false;
602604
Args.insert(A);
605+
}
606+
}
603607
}
604608

605609
// We made it, we need to lift
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: opt -memcpyopt -S -o - < %s | FileCheck %s
2+
3+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-apple-macosx10.14.0"
5+
6+
%my_struct = type { i8, i32 }
7+
8+
; Function Attrs: inaccessiblemem_or_argmemonly
9+
declare noalias i8* @my_malloc(%my_struct*) #0
10+
11+
define void @my_func(%my_struct*) {
12+
entry:
13+
; CHECK: entry:
14+
%1 = load %my_struct, %my_struct* %0
15+
%2 = call i8* @my_malloc(%my_struct* %0)
16+
%3 = bitcast i8* %2 to %my_struct*
17+
store %my_struct %1, %my_struct* %3
18+
; CHECK-NOT: call void @llvm.memcpy.{{.*}}.{{.*}}.{{.*}}
19+
ret void
20+
}
21+
22+
attributes #0 = { inaccessiblemem_or_argmemonly }
23+
24+
!llvm.module.flags = !{!0, !1, !2}
25+
!llvm.ident = !{!3}
26+
27+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 14]}
28+
!1 = !{i32 1, !"wchar_size", i32 4}
29+
!2 = !{i32 7, !"PIC Level", i32 2}
30+
!3 = !{!"Apple LLVM version 10.0.1 (clang-1001.0.46.4)"}

0 commit comments

Comments
 (0)