Skip to content

Commit 378daa6

Browse files
authored
[MemCpyOpt] Avoid infinite loops in MemCpyOptPass::processMemCpyMemCpyDependence (#103218)
Closes #102994.
1 parent 15e915a commit 378daa6

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,10 @@ bool MemCpyOptPass::processMemCpyMemCpyDependence(MemCpyInst *M,
11931193
CopySourceAlign = commonAlignment(*CopySourceAlign, MForwardOffset);
11941194
}
11951195

1196+
// Avoid infinite loops
1197+
if (BAA.isMustAlias(M->getSource(), CopySource))
1198+
return false;
1199+
11961200
// Verify that the copied-from memory doesn't change in between the two
11971201
// transfers. For example, in:
11981202
// memcpy(a <- b)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=memcpyopt < %s | FileCheck %s
3+
4+
@g1 = external global i8
5+
@g2 = external global [64 x i8]
6+
@g3 = global i8 0, align 1
7+
8+
define void @func() {
9+
; CHECK-LABEL: define void @func() {
10+
; CHECK-NEXT: [[ENTRY:.*:]]
11+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr getelementptr inbounds (i8, ptr @g2, i64 16), ptr getelementptr inbounds nuw (i8, ptr @g2, i64 16), i64 20, i1 false)
12+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr @g1, ptr getelementptr inbounds (i8, ptr @g2, i64 24), i64 1, i1 false)
13+
; CHECK-NEXT: ret void
14+
;
15+
entry:
16+
call void @llvm.memcpy.p0.p0.i64(ptr getelementptr inbounds (i8, ptr @g2, i64 16), ptr getelementptr inbounds nuw (i8, ptr @g2, i64 16), i64 20, i1 false)
17+
call void @llvm.memcpy.p0.p0.i64(ptr @g1, ptr getelementptr inbounds (i8, ptr @g2, i64 24), i64 1, i1 false)
18+
ret void
19+
}
20+
21+
define void @func2(ptr %p) {
22+
; CHECK-LABEL: define void @func2(
23+
; CHECK-SAME: ptr [[P:%.*]]) {
24+
; CHECK-NEXT: [[ENTRY:.*:]]
25+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 32
26+
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[P]], i64 34
27+
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[P]], i64 32
28+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[GEP1]], ptr [[GEP3]], i64 32, i1 false)
29+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr @g3, ptr [[GEP2]], i64 1, i1 false)
30+
; CHECK-NEXT: ret void
31+
;
32+
entry:
33+
%gep1 = getelementptr i8, ptr %p, i64 32
34+
%gep2 = getelementptr i8, ptr %p, i64 34
35+
%gep3 = getelementptr i8, ptr %p, i64 32
36+
call void @llvm.memcpy.p0.p0.i64(ptr %gep1, ptr %gep3, i64 32, i1 false)
37+
call void @llvm.memcpy.p0.p0.i64(ptr @g3, ptr %gep2, i64 1, i1 false)
38+
ret void
39+
}

0 commit comments

Comments
 (0)