xref: /llvm-project/llvm/test/Transforms/GlobalOpt/stored-once-forward-value.ll (revision dede19caf0da31d9b8b69d014602cde41ab9a96e)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=globalopt -S < %s | FileCheck %s
3
4@g1 = internal unnamed_addr global i32 0
5@g2 = internal unnamed_addr global i32 0
6@g3 = internal unnamed_addr global i32 0
7@g4 = internal unnamed_addr global i32 0
8@g5 = internal unnamed_addr global i32 0
9@g6 = internal unnamed_addr global i32 0
10@g7 = internal unnamed_addr global i32 0
11@g8 = internal unnamed_addr global ptr null
12@tl = internal thread_local unnamed_addr global i32 0
13
14declare void @b()
15
16define i1 @dom_const() {
17; CHECK-LABEL: @dom_const(
18; CHECK-NEXT:    call void @b()
19; CHECK-NEXT:    ret i1 true
20;
21  store i1 true, ptr @g1
22  call void @b()
23  %r = load i1, ptr @g1
24  ret i1 %r
25}
26
27define i32 @dom_arg(i32 %a) {
28; CHECK-LABEL: @dom_arg(
29; CHECK-NEXT:    store i32 [[A:%.*]], ptr @g2, align 4
30; CHECK-NEXT:    call void @b()
31; CHECK-NEXT:    [[R:%.*]] = load i32, ptr @g2, align 4
32; CHECK-NEXT:    ret i32 [[R]]
33;
34  store i32 %a, ptr @g2
35  call void @b()
36  %r = load i32, ptr @g2
37  ret i32 %r
38}
39
40define ptr @dom_thread_local_global() {
41; CHECK-LABEL: @dom_thread_local_global(
42; CHECK-NEXT:    [[P:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @tl)
43; CHECK-NEXT:    store ptr [[P]], ptr @g3, align 8
44; CHECK-NEXT:    call void @b()
45; CHECK-NEXT:    [[R:%.*]] = load ptr, ptr @g3, align 8
46; CHECK-NEXT:    ret ptr [[R]]
47;
48  %p = call ptr @llvm.threadlocal.address(ptr @tl)
49  store ptr %p, ptr @g3
50  call void @b()
51  %r = load ptr, ptr @g3
52  ret ptr %r
53}
54
55define i32 @dom_different_types() {
56; CHECK-LABEL: @dom_different_types(
57; CHECK-NEXT:    store i1 true, ptr @g4, align 1
58; CHECK-NEXT:    call void @b()
59; CHECK-NEXT:    [[R:%.*]] = load i32, ptr @g4, align 4
60; CHECK-NEXT:    ret i32 [[R]]
61;
62  store i1 true, ptr @g4
63  call void @b()
64  %r = load i32, ptr @g4
65  ret i32 %r
66}
67
68define i1 @no_dom(i1 %i) {
69; CHECK-LABEL: @no_dom(
70; CHECK-NEXT:    br i1 [[I:%.*]], label [[BB1:%.*]], label [[END:%.*]]
71; CHECK:       bb1:
72; CHECK-NEXT:    store i1 true, ptr @g5, align 1
73; CHECK-NEXT:    br label [[END]]
74; CHECK:       end:
75; CHECK-NEXT:    call void @b()
76; CHECK-NEXT:    [[R:%.*]] = load i1, ptr @g5, align 1
77; CHECK-NEXT:    ret i1 [[R]]
78;
79  br i1 %i, label %bb1, label %end
80bb1:
81  store i1 true, ptr @g5
82  br label %end
83end:
84  call void @b()
85  %r = load i1, ptr @g5
86  ret i1 %r
87}
88
89define i1 @dom_multiple_function_loads() {
90; CHECK-LABEL: @dom_multiple_function_loads(
91; CHECK-NEXT:    store i1 true, ptr @g6, align 1
92; CHECK-NEXT:    call void @b()
93; CHECK-NEXT:    ret i1 true
94;
95  store i1 true, ptr @g6
96  call void @b()
97  %r = load i1, ptr @g6
98  ret i1 %r
99}
100
101define i1 @other() {
102; CHECK-LABEL: @other(
103; CHECK-NEXT:    call void @b()
104; CHECK-NEXT:    [[R:%.*]] = load i1, ptr @g6, align 1
105; CHECK-NEXT:    ret i1 [[R]]
106;
107  call void @b()
108  %r = load i1, ptr @g6
109  ret i1 %r
110}
111
112define i1 @dom_volatile() {
113; CHECK-LABEL: @dom_volatile(
114; CHECK-NEXT:    store i1 true, ptr @g7, align 1
115; CHECK-NEXT:    call void @b()
116; CHECK-NEXT:    [[R:%.*]] = load volatile i1, ptr @g7, align 1
117; CHECK-NEXT:    ret i1 [[R]]
118;
119  store i1 true, ptr @g7
120  call void @b()
121  %r = load volatile i1, ptr @g7
122  ret i1 %r
123}
124
125define i1 @dom_store_const_and_initializer() {
126; CHECK-LABEL: @dom_store_const_and_initializer(
127; CHECK-NEXT:    store i1 true, ptr @g8, align 1
128; CHECK-NEXT:    store i1 false, ptr @g8, align 1
129; CHECK-NEXT:    call void @b()
130; CHECK-NEXT:    [[R:%.*]] = load i1, ptr @g8, align 1
131; CHECK-NEXT:    ret i1 [[R]]
132;
133  store i1 true, ptr @g8
134  store i1 false, ptr @g8
135  call void @b()
136  %r = load i1, ptr @g8
137  ret i1 %r
138}
139