Skip to content

Commit ecc9f0f

Browse files
committed
Support memintrinsics
1 parent 7ed780f commit ecc9f0f

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

llvm/lib/Transforms/IPO/GlobalOpt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ CleanupPointerRootUsers(GlobalVariable *GV,
211211
} else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
212212
if (isa<GEPOperator>(CE))
213213
append_range(Worklist, CE->users());
214+
} else if (auto *MI = dyn_cast<MemIntrinsic>(U)) {
215+
if (MI->getRawDest() == GV)
216+
Writes.push_back(MI);
214217
}
215218
}
216219

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt -passes=globalopt < %s -S | FileCheck %s
3+
4+
@gv = internal unnamed_addr global [3 x ptr] zeroinitializer, align 16
5+
@gv2 = internal unnamed_addr global i32 0, align 4
6+
7+
;; This test includes a load from @gv. No stores
8+
;; or memintrinsics with destination @gv should be removed.
9+
define i32 @main_with_load_from_b() local_unnamed_addr {
10+
; CHECK-LABEL: define i32 @main_with_load_from_b() local_unnamed_addr {
11+
; CHECK-NEXT: entry:
12+
; CHECK-NEXT: [[E:%.*]] = alloca i32, align 4
13+
; CHECK-NEXT: store ptr [[E]], ptr getelementptr inbounds ([3 x ptr], ptr @gv, i64 0, i64 2), align 16
14+
; CHECK-NEXT: [[LOAD_B:%.*]] = load ptr, ptr getelementptr inbounds ([3 x ptr], ptr @gv, i64 0, i64 2), align 16
15+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr @gv, ptr null, i64 8, i1 false)
16+
; CHECK-NEXT: ret i32 0
17+
;
18+
entry:
19+
%e = alloca i32, align 4
20+
store ptr %e, ptr getelementptr inbounds ([3 x ptr], ptr @gv, i64 0, i64 2), align 16
21+
%load.b = load ptr, ptr getelementptr inbounds ([3 x ptr], ptr @gv, i64 0, i64 2), align 16
22+
call void @llvm.memcpy.p0i8.p0i8.i64(ptr getelementptr inbounds ([3 x ptr], ptr @gv, i64 0, i64 0), ptr null, i64 8, i1 false)
23+
ret i32 0
24+
}
25+
26+
;; This test includes a memcpy with @c as it's source and destination
27+
;; operands. CleanupPointerRootUsers is not called in this case.
28+
define i32 @main_with_load_store_c() local_unnamed_addr {
29+
; CHECK-LABEL: define i32 @main_with_load_store_c() local_unnamed_addr {
30+
; CHECK-NEXT: entry:
31+
; CHECK-NEXT: [[E:%.*]] = alloca i32, align 4
32+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr @gv2, ptr @gv2, i64 4, i1 false)
33+
; CHECK-NEXT: ret i32 0
34+
;
35+
entry:
36+
%e = alloca i32, align 4
37+
call void @llvm.memcpy.p0i8.p0i8.i64(ptr @gv2, ptr @gv2, i64 4, i1 false)
38+
ret i32 0
39+
}
40+
41+
declare void @llvm.memcpy.p0i8.p0i8.i64(ptr nocapture, ptr nocapture readonly, i64, i1) local_unnamed_addr
42+
declare void @llvm.memset.p0i8.i64(ptr nocapture, i8, i64, i1) local_unnamed_addr

llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-stores.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
@a = internal unnamed_addr global i32 0, align 4
55
@b = internal unnamed_addr global [3 x ptr] zeroinitializer, align 16
66

7+
;; This test is extracted from the issue reported in #64680, with an
8+
;; additional memcpy and a memset. Ensure all stores and memintrinsics with
9+
;; destination @b are removed as @b is dead.
710
define i32 @main() local_unnamed_addr {
811
; CHECK-LABEL: define i32 @main() local_unnamed_addr {
912
; CHECK-NEXT: entry:
@@ -52,11 +55,15 @@ if.end: ; preds = %if.then, %for.body
5255
%inc = add nsw i32 %1, 1
5356
store i32 %inc, ptr @a, align 4
5457
%cmp = icmp slt i32 %1, 2
58+
call void @llvm.memset.p0i8.i64(ptr getelementptr inbounds ([3 x ptr], ptr @b, i64 0, i64 0), i8 0, i64 8, i1 false)
5559
br i1 %cmp, label %for.body, label %for.end
5660

5761
for.end: ; preds = %if.end, %entry
62+
call void @llvm.memcpy.p0i8.p0i8.i64(ptr getelementptr inbounds ([3 x ptr], ptr @b, i64 0, i64 0), ptr null, i64 8, i1 false)
5863
ret i32 0
5964
}
6065

6166
declare void @bar20_() local_unnamed_addr
6267
declare void @foo() local_unnamed_addr
68+
declare void @llvm.memcpy.p0i8.p0i8.i64(ptr nocapture, ptr nocapture readonly, i64, i1) local_unnamed_addr
69+
declare void @llvm.memset.p0i8.i64(ptr nocapture, i8, i64, i1) local_unnamed_addr

0 commit comments

Comments
 (0)