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