[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / aarch64-fold-lslfast.ll
blob59cd87f58ab08eaeecdfd83b794071f699d44860
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK0
3 ; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+addr-lsl-fast | FileCheck %s --check-prefixes=CHECK,CHECK3
5 %struct.a = type [256 x i16]
6 %struct.b = type [256 x i32]
7 %struct.c = type [256 x i64]
9 declare void @foo()
10 define i16 @halfword(ptr %ctx, i32 %xor72) nounwind {
11 ; CHECK0-LABEL: halfword:
12 ; CHECK0:       // %bb.0:
13 ; CHECK0-NEXT:    stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
14 ; CHECK0-NEXT:    // kill: def $w1 killed $w1 def $x1
15 ; CHECK0-NEXT:    ubfx x8, x1, #9, #8
16 ; CHECK0-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
17 ; CHECK0-NEXT:    mov x19, x0
18 ; CHECK0-NEXT:    lsl x21, x8, #1
19 ; CHECK0-NEXT:    ldrh w20, [x0, x21]
20 ; CHECK0-NEXT:    bl foo
21 ; CHECK0-NEXT:    mov w0, w20
22 ; CHECK0-NEXT:    strh w20, [x19, x21]
23 ; CHECK0-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
24 ; CHECK0-NEXT:    ldp x30, x21, [sp], #32 // 16-byte Folded Reload
25 ; CHECK0-NEXT:    ret
27 ; CHECK3-LABEL: halfword:
28 ; CHECK3:       // %bb.0:
29 ; CHECK3-NEXT:    stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
30 ; CHECK3-NEXT:    // kill: def $w1 killed $w1 def $x1
31 ; CHECK3-NEXT:    ubfx x21, x1, #9, #8
32 ; CHECK3-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
33 ; CHECK3-NEXT:    mov x19, x0
34 ; CHECK3-NEXT:    ldrh w20, [x0, x21, lsl #1]
35 ; CHECK3-NEXT:    bl foo
36 ; CHECK3-NEXT:    mov w0, w20
37 ; CHECK3-NEXT:    strh w20, [x19, x21, lsl #1]
38 ; CHECK3-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
39 ; CHECK3-NEXT:    ldp x30, x21, [sp], #32 // 16-byte Folded Reload
40 ; CHECK3-NEXT:    ret
41   %shr81 = lshr i32 %xor72, 9
42   %conv82 = zext i32 %shr81 to i64
43   %idxprom83 = and i64 %conv82, 255
44   %arrayidx86 = getelementptr inbounds %struct.a, ptr %ctx, i64 0, i64 %idxprom83
45   %result = load i16, ptr %arrayidx86, align 2
46   call void @foo()
47   store i16 %result, ptr %arrayidx86, align 2
48   ret i16 %result
51 define i32 @word(ptr %ctx, i32 %xor72) nounwind {
52 ; CHECK0-LABEL: word:
53 ; CHECK0:       // %bb.0:
54 ; CHECK0-NEXT:    stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
55 ; CHECK0-NEXT:    // kill: def $w1 killed $w1 def $x1
56 ; CHECK0-NEXT:    ubfx x8, x1, #9, #8
57 ; CHECK0-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
58 ; CHECK0-NEXT:    mov x19, x0
59 ; CHECK0-NEXT:    lsl x21, x8, #2
60 ; CHECK0-NEXT:    ldr w20, [x0, x21]
61 ; CHECK0-NEXT:    bl foo
62 ; CHECK0-NEXT:    mov w0, w20
63 ; CHECK0-NEXT:    str w20, [x19, x21]
64 ; CHECK0-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
65 ; CHECK0-NEXT:    ldp x30, x21, [sp], #32 // 16-byte Folded Reload
66 ; CHECK0-NEXT:    ret
68 ; CHECK3-LABEL: word:
69 ; CHECK3:       // %bb.0:
70 ; CHECK3-NEXT:    stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
71 ; CHECK3-NEXT:    // kill: def $w1 killed $w1 def $x1
72 ; CHECK3-NEXT:    ubfx x21, x1, #9, #8
73 ; CHECK3-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
74 ; CHECK3-NEXT:    mov x19, x0
75 ; CHECK3-NEXT:    ldr w20, [x0, x21, lsl #2]
76 ; CHECK3-NEXT:    bl foo
77 ; CHECK3-NEXT:    mov w0, w20
78 ; CHECK3-NEXT:    str w20, [x19, x21, lsl #2]
79 ; CHECK3-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
80 ; CHECK3-NEXT:    ldp x30, x21, [sp], #32 // 16-byte Folded Reload
81 ; CHECK3-NEXT:    ret
82   %shr81 = lshr i32 %xor72, 9
83   %conv82 = zext i32 %shr81 to i64
84   %idxprom83 = and i64 %conv82, 255
85   %arrayidx86 = getelementptr inbounds %struct.b, ptr %ctx, i64 0, i64 %idxprom83
86   %result = load i32, ptr %arrayidx86, align 4
87   call void @foo()
88   store i32 %result, ptr %arrayidx86, align 4
89   ret i32 %result
92 define i64 @doubleword(ptr %ctx, i32 %xor72) nounwind {
93 ; CHECK0-LABEL: doubleword:
94 ; CHECK0:       // %bb.0:
95 ; CHECK0-NEXT:    stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
96 ; CHECK0-NEXT:    // kill: def $w1 killed $w1 def $x1
97 ; CHECK0-NEXT:    ubfx x8, x1, #9, #8
98 ; CHECK0-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
99 ; CHECK0-NEXT:    mov x19, x0
100 ; CHECK0-NEXT:    lsl x21, x8, #3
101 ; CHECK0-NEXT:    ldr x20, [x0, x21]
102 ; CHECK0-NEXT:    bl foo
103 ; CHECK0-NEXT:    mov x0, x20
104 ; CHECK0-NEXT:    str x20, [x19, x21]
105 ; CHECK0-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
106 ; CHECK0-NEXT:    ldp x30, x21, [sp], #32 // 16-byte Folded Reload
107 ; CHECK0-NEXT:    ret
109 ; CHECK3-LABEL: doubleword:
110 ; CHECK3:       // %bb.0:
111 ; CHECK3-NEXT:    stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
112 ; CHECK3-NEXT:    // kill: def $w1 killed $w1 def $x1
113 ; CHECK3-NEXT:    ubfx x21, x1, #9, #8
114 ; CHECK3-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
115 ; CHECK3-NEXT:    mov x19, x0
116 ; CHECK3-NEXT:    ldr x20, [x0, x21, lsl #3]
117 ; CHECK3-NEXT:    bl foo
118 ; CHECK3-NEXT:    mov x0, x20
119 ; CHECK3-NEXT:    str x20, [x19, x21, lsl #3]
120 ; CHECK3-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
121 ; CHECK3-NEXT:    ldp x30, x21, [sp], #32 // 16-byte Folded Reload
122 ; CHECK3-NEXT:    ret
123   %shr81 = lshr i32 %xor72, 9
124   %conv82 = zext i32 %shr81 to i64
125   %idxprom83 = and i64 %conv82, 255
126   %arrayidx86 = getelementptr inbounds %struct.c, ptr %ctx, i64 0, i64 %idxprom83
127   %result = load i64, ptr %arrayidx86, align 8
128   call void @foo()
129   store i64 %result, ptr %arrayidx86, align 8
130   ret i64 %result
133 define i64 @multi_use_non_memory(i64 %a, i64 %b) {
134 ; CHECK-LABEL: multi_use_non_memory:
135 ; CHECK:       // %bb.0: // %entry
136 ; CHECK-NEXT:    lsl x8, x0, #3
137 ; CHECK-NEXT:    lsl x9, x1, #3
138 ; CHECK-NEXT:    cmp x8, x9
139 ; CHECK-NEXT:    b.lt .LBB3_2
140 ; CHECK-NEXT:  // %bb.1: // %falsebb
141 ; CHECK-NEXT:    csel x0, x8, x9, gt
142 ; CHECK-NEXT:    ret
143 ; CHECK-NEXT:  .LBB3_2: // %truebb
144 ; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
145 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
146 ; CHECK-NEXT:    .cfi_offset w30, -16
147 ; CHECK-NEXT:    bl foo
148 entry:
149   %mul1 = shl i64 %a, 3
150   %mul2 = shl i64 %b, 3
151   %cmp = icmp slt i64 %mul1, %mul2
152   br i1 %cmp, label %truebb, label %falsebb
153 truebb:
154   tail call void @foo()
155   unreachable
156 falsebb:
157   %cmp2 = icmp sgt i64 %mul1, %mul2
158   br i1 %cmp2, label %exitbb, label %endbb
159 exitbb:
160  ret i64 %mul1
161 endbb:
162  ret i64 %mul2
165 define i64 @gep3(ptr %p, i64 %b) {
166 ; CHECK0-LABEL: gep3:
167 ; CHECK0:       // %bb.0:
168 ; CHECK0-NEXT:    lsl x9, x1, #3
169 ; CHECK0-NEXT:    mov x8, x0
170 ; CHECK0-NEXT:    ldr x0, [x0, x9]
171 ; CHECK0-NEXT:    str x1, [x8, x9]
172 ; CHECK0-NEXT:    ret
174 ; CHECK3-LABEL: gep3:
175 ; CHECK3:       // %bb.0:
176 ; CHECK3-NEXT:    mov x8, x0
177 ; CHECK3-NEXT:    ldr x0, [x0, x1, lsl #3]
178 ; CHECK3-NEXT:    str x1, [x8, x1, lsl #3]
179 ; CHECK3-NEXT:    ret
180   %g = getelementptr inbounds i64, ptr %p, i64 %b
181   %l = load i64, ptr %g
182   store i64 %b, ptr %g
183   ret i64 %l
186 define i128 @gep4(ptr %p, i128 %a, i64 %b) {
187 ; CHECK-LABEL: gep4:
188 ; CHECK:       // %bb.0:
189 ; CHECK-NEXT:    add x8, x0, x4, lsl #4
190 ; CHECK-NEXT:    ldp x0, x1, [x8]
191 ; CHECK-NEXT:    stp x2, x3, [x8]
192 ; CHECK-NEXT:    ret
193   %g = getelementptr inbounds i128, ptr %p, i64 %b
194   %l = load i128, ptr %g
195   store i128 %a, ptr %g
196   ret i128 %l
199 define i64 @addlsl3(i64 %a, i64 %b) {
200 ; CHECK-LABEL: addlsl3:
201 ; CHECK:       // %bb.0:
202 ; CHECK-NEXT:    lsl x8, x0, #3
203 ; CHECK-NEXT:    add x9, x1, x8
204 ; CHECK-NEXT:    sub x8, x1, x8
205 ; CHECK-NEXT:    eor x0, x9, x8
206 ; CHECK-NEXT:    ret
207   %x = shl i64 %a, 3
208   %y = add i64 %b, %x
209   %z = sub i64 %b, %x
210   %r = xor i64 %y, %z
211   ret i64 %r
214 define i64 @addlsl4(i64 %a, i64 %b) {
215 ; CHECK-LABEL: addlsl4:
216 ; CHECK:       // %bb.0:
217 ; CHECK-NEXT:    lsl x8, x0, #4
218 ; CHECK-NEXT:    add x9, x1, x8
219 ; CHECK-NEXT:    sub x8, x1, x8
220 ; CHECK-NEXT:    eor x0, x9, x8
221 ; CHECK-NEXT:    ret
222   %x = shl i64 %a, 4
223   %y = add i64 %b, %x
224   %z = sub i64 %b, %x
225   %r = xor i64 %y, %z
226   ret i64 %r