1
+ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1
2
; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
2
3
3
4
%struct.anon = type { i32* , i32* }
4
5
5
- @ptr_wrapper = common dso_local local_unnamed_addr global %struct.anon* null , align 8
6
+ @ptr_wrapper = common global %struct.anon* null , align 8
6
7
7
- define dso_local i32 @test_func_i32_two_uses (i32 %in , i32 %bit , i32 %mask ) local_unnamed_addr {
8
+ define i32 @test_func_i32_two_uses (i32 %in , i32 %bit , i32 %mask ) {
9
+ ; CHECK-LABEL: test_func_i32_two_uses:
10
+ ; CHECK: // %bb.0: // %entry
11
+ ; CHECK-NEXT: adrp x9, :got:ptr_wrapper
12
+ ; CHECK-NEXT: mov w8, w0
13
+ ; CHECK-NEXT: mov w0, wzr
14
+ ; CHECK-NEXT: ldr x9, [x9, :got_lo12:ptr_wrapper]
15
+ ; CHECK-NEXT: ldr x9, [x9]
16
+ ; CHECK-NEXT: b .LBB0_3
17
+ ; CHECK-NEXT: .LBB0_1: // in Loop: Header=BB0_3 Depth=1
18
+ ; CHECK-NEXT: str xzr, [x9, #8]
19
+ ; CHECK-NEXT: .LBB0_2: // in Loop: Header=BB0_3 Depth=1
20
+ ; CHECK-NEXT: lsl w1, w1, #1
21
+ ; CHECK-NEXT: cbz w1, .LBB0_6
22
+ ; CHECK-NEXT: .LBB0_3: // %do.body
23
+ ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
24
+ ; CHECK-NEXT: ands w10, w1, w8
25
+ ; CHECK-NEXT: and w11, w2, w8
26
+ ; CHECK-NEXT: cinc w0, w0, ne
27
+ ; CHECK-NEXT: cmp w10, w11
28
+ ; CHECK-NEXT: b.eq .LBB0_1
29
+ ; CHECK-NEXT: // %bb.4: // %do.body
30
+ ; CHECK-NEXT: // in Loop: Header=BB0_3 Depth=1
31
+ ; CHECK-NEXT: cbnz w2, .LBB0_1
32
+ ; CHECK-NEXT: // %bb.5: // %do.body
33
+ ; CHECK-NEXT: // in Loop: Header=BB0_3 Depth=1
34
+ ; CHECK-NEXT: cbz w10, .LBB0_2
35
+ ; CHECK-NEXT: b .LBB0_1
36
+ ; CHECK-NEXT: .LBB0_6: // %do.end
37
+ ; CHECK-NEXT: ret
8
38
entry:
9
39
%0 = load %struct.anon* , %struct.anon** @ptr_wrapper , align 8
10
40
%result = getelementptr inbounds %struct.anon , %struct.anon* %0 , i64 0 , i32 1
11
41
%tobool2 = icmp ne i32 %mask , 0
12
42
br label %do.body
13
43
14
44
do.body: ; preds = %4, %entry
15
- ; CHECK-LABEL: test_func_i32_two_uses:
16
- ; CHECK: ands [[DSTREG:w[0-9]+]]
17
- ; Usage #1
18
- ; CHECK: cmp [[DSTREG]]
19
- ; Usage #2
20
- ; CHECK: cbz [[DSTREG]]
21
45
%bit.addr.0 = phi i32 [ %bit , %entry ], [ %shl , %4 ]
22
46
%retval1.0 = phi i32 [ 0 , %entry ], [ %retval1.1 , %4 ]
23
47
%and = and i32 %bit.addr.0 , %in
@@ -45,17 +69,36 @@ do.end: ; preds = %4
45
69
ret i32 %retval1.1
46
70
}
47
71
48
- define dso_local i32 @test_func_i64_one_use (i64 %in , i64 %bit , i64 %mask ) local_unnamed_addr #0 {
72
+ define i32 @test_func_i64_one_use (i64 %in , i64 %bit , i64 %mask ) {
73
+ ; CHECK-LABEL: test_func_i64_one_use:
74
+ ; CHECK: // %bb.0: // %entry
75
+ ; CHECK-NEXT: adrp x9, :got:ptr_wrapper
76
+ ; CHECK-NEXT: mov x8, x0
77
+ ; CHECK-NEXT: mov w0, wzr
78
+ ; CHECK-NEXT: ldr x9, [x9, :got_lo12:ptr_wrapper]
79
+ ; CHECK-NEXT: ldr x9, [x9]
80
+ ; CHECK-NEXT: b .LBB1_2
81
+ ; CHECK-NEXT: .LBB1_1: // in Loop: Header=BB1_2 Depth=1
82
+ ; CHECK-NEXT: lsl x1, x1, #1
83
+ ; CHECK-NEXT: cbz x1, .LBB1_4
84
+ ; CHECK-NEXT: .LBB1_2: // %do.body
85
+ ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
86
+ ; CHECK-NEXT: ands x10, x1, x8
87
+ ; CHECK-NEXT: orr x10, x2, x10
88
+ ; CHECK-NEXT: cinc w0, w0, ne
89
+ ; CHECK-NEXT: cbz x10, .LBB1_1
90
+ ; CHECK-NEXT: // %bb.3: // in Loop: Header=BB1_2 Depth=1
91
+ ; CHECK-NEXT: str xzr, [x9, #8]
92
+ ; CHECK-NEXT: b .LBB1_1
93
+ ; CHECK-NEXT: .LBB1_4: // %do.end
94
+ ; CHECK-NEXT: ret
49
95
entry:
50
96
%0 = load %struct.anon* , %struct.anon** @ptr_wrapper , align 8
51
97
%result = getelementptr inbounds %struct.anon , %struct.anon* %0 , i64 0 , i32 1
52
98
%tobool2 = icmp ne i64 %mask , 0
53
99
br label %do.body
54
100
55
101
do.body: ; preds = %4, %entry
56
- ; CHECK-LABEL: test_func_i64_one_use:
57
- ; CHECK: ands [[DSTREG:x[0-9]+]], [[SRCREG1:x[0-9]+]], [[SRCREG2:x[0-9]+]]
58
- ; CHECK-NEXT: orr [[DSTREG]], [[SRCREG_ORR:x[0-9]+]], [[DSTREG]]
59
102
%bit.addr.0 = phi i64 [ %bit , %entry ], [ %shl , %4 ]
60
103
%retval1.0 = phi i32 [ 0 , %entry ], [ %retval1.1 , %4 ]
61
104
%and = and i64 %bit.addr.0 , %in
@@ -79,3 +122,100 @@ do.body: ; preds = %4, %entry
79
122
do.end: ; preds = %4
80
123
ret i32 %retval1.1
81
124
}
125
+
126
+ define i64 @test_and1 (i64 %x , i64 %y ) {
127
+ ; CHECK-LABEL: test_and1:
128
+ ; CHECK: // %bb.0:
129
+ ; CHECK-NEXT: and x8, x0, #0x3
130
+ ; CHECK-NEXT: tst x0, #0x3
131
+ ; CHECK-NEXT: csel x0, x8, x1, eq
132
+ ; CHECK-NEXT: ret
133
+ %a = and i64 %x , 3
134
+ %c = icmp eq i64 %a , 0
135
+ %s = select i1 %c , i64 %a , i64 %y
136
+ ret i64 %s
137
+ }
138
+
139
+ define i64 @test_and2 (i64 %x , i64 %y ) {
140
+ ; CHECK-LABEL: test_and2:
141
+ ; CHECK: // %bb.0:
142
+ ; CHECK-NEXT: tst x0, #0x3
143
+ ; CHECK-NEXT: csel x0, x0, x1, eq
144
+ ; CHECK-NEXT: ret
145
+ %a = and i64 %x , 3
146
+ %c = icmp eq i64 %a , 0
147
+ %s = select i1 %c , i64 %x , i64 %y
148
+ ret i64 %s
149
+ }
150
+
151
+ define i64 @test_and3 (i64 %x , i64 %y ) {
152
+ ; CHECK-LABEL: test_and3:
153
+ ; CHECK: // %bb.0:
154
+ ; CHECK-NEXT: stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
155
+ ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
156
+ ; CHECK-NEXT: .cfi_def_cfa_offset 32
157
+ ; CHECK-NEXT: .cfi_offset w19, -8
158
+ ; CHECK-NEXT: .cfi_offset w20, -16
159
+ ; CHECK-NEXT: .cfi_offset w21, -24
160
+ ; CHECK-NEXT: .cfi_offset w30, -32
161
+ ; CHECK-NEXT: mov x20, x0
162
+ ; CHECK-NEXT: and x21, x0, #0x3
163
+ ; CHECK-NEXT: mov x0, xzr
164
+ ; CHECK-NEXT: mov x19, x1
165
+ ; CHECK-NEXT: bl callee
166
+ ; CHECK-NEXT: tst x20, #0x3
167
+ ; CHECK-NEXT: csel x0, x21, x19, eq
168
+ ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
169
+ ; CHECK-NEXT: ldp x30, x21, [sp], #32 // 16-byte Folded Reload
170
+ ; CHECK-NEXT: ret
171
+ %a = and i64 %x , 3
172
+ %b = call i64 @callee (i64 0 )
173
+ %c = icmp eq i64 %a , 0
174
+ %s = select i1 %c , i64 %a , i64 %y
175
+ ret i64 %s
176
+ }
177
+
178
+ define i64 @test_and_4 (i64 %x , i64 %y ) {
179
+ ; CHECK-LABEL: test_and_4:
180
+ ; CHECK: // %bb.0:
181
+ ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
182
+ ; CHECK-NEXT: .cfi_def_cfa_offset 16
183
+ ; CHECK-NEXT: .cfi_offset w19, -8
184
+ ; CHECK-NEXT: .cfi_offset w30, -16
185
+ ; CHECK-NEXT: mov x19, x0
186
+ ; CHECK-NEXT: ands x0, x0, #0x3
187
+ ; CHECK-NEXT: bl callee
188
+ ; CHECK-NEXT: tst x19, #0x3
189
+ ; CHECK-NEXT: and x8, x19, #0x3
190
+ ; CHECK-NEXT: csel x0, x8, x0, eq
191
+ ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
192
+ ; CHECK-NEXT: ret
193
+ %a = and i64 %x , 3
194
+ %b = call i64 @callee (i64 %a )
195
+ %c = icmp eq i64 %a , 0
196
+ %s = select i1 %c , i64 %a , i64 %b
197
+ ret i64 %s
198
+ }
199
+
200
+ define i64 @test_add (i64 %x , i64 %y ) {
201
+ ; CHECK-LABEL: test_add:
202
+ ; CHECK: // %bb.0:
203
+ ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
204
+ ; CHECK-NEXT: .cfi_def_cfa_offset 16
205
+ ; CHECK-NEXT: .cfi_offset w19, -8
206
+ ; CHECK-NEXT: .cfi_offset w30, -16
207
+ ; CHECK-NEXT: add x19, x0, #3
208
+ ; CHECK-NEXT: mov x0, xzr
209
+ ; CHECK-NEXT: bl callee
210
+ ; CHECK-NEXT: cmp x19, #0
211
+ ; CHECK-NEXT: csel x0, x19, x0, eq
212
+ ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
213
+ ; CHECK-NEXT: ret
214
+ %a = add i64 %x , 3
215
+ %b = call i64 @callee (i64 0 )
216
+ %c = icmp eq i64 %a , 0
217
+ %s = select i1 %c , i64 %a , i64 %b
218
+ ret i64 %s
219
+ }
220
+
221
+ declare i64 @callee (i64 )
0 commit comments