1
+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1
2
; RUN: opt < %s -passes=mem2reg -S | FileCheck %s
2
3
3
4
; This tests that mem2reg preserves the !nonnull metadata on loads
4
5
; from allocas that get optimized out.
5
6
6
7
; Check the case where the alloca in question has a single store.
7
8
define float * @single_store (float ** %arg ) {
8
- ; CHECK-LABEL: define float* @single_store
9
- ; CHECK: %arg.load = load float*, float** %arg, align 8
10
- ; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null
11
- ; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]])
12
- ; CHECK: ret float* %arg.load
9
+ ; CHECK-LABEL: @single_store(
10
+ ; CHECK-NEXT: entry:
11
+ ; CHECK-NEXT: [[ARG_LOAD:%.*]] = load float*, float** [[ARG:%.*]], align 8
12
+ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne float* [[ARG_LOAD]], null
13
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
14
+ ; CHECK-NEXT: ret float* [[ARG_LOAD]]
15
+ ;
13
16
entry:
14
17
%buf = alloca float *
15
18
%arg.load = load float *, float ** %arg , align 8
@@ -21,11 +24,13 @@ entry:
21
24
; Check the case where the alloca in question has more than one
22
25
; store but still within one basic block.
23
26
define float * @single_block (float ** %arg ) {
24
- ; CHECK-LABEL: define float* @single_block
25
- ; CHECK: %arg.load = load float*, float** %arg, align 8
26
- ; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null
27
- ; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]])
28
- ; CHECK: ret float* %arg.load
27
+ ; CHECK-LABEL: @single_block(
28
+ ; CHECK-NEXT: entry:
29
+ ; CHECK-NEXT: [[ARG_LOAD:%.*]] = load float*, float** [[ARG:%.*]], align 8
30
+ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne float* [[ARG_LOAD]], null
31
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
32
+ ; CHECK-NEXT: ret float* [[ARG_LOAD]]
33
+ ;
29
34
entry:
30
35
%buf = alloca float *
31
36
%arg.load = load float *, float ** %arg , align 8
@@ -38,14 +43,15 @@ entry:
38
43
; Check the case where the alloca in question has more than one
39
44
; store and also reads ands writes in multiple blocks.
40
45
define float * @multi_block (float ** %arg ) {
41
- ; CHECK-LABEL: define float* @multi_block
42
- ; CHECK-LABEL: entry:
43
- ; CHECK: %arg.load = load float*, float** %arg, align 8
44
- ; CHECK: br label %next
45
- ; CHECK-LABEL: next:
46
- ; CHECK: [[ASSUME:%(.*)]] = icmp ne float* %arg.load, null
47
- ; CHECK: call void @llvm.assume(i1 {{.*}}[[ASSUME]])
48
- ; CHECK: ret float* %arg.load
46
+ ; CHECK-LABEL: @multi_block(
47
+ ; CHECK-NEXT: entry:
48
+ ; CHECK-NEXT: [[ARG_LOAD:%.*]] = load float*, float** [[ARG:%.*]], align 8
49
+ ; CHECK-NEXT: br label [[NEXT:%.*]]
50
+ ; CHECK: next:
51
+ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne float* [[ARG_LOAD]], null
52
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
53
+ ; CHECK-NEXT: ret float* [[ARG_LOAD]]
54
+ ;
49
55
entry:
50
56
%buf = alloca float *
51
57
%arg.load = load float *, float ** %arg , align 8
@@ -60,16 +66,16 @@ next:
60
66
; Check that we don't add an assume if it's not
61
67
; necessary i.e. the value is already implied to be nonnull
62
68
define float * @no_assume (float ** %arg ) {
63
- ; CHECK-LABEL: define float* @no_assume
64
- ; CHECK-LABEL: entry:
65
- ; CHECK: %arg.load = load float*, float** %arg , align 8
66
- ; CHECK: %cn = icmp ne float* %arg.load , null
67
- ; CHECK: br i1 %cn , label %next , label %fin
68
- ; CHECK-LABEL: next:
69
- ; CHECK-NOT: call void @llvm.assume
70
- ; CHECK: ret float* %arg.load
71
- ; CHECK-LABEL: fin:
72
- ; CHECK: ret float* null
69
+ ; CHECK-LABEL: @no_assume(
70
+ ; CHECK-NEXT: entry:
71
+ ; CHECK-NEXT: [[ARG_LOAD:%.*]] = load float*, float** [[ARG:%.*]] , align 8
72
+ ; CHECK-NEXT: [[CN:%.*]] = icmp ne float* [[ARG_LOAD]] , null
73
+ ; CHECK-NEXT: br i1 [[CN]] , label [[NEXT:%.*]] , label [[FIN:%.*]]
74
+ ; CHECK: next:
75
+ ; CHECK-NEXT: ret float* [[ARG_LOAD]]
76
+ ; CHECK: fin:
77
+ ; CHECK-NEXT: ret float* null
78
+ ;
73
79
entry:
74
80
%buf = alloca float *
75
81
%arg.load = load float *, float ** %arg , align 8
86
92
ret float * null
87
93
}
88
94
95
+ define float * @no_store_single_load () {
96
+ ; CHECK-LABEL: @no_store_single_load(
97
+ ; CHECK-NEXT: entry:
98
+ ; CHECK-NEXT: ret float* undef
99
+ ;
100
+ entry:
101
+ %buf = alloca float *
102
+ %buf.load = load float *, float **%buf , !nonnull !0
103
+ ret float * %buf.load
104
+ }
105
+
106
+ define float * @no_store_multiple_loads (i1 %c ) {
107
+ ; CHECK-LABEL: @no_store_multiple_loads(
108
+ ; CHECK-NEXT: entry:
109
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
110
+ ; CHECK: if:
111
+ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne float* undef, null
112
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
113
+ ; CHECK-NEXT: ret float* undef
114
+ ; CHECK: else:
115
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne float* undef, null
116
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
117
+ ; CHECK-NEXT: ret float* undef
118
+ ;
119
+ entry:
120
+ %buf = alloca float *
121
+ br i1 %c , label %if , label %else
122
+
123
+ if:
124
+ %buf.load = load float *, float **%buf , !nonnull !0
125
+ ret float * %buf.load
126
+
127
+ else:
128
+ %buf.load2 = load float *, float **%buf , !nonnull !0
129
+ ret float * %buf.load2
130
+ }
131
+
89
132
!0 = !{}
0 commit comments