[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / peephole-and-tst.ll
blob17ad2983abe905ed3860fd052a777028cdcede9a
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 %struct.anon = type { ptr, ptr }
6 @ptr_wrapper = common global ptr null, align 8
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 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
38 entry:
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
44 do.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
59 3:                                                ; preds = %do.body
60   store ptr null, ptr %result, align 8
61   br label %4
63 4:                                                ; 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
68 do.end:                                           ; preds = %4
69   ret i32 %retval1.1
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 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
95 entry:
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
101 do.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
113 3:                                                ; preds = %do.body
114   store ptr null, ptr %result, align 8
115   br label %4
117 4:                                                ; 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
122 do.end:                                           ; preds = %4
123   ret i32 %retval1.1
126 define 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
138 define 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
150 define 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
175 define 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
196 define 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
217 declare i64 @callee(i64)