Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / Mem2Reg / preserve-nonnull-load-metadata.ll
blobedc07864795e83970d201914601e84a826317353
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=mem2reg -S | FileCheck %s
4 ; This tests that mem2reg preserves the !nonnull metadata on loads
5 ; from allocas that get optimized out.
7 ; Check the case where the alloca in question has a single store.
8 define ptr @single_store_noundef(ptr %arg) {
9 ; CHECK-LABEL: @single_store_noundef(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
12 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne ptr [[ARG_LOAD]], null
13 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
14 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
16 entry:
17   %buf = alloca ptr
18   %arg.load = load ptr, ptr %arg, align 8
19   store ptr %arg.load, ptr %buf, align 8
20   %buf.load = load ptr, ptr %buf, !nonnull !0, !noundef !0
21   ret ptr %buf.load
24 define ptr @single_store_missing_noundef(ptr %arg) {
25 ; CHECK-LABEL: @single_store_missing_noundef(
26 ; CHECK-NEXT:  entry:
27 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
28 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
30 entry:
31   %buf = alloca ptr
32   %arg.load = load ptr, ptr %arg, align 8
33   store ptr %arg.load, ptr %buf, align 8
34   %buf.load = load ptr, ptr %buf, !nonnull !0
35   ret ptr %buf.load
38 ; Check the case where the alloca in question has more than one
39 ; store but still within one basic block.
40 define ptr @single_block_noundef(ptr %arg) {
41 ; CHECK-LABEL: @single_block_noundef(
42 ; CHECK-NEXT:  entry:
43 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
44 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne ptr [[ARG_LOAD]], null
45 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
46 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
48 entry:
49   %buf = alloca ptr
50   %arg.load = load ptr, ptr %arg, align 8
51   store ptr null, ptr %buf, align 8
52   store ptr %arg.load, ptr %buf, align 8
53   %buf.load = load ptr, ptr %buf, !nonnull !0, !noundef !0
54   ret ptr %buf.load
57 define ptr @single_block_missing_noundef(ptr %arg) {
58 ; CHECK-LABEL: @single_block_missing_noundef(
59 ; CHECK-NEXT:  entry:
60 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
61 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
63 entry:
64   %buf = alloca ptr
65   %arg.load = load ptr, ptr %arg, align 8
66   store ptr null, ptr %buf, align 8
67   store ptr %arg.load, ptr %buf, align 8
68   %buf.load = load ptr, ptr %buf, !nonnull !0
69   ret ptr %buf.load
72 ; Check the case where the alloca in question has more than one
73 ; store and also reads ands writes in multiple blocks.
74 define ptr @multi_block_noundef(ptr %arg) {
75 ; CHECK-LABEL: @multi_block_noundef(
76 ; CHECK-NEXT:  entry:
77 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
78 ; CHECK-NEXT:    br label [[NEXT:%.*]]
79 ; CHECK:       next:
80 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne ptr [[ARG_LOAD]], null
81 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
82 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
84 entry:
85   %buf = alloca ptr
86   %arg.load = load ptr, ptr %arg, align 8
87   store ptr null, ptr %buf, align 8
88   br label %next
89 next:
90   store ptr %arg.load, ptr %buf, align 8
91   %buf.load = load ptr, ptr %buf, !nonnull !0, !noundef !0
92   ret ptr %buf.load
95 define ptr @multi_block_missing_noundef(ptr %arg) {
96 ; CHECK-LABEL: @multi_block_missing_noundef(
97 ; CHECK-NEXT:  entry:
98 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
99 ; CHECK-NEXT:    br label [[NEXT:%.*]]
100 ; CHECK:       next:
101 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
103 entry:
104   %buf = alloca ptr
105   %arg.load = load ptr, ptr %arg, align 8
106   store ptr null, ptr %buf, align 8
107   br label %next
108 next:
109   store ptr %arg.load, ptr %buf, align 8
110   %buf.load = load ptr, ptr %buf, !nonnull !0
111   ret ptr %buf.load
114 ; Check that we don't add an assume if it's not
115 ; necessary i.e. the value is already implied to be nonnull
116 define ptr @no_assume(ptr %arg) {
117 ; CHECK-LABEL: @no_assume(
118 ; CHECK-NEXT:  entry:
119 ; CHECK-NEXT:    [[ARG_LOAD:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
120 ; CHECK-NEXT:    [[CN:%.*]] = icmp ne ptr [[ARG_LOAD]], null
121 ; CHECK-NEXT:    br i1 [[CN]], label [[NEXT:%.*]], label [[FIN:%.*]]
122 ; CHECK:       next:
123 ; CHECK-NEXT:    ret ptr [[ARG_LOAD]]
124 ; CHECK:       fin:
125 ; CHECK-NEXT:    ret ptr null
127 entry:
128   %buf = alloca ptr
129   %arg.load = load ptr, ptr %arg, align 8
130   %cn = icmp ne ptr %arg.load, null
131   br i1 %cn, label %next, label %fin
132 next:
133 ; At this point the above nonnull check ensures that
134 ; the value %arg.load is nonnull in this block and thus
135 ; we need not add the assume.
136   store ptr %arg.load, ptr %buf, align 8
137   %buf.load = load ptr, ptr %buf, !nonnull !0
138   ret ptr %buf.load
139 fin:
140   ret ptr null
143 define ptr @no_store_single_load_noundef() {
144 ; CHECK-LABEL: @no_store_single_load_noundef(
145 ; CHECK-NEXT:  entry:
146 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
147 ; CHECK-NEXT:    ret ptr undef
149 entry:
150   %buf = alloca ptr
151   %buf.load = load ptr, ptr %buf, !noundef !0
152   ret ptr %buf.load
155 define ptr @no_store_multiple_loads_noundef(i1 %c) {
156 ; CHECK-LABEL: @no_store_multiple_loads_noundef(
157 ; CHECK-NEXT:  entry:
158 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
159 ; CHECK:       if:
160 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
161 ; CHECK-NEXT:    ret ptr undef
162 ; CHECK:       else:
163 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
164 ; CHECK-NEXT:    ret ptr undef
166 entry:
167   %buf = alloca ptr
168   br i1 %c, label %if, label %else
171   %buf.load = load ptr, ptr %buf, !noundef !0
172   ret ptr %buf.load
174   else:
175   %buf.load2 = load ptr, ptr %buf, !noundef !0
176   ret ptr %buf.load2
179 define ptr @no_store_single_load_nonnull_noundef() {
180 ; CHECK-LABEL: @no_store_single_load_nonnull_noundef(
181 ; CHECK-NEXT:  entry:
182 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
183 ; CHECK-NEXT:    ret ptr undef
185 entry:
186   %buf = alloca ptr
187   %buf.load = load ptr, ptr %buf, !nonnull !0, !noundef !0
188   ret ptr %buf.load
191 define ptr @no_store_multiple_loads_nonnull_noundef(i1 %c) {
192 ; CHECK-LABEL: @no_store_multiple_loads_nonnull_noundef(
193 ; CHECK-NEXT:  entry:
194 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
195 ; CHECK:       if:
196 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
197 ; CHECK-NEXT:    ret ptr undef
198 ; CHECK:       else:
199 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
200 ; CHECK-NEXT:    ret ptr undef
202 entry:
203   %buf = alloca ptr
204   br i1 %c, label %if, label %else
207   %buf.load = load ptr, ptr %buf, !nonnull !0, !noundef !0
208   ret ptr %buf.load
210   else:
211   %buf.load2 = load ptr, ptr %buf, !nonnull !0, !noundef !0
212   ret ptr %buf.load2
215 !0 = !{}