1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -o - -mtriple=x86_64-- -run-pass=greedy %s | FileCheck %s
3 # Tests for stack folding ADCX and ADOX. The ADOX tests were manually constructed by modifying ADCX tests to use OF instead of CF.
5 ; Function Attrs: nounwind
6 define i8 @stack_fold_adcx32(i8 %a0, i32 %a1, i32 %a2, i8* %a3) #0 {
7 tail call void asm sideeffect "nop", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
8 %1 = call { i8, i32 } @llvm.x86.addcarry.32(i8 %a0, i32 %a1, i32 %a2)
9 %2 = extractvalue { i8, i32 } %1, 1
10 %3 = bitcast i8* %a3 to i32*
11 store i32 %2, i32* %3, align 1
12 %4 = extractvalue { i8, i32 } %1, 0
16 ; Function Attrs: nounwind
17 define i8 @stack_fold_adcx64(i8 %a0, i64 %a1, i64 %a2, i8* %a3) #0 {
18 tail call void asm sideeffect "nop", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
19 %1 = call { i8, i64 } @llvm.x86.addcarry.64(i8 %a0, i64 %a1, i64 %a2)
20 %2 = extractvalue { i8, i64 } %1, 1
21 %3 = bitcast i8* %a3 to i64*
22 store i64 %2, i64* %3, align 1
23 %4 = extractvalue { i8, i64 } %1, 0
27 ; Function Attrs: nounwind
28 define i8 @stack_fold_adox32(i8 %a0, i32 %a1, i32 %a2, i8* %a3) #0 {
29 tail call void asm sideeffect "nop", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
30 %1 = call { i8, i32 } @llvm.x86.addcarry.32(i8 %a0, i32 %a1, i32 %a2)
31 %2 = extractvalue { i8, i32 } %1, 1
32 %3 = bitcast i8* %a3 to i32*
33 store i32 %2, i32* %3, align 1
34 %4 = extractvalue { i8, i32 } %1, 0
38 ; Function Attrs: nounwind
39 define i8 @stack_fold_adox64(i8 %a0, i64 %a1, i64 %a2, i8* %a3) #0 {
40 tail call void asm sideeffect "nop", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
41 %1 = call { i8, i64 } @llvm.x86.addcarry.64(i8 %a0, i64 %a1, i64 %a2)
42 %2 = extractvalue { i8, i64 } %1, 1
43 %3 = bitcast i8* %a3 to i64*
44 store i64 %2, i64* %3, align 1
45 %4 = extractvalue { i8, i64 } %1, 0
49 ; Function Attrs: nounwind readnone
50 declare { i8, i32 } @llvm.x86.addcarry.32(i8, i32, i32) #1
52 ; Function Attrs: nounwind readnone
53 declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64) #1
55 ; Function Attrs: nounwind
56 declare void @llvm.stackprotector(i8*, i8**) #2
58 attributes #0 = { nounwind "target-features"="+adx" }
59 attributes #1 = { nounwind readnone "target-features"="+adx" }
60 attributes #2 = { nounwind }
64 name: stack_fold_adcx32
66 tracksRegLiveness: true
68 - { id: 0, class: gr32 }
69 - { id: 1, class: gr32 }
70 - { id: 2, class: gr32 }
71 - { id: 3, class: gr64 }
72 - { id: 4, class: gr8 }
73 - { id: 5, class: gr8 }
74 - { id: 6, class: gr32 }
75 - { id: 7, class: gr8 }
77 - { reg: '$edi', virtual-reg: '%0' }
78 - { reg: '$esi', virtual-reg: '%1' }
79 - { reg: '$edx', virtual-reg: '%2' }
80 - { reg: '$rcx', virtual-reg: '%3' }
83 liveins: $edi, $esi, $edx, $rcx
85 ; CHECK-LABEL: name: stack_fold_adcx32
86 ; CHECK: liveins: $edi, $esi, $edx, $rcx
87 ; CHECK: MOV64mr %stack.0, 1, $noreg, 0, $noreg, $rcx :: (store (s64) into %stack.0)
88 ; CHECK: MOV32mr %stack.1, 1, $noreg, 0, $noreg, $edx :: (store (s32) into %stack.1)
89 ; CHECK: MOV32mr %stack.2, 1, $noreg, 0, $noreg, $esi :: (store (s32) into %stack.2)
90 ; CHECK: MOV32mr %stack.3, 1, $noreg, 0, $noreg, $edi :: (store (s32) into %stack.3)
91 ; CHECK: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
92 ; CHECK: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %stack.3, 1, $noreg, 0, $noreg :: (load (s32) from %stack.3)
93 ; CHECK: dead [[MOV32rm]].sub_8bit:gr32 = ADD8ri [[MOV32rm]].sub_8bit, -1, implicit-def $eflags
94 ; CHECK: [[MOV32rm1:%[0-9]+]]:gr32 = MOV32rm %stack.2, 1, $noreg, 0, $noreg :: (load (s32) from %stack.2)
95 ; CHECK: [[ADCX32rm:%[0-9]+]]:gr32 = ADCX32rm [[ADCX32rm]], %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags, implicit killed $eflags :: (load (s32) from %stack.1)
96 ; CHECK: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit killed $eflags
97 ; CHECK: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm %stack.0, 1, $noreg, 0, $noreg :: (load (s64) from %stack.0)
98 ; CHECK: MOV32mr [[MOV64rm]], 1, $noreg, 0, $noreg, [[ADCX32rm]] :: (store (s32) into %ir.3, align 1)
99 ; CHECK: $al = COPY [[SETCCr]]
105 INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
106 dead %0.sub_8bit:gr32 = ADD8ri %0.sub_8bit, -1, implicit-def $eflags
107 %6:gr32 = ADCX32rr %6, %2, implicit-def $eflags, implicit killed $eflags
108 %7:gr8 = SETCCr 2, implicit killed $eflags
109 MOV32mr %3, 1, $noreg, 0, $noreg, %6 :: (store (s32) into %ir.3, align 1)
115 name: stack_fold_adcx64
117 tracksRegLiveness: true
119 - { id: 0, class: gr32 }
120 - { id: 1, class: gr64 }
121 - { id: 2, class: gr64 }
122 - { id: 3, class: gr64 }
123 - { id: 4, class: gr8 }
124 - { id: 5, class: gr8 }
125 - { id: 6, class: gr64 }
126 - { id: 7, class: gr8 }
128 - { reg: '$edi', virtual-reg: '%0' }
129 - { reg: '$rsi', virtual-reg: '%1' }
130 - { reg: '$rdx', virtual-reg: '%2' }
131 - { reg: '$rcx', virtual-reg: '%3' }
134 liveins: $edi, $rsi, $rdx, $rcx
136 ; CHECK-LABEL: name: stack_fold_adcx64
137 ; CHECK: liveins: $edi, $rsi, $rdx, $rcx
138 ; CHECK: MOV64mr %stack.0, 1, $noreg, 0, $noreg, $rcx :: (store (s64) into %stack.0)
139 ; CHECK: MOV64mr %stack.1, 1, $noreg, 0, $noreg, $rdx :: (store (s64) into %stack.1)
140 ; CHECK: MOV64mr %stack.2, 1, $noreg, 0, $noreg, $rsi :: (store (s64) into %stack.2)
141 ; CHECK: MOV32mr %stack.3, 1, $noreg, 0, $noreg, $edi :: (store (s32) into %stack.3)
142 ; CHECK: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
143 ; CHECK: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %stack.3, 1, $noreg, 0, $noreg :: (load (s32) from %stack.3)
144 ; CHECK: dead [[MOV32rm]].sub_8bit:gr32 = ADD8ri [[MOV32rm]].sub_8bit, -1, implicit-def $eflags
145 ; CHECK: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm %stack.2, 1, $noreg, 0, $noreg :: (load (s64) from %stack.2)
146 ; CHECK: [[ADCX64rm:%[0-9]+]]:gr64 = ADCX64rm [[ADCX64rm]], %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags, implicit killed $eflags :: (load (s64) from %stack.1)
147 ; CHECK: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit killed $eflags
148 ; CHECK: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm %stack.0, 1, $noreg, 0, $noreg :: (load (s64) from %stack.0)
149 ; CHECK: MOV64mr [[MOV64rm]], 1, $noreg, 0, $noreg, [[ADCX64rm]] :: (store (s64) into %ir.3, align 1)
150 ; CHECK: $al = COPY [[SETCCr]]
156 INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
157 dead %0.sub_8bit:gr32 = ADD8ri %0.sub_8bit, -1, implicit-def $eflags
158 %6:gr64 = ADCX64rr %6, %2, implicit-def $eflags, implicit killed $eflags
159 %7:gr8 = SETCCr 2, implicit killed $eflags
160 MOV64mr %3, 1, $noreg, 0, $noreg, %6 :: (store (s64) into %ir.3, align 1)
166 name: stack_fold_adox32
168 tracksRegLiveness: true
170 - { id: 0, class: gr32 }
171 - { id: 1, class: gr32 }
172 - { id: 2, class: gr32 }
173 - { id: 3, class: gr64 }
174 - { id: 4, class: gr8 }
175 - { id: 5, class: gr8 }
176 - { id: 6, class: gr32 }
177 - { id: 7, class: gr8 }
179 - { reg: '$edi', virtual-reg: '%0' }
180 - { reg: '$esi', virtual-reg: '%1' }
181 - { reg: '$edx', virtual-reg: '%2' }
182 - { reg: '$rcx', virtual-reg: '%3' }
185 liveins: $edi, $esi, $edx, $rcx
187 ; CHECK-LABEL: name: stack_fold_adox32
188 ; CHECK: liveins: $edi, $esi, $edx, $rcx
189 ; CHECK: MOV64mr %stack.0, 1, $noreg, 0, $noreg, $rcx :: (store (s64) into %stack.0)
190 ; CHECK: MOV32mr %stack.1, 1, $noreg, 0, $noreg, $edx :: (store (s32) into %stack.1)
191 ; CHECK: MOV32mr %stack.2, 1, $noreg, 0, $noreg, $esi :: (store (s32) into %stack.2)
192 ; CHECK: MOV32mr %stack.3, 1, $noreg, 0, $noreg, $edi :: (store (s32) into %stack.3)
193 ; CHECK: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
194 ; CHECK: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %stack.3, 1, $noreg, 0, $noreg :: (load (s32) from %stack.3)
195 ; CHECK: dead [[MOV32rm]].sub_8bit:gr32 = ADD8ri [[MOV32rm]].sub_8bit, -1, implicit-def $eflags
196 ; CHECK: [[MOV32rm1:%[0-9]+]]:gr32 = MOV32rm %stack.2, 1, $noreg, 0, $noreg :: (load (s32) from %stack.2)
197 ; CHECK: [[ADOX32rm:%[0-9]+]]:gr32 = ADOX32rm [[ADOX32rm]], %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags, implicit killed $eflags :: (load (s32) from %stack.1)
198 ; CHECK: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit killed $eflags
199 ; CHECK: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm %stack.0, 1, $noreg, 0, $noreg :: (load (s64) from %stack.0)
200 ; CHECK: MOV32mr [[MOV64rm]], 1, $noreg, 0, $noreg, [[ADOX32rm]] :: (store (s32) into %ir.3, align 1)
201 ; CHECK: $al = COPY [[SETCCr]]
207 INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
208 dead %0.sub_8bit:gr32 = ADD8ri %0.sub_8bit, -1, implicit-def $eflags
209 %6:gr32 = ADOX32rr %6, %2, implicit-def $eflags, implicit killed $eflags
210 %7:gr8 = SETCCr 2, implicit killed $eflags
211 MOV32mr %3, 1, $noreg, 0, $noreg, %6 :: (store (s32) into %ir.3, align 1)
217 name: stack_fold_adox64
219 tracksRegLiveness: true
221 - { id: 0, class: gr32 }
222 - { id: 1, class: gr64 }
223 - { id: 2, class: gr64 }
224 - { id: 3, class: gr64 }
225 - { id: 4, class: gr8 }
226 - { id: 5, class: gr8 }
227 - { id: 6, class: gr64 }
228 - { id: 7, class: gr8 }
230 - { reg: '$edi', virtual-reg: '%0' }
231 - { reg: '$rsi', virtual-reg: '%1' }
232 - { reg: '$rdx', virtual-reg: '%2' }
233 - { reg: '$rcx', virtual-reg: '%3' }
236 liveins: $edi, $rsi, $rdx, $rcx
238 ; CHECK-LABEL: name: stack_fold_adox64
239 ; CHECK: liveins: $edi, $rsi, $rdx, $rcx
240 ; CHECK: MOV64mr %stack.0, 1, $noreg, 0, $noreg, $rcx :: (store (s64) into %stack.0)
241 ; CHECK: MOV64mr %stack.1, 1, $noreg, 0, $noreg, $rdx :: (store (s64) into %stack.1)
242 ; CHECK: MOV64mr %stack.2, 1, $noreg, 0, $noreg, $rsi :: (store (s64) into %stack.2)
243 ; CHECK: MOV32mr %stack.3, 1, $noreg, 0, $noreg, $edi :: (store (s32) into %stack.3)
244 ; CHECK: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
245 ; CHECK: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %stack.3, 1, $noreg, 0, $noreg :: (load (s32) from %stack.3)
246 ; CHECK: dead [[MOV32rm]].sub_8bit:gr32 = ADD8ri [[MOV32rm]].sub_8bit, -1, implicit-def $eflags
247 ; CHECK: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm %stack.2, 1, $noreg, 0, $noreg :: (load (s64) from %stack.2)
248 ; CHECK: [[ADOX64rm:%[0-9]+]]:gr64 = ADOX64rm [[ADOX64rm]], %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags, implicit killed $eflags :: (load (s64) from %stack.1)
249 ; CHECK: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit killed $eflags
250 ; CHECK: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm %stack.0, 1, $noreg, 0, $noreg :: (load (s64) from %stack.0)
251 ; CHECK: MOV64mr [[MOV64rm]], 1, $noreg, 0, $noreg, [[ADOX64rm]] :: (store (s64) into %ir.3, align 1)
252 ; CHECK: $al = COPY [[SETCCr]]
258 INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $rax, 12 /* clobber */, implicit-def dead early-clobber $rbx, 12 /* clobber */, implicit-def dead early-clobber $rcx, 12 /* clobber */, implicit-def dead early-clobber $rdx, 12 /* clobber */, implicit-def dead early-clobber $rsi, 12 /* clobber */, implicit-def dead early-clobber $rdi, 12 /* clobber */, implicit-def dead early-clobber $rbp, 12 /* clobber */, implicit-def dead early-clobber $r8, 12 /* clobber */, implicit-def dead early-clobber $r9, 12 /* clobber */, implicit-def dead early-clobber $r10, 12 /* clobber */, implicit-def dead early-clobber $r11, 12 /* clobber */, implicit-def dead early-clobber $r12, 12 /* clobber */, implicit-def dead early-clobber $r13, 12 /* clobber */, implicit-def dead early-clobber $r14, 12 /* clobber */, implicit-def dead early-clobber $r15
259 dead %0.sub_8bit:gr32 = ADD8ri %0.sub_8bit, -1, implicit-def $eflags
260 %6:gr64 = ADOX64rr %6, %2, implicit-def $eflags, implicit killed $eflags
261 %7:gr8 = SETCCr 2, implicit killed $eflags
262 MOV64mr %3, 1, $noreg, 0, $noreg, %6 :: (store (s64) into %ir.3, align 1)