|
2 | 2 | ; RUN: opt -mtriple=x86_64-apple-darwin10.0.0 -passes=pre-isel-intrinsic-lowering -S -o - %s | FileCheck %s
|
3 | 3 |
|
4 | 4 | ;.
|
| 5 | +; CHECK: @G = global i32 5 |
| 6 | +; CHECK: @ptr_pat = private unnamed_addr constant ptr @G, align 8 |
5 | 7 | ; CHECK: @.memset_pattern = private unnamed_addr constant [2 x i64] [i64 -6148895925951734307, i64 -6148895925951734307], align 16
|
6 | 8 | ; CHECK: @.memset_pattern.1 = private unnamed_addr constant [2 x i64] [i64 4614256656552045848, i64 4614256656552045848], align 16
|
7 | 9 | ; CHECK: @.memset_pattern.2 = private unnamed_addr constant [8 x i16] [i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555, i16 -21555], align 16
|
@@ -144,6 +146,78 @@ define void @memset_pattern_i64_128_tbaa(ptr %a) nounwind {
|
144 | 146 | !7 = !{!"omnipotent char", !8, i64 0}
|
145 | 147 | !8 = !{!"Simple C++ TBAA"}
|
146 | 148 |
|
| 149 | +@G = global i32 5 |
| 150 | +@ptr_pat = private unnamed_addr constant ptr @G, align 8 |
| 151 | + |
| 152 | +; FIXME: memset_pattern16 should be selected. |
| 153 | +define void @memset_pattern_i64_16_fromptr(ptr %a) nounwind { |
| 154 | +; CHECK-LABEL: define void @memset_pattern_i64_16_fromptr( |
| 155 | +; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] { |
| 156 | +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @ptr_pat, align 8 |
| 157 | +; CHECK-NEXT: br i1 false, label %[[SPLIT:.*]], label %[[LOADSTORELOOP:.*]] |
| 158 | +; CHECK: [[LOADSTORELOOP]]: |
| 159 | +; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ 0, [[TMP0:%.*]] ], [ [[TMP4:%.*]], %[[LOADSTORELOOP]] ] |
| 160 | +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]] |
| 161 | +; CHECK-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 1 |
| 162 | +; CHECK-NEXT: [[TMP4]] = add i64 [[TMP2]], 1 |
| 163 | +; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 [[TMP4]], 16 |
| 164 | +; CHECK-NEXT: br i1 [[TMP5]], label %[[LOADSTORELOOP]], label %[[SPLIT]] |
| 165 | +; CHECK: [[SPLIT]]: |
| 166 | +; CHECK-NEXT: ret void |
| 167 | +; |
| 168 | + %1 = load i64, ptr @ptr_pat, align 8 |
| 169 | + tail call void @llvm.experimental.memset.pattern(ptr %a, i64 %1, i64 16, i1 false) |
| 170 | + ret void |
| 171 | +} |
| 172 | + |
| 173 | +; FIXME: memset_pattern16 should be selected. |
| 174 | +define void @memset_pattern_i64_x_fromptr(ptr %a, i64 %x) nounwind { |
| 175 | +; CHECK-LABEL: define void @memset_pattern_i64_x_fromptr( |
| 176 | +; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] { |
| 177 | +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @ptr_pat, align 8 |
| 178 | +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 0, [[X]] |
| 179 | +; CHECK-NEXT: br i1 [[TMP2]], label %[[SPLIT:.*]], label %[[LOADSTORELOOP:.*]] |
| 180 | +; CHECK: [[LOADSTORELOOP]]: |
| 181 | +; CHECK-NEXT: [[TMP3:%.*]] = phi i64 [ 0, [[TMP0:%.*]] ], [ [[TMP5:%.*]], %[[LOADSTORELOOP]] ] |
| 182 | +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]] |
| 183 | +; CHECK-NEXT: store i64 [[TMP1]], ptr [[TMP4]], align 1 |
| 184 | +; CHECK-NEXT: [[TMP5]] = add i64 [[TMP3]], 1 |
| 185 | +; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 [[TMP5]], [[X]] |
| 186 | +; CHECK-NEXT: br i1 [[TMP6]], label %[[LOADSTORELOOP]], label %[[SPLIT]] |
| 187 | +; CHECK: [[SPLIT]]: |
| 188 | +; CHECK-NEXT: ret void |
| 189 | +; |
| 190 | + %1 = load i64, ptr @ptr_pat, align 8 |
| 191 | + tail call void @llvm.experimental.memset.pattern(ptr %a, i64 %1, i64 %x, i1 false) |
| 192 | + ret void |
| 193 | +} |
| 194 | + |
| 195 | +@nonconst_ptr_pat = private unnamed_addr global ptr @G, align 8 |
| 196 | + |
| 197 | +; memset_pattern16 shouldn't be used for this example (at least not by just |
| 198 | +; creating a constantarray global at compile tiem), as the global isn't |
| 199 | +; constant. |
| 200 | +define void @memset_pattern_i64_x_fromnonconstptr(ptr %a, i64 %x) nounwind { |
| 201 | +; CHECK-LABEL: define void @memset_pattern_i64_x_fromnonconstptr( |
| 202 | +; CHECK-SAME: ptr [[A:%.*]], i64 [[X:%.*]]) #[[ATTR0]] { |
| 203 | +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @nonconst_ptr_pat, align 8 |
| 204 | +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 0, [[X]] |
| 205 | +; CHECK-NEXT: br i1 [[TMP2]], label %[[SPLIT:.*]], label %[[LOADSTORELOOP:.*]] |
| 206 | +; CHECK: [[LOADSTORELOOP]]: |
| 207 | +; CHECK-NEXT: [[TMP3:%.*]] = phi i64 [ 0, [[TMP0:%.*]] ], [ [[TMP5:%.*]], %[[LOADSTORELOOP]] ] |
| 208 | +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]] |
| 209 | +; CHECK-NEXT: store i64 [[TMP1]], ptr [[TMP4]], align 1 |
| 210 | +; CHECK-NEXT: [[TMP5]] = add i64 [[TMP3]], 1 |
| 211 | +; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 [[TMP5]], [[X]] |
| 212 | +; CHECK-NEXT: br i1 [[TMP6]], label %[[LOADSTORELOOP]], label %[[SPLIT]] |
| 213 | +; CHECK: [[SPLIT]]: |
| 214 | +; CHECK-NEXT: ret void |
| 215 | +; |
| 216 | + %1 = load i64, ptr @nonconst_ptr_pat, align 8 |
| 217 | + tail call void @llvm.experimental.memset.pattern(ptr %a, i64 %1, i64 %x, i1 false) |
| 218 | + ret void |
| 219 | +} |
| 220 | + |
147 | 221 | ;.
|
148 | 222 | ; CHECK: attributes #[[ATTR0]] = { nounwind }
|
149 | 223 | ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
|
0 commit comments