1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=avr -mcpu=avrtiny | FileCheck %s
3
4; NOTE: Both %a(i8) and %b(i8) cost two registers.
5define i8 @foo0(i8 %a, i8 %b) {
6; CHECK-LABEL: foo0:
7; CHECK:       ; %bb.0:
8; CHECK-NEXT:    sub r24, r22
9; CHECK-NEXT:    ret
10  %c = sub i8 %a, %b
11  ret i8 %c
12}
13
14; NOTE: Both %a(i16) and %b(i16) cost two registers.
15define i16 @foo1(i16 %a, i16 %b) {
16; CHECK-LABEL: foo1:
17; CHECK:       ; %bb.0:
18; CHECK-NEXT:    sub r24, r22
19; CHECK-NEXT:    sbc r25, r23
20; CHECK-NEXT:    ret
21  %c = sub i16 %a, %b
22  ret i16 %c
23}
24
25; NOTE: %a(i16), %b(i16) and %c(i16) each costs two registers.
26define i16 @foo2(i16 %a, i16 %b, i16 %c) {
27; CHECK-LABEL: foo2:
28; CHECK:       ; %bb.0:
29; CHECK-NEXT:    sub r22, r24
30; CHECK-NEXT:    sbc r23, r25
31; CHECK-NEXT:    add r22, r20
32; CHECK-NEXT:    adc r23, r21
33; CHECK-NEXT:    mov r24, r22
34; CHECK-NEXT:    mov r25, r23
35; CHECK-NEXT:    ret
36  %d = sub i16 %a, %b
37  %e = sub i16 %c, %d
38  ret i16 %e
39}
40
41; NOTE:  %a(i16), %b(i16) and %c(i16) each costs two registers,
42;        while %d(i16) is passed via the stack.
43; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows
44;        how arguments are passed.
45define i16 @foo3(i16 %a, i16 %b, i16 %c, i16 %d) {
46; CHECK-LABEL: foo3:
47; CHECK:       ; %bb.0:
48; CHECK-NEXT:    push r28
49; CHECK-NEXT:    push r29
50; CHECK-NEXT:    in r28, 61
51; CHECK-NEXT:    in r29, 62
52; CHECK-NEXT:    ldd r30, Y+5
53; CHECK-NEXT:    ldd r31, Y+6
54; CHECK-NEXT:    sub r20, r30
55; CHECK-NEXT:    sbc r21, r31
56; CHECK-NEXT:    sub r24, r22
57; CHECK-NEXT:    sbc r25, r23
58; CHECK-NEXT:    add r24, r20
59; CHECK-NEXT:    adc r25, r21
60; CHECK-NEXT:    pop r29
61; CHECK-NEXT:    pop r28
62; CHECK-NEXT:    ret
63  %e = sub i16 %a, %b
64  %g = sub i16 %c, %d
65  %h = add i16 %e, %g
66  ret i16 %h
67}
68
69; NOTE: %a(i32) costs four registers, while %b(i32) is passed via the stack.
70; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows
71;        how arguments are passed.
72define i32 @foo4(i32 %a, i32 %b) {
73; CHECK-LABEL: foo4:
74; CHECK:       ; %bb.0:
75; CHECK-NEXT:    push r28
76; CHECK-NEXT:    push r29
77; CHECK-NEXT:    in r28, 61
78; CHECK-NEXT:    in r29, 62
79; CHECK-NEXT:    ldd r20, Y+5
80; CHECK-NEXT:    ldd r21, Y+6
81; CHECK-NEXT:    ldd r30, Y+7
82; CHECK-NEXT:    ldd r31, Y+8
83; CHECK-NEXT:    sub r20, r22
84; CHECK-NEXT:    sbc r21, r23
85; CHECK-NEXT:    sbc r30, r24
86; CHECK-NEXT:    sbc r31, r25
87; CHECK-NEXT:    mov r22, r20
88; CHECK-NEXT:    mov r23, r21
89; CHECK-NEXT:    mov r24, r30
90; CHECK-NEXT:    mov r25, r31
91; CHECK-NEXT:    pop r29
92; CHECK-NEXT:    pop r28
93; CHECK-NEXT:    ret
94  %c = sub i32 %b, %a
95  ret i32 %c
96}
97
98; NOTE: %0 costs six registers, while %1 is passed via the stack.
99; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows
100;        how arguments are passed.
101define i8 @foo5([5 x i8] %0, i8 %1) {
102; CHECK-LABEL: foo5:
103; CHECK:       ; %bb.0:
104; CHECK-NEXT:    push r28
105; CHECK-NEXT:    push r29
106; CHECK-NEXT:    in r28, 61
107; CHECK-NEXT:    in r29, 62
108; CHECK-NEXT:    ldd r24, Y+5
109; CHECK-NEXT:    add r24, r20
110; CHECK-NEXT:    pop r29
111; CHECK-NEXT:    pop r28
112; CHECK-NEXT:    ret
113  %3 = extractvalue [5 x i8] %0, 0
114  %4 = add i8 %3, %1
115  ret i8 %4
116}
117
118; NOTE: %0 costs two registers and %1 costs four registers.
119define i8 @foo6([2 x i8] %0, [4 x i8] %1) {
120; CHECK-LABEL: foo6:
121; CHECK:       ; %bb.0:
122; CHECK-NEXT:    add r24, r20
123; CHECK-NEXT:    ret
124  %3 = extractvalue [2 x i8] %0, 0
125  %4 = extractvalue [4 x i8] %1, 0
126  %5 = add i8 %3, %4
127  ret i8 %5
128}
129
130; NOTE: %0 cost four registers, while %1 is passed via the stack,
131;       though there are two vacant registers.
132; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows
133;        how arguments are passed.
134define i8 @foo7([3 x i8] %0, [3 x i8] %1) {
135; CHECK-LABEL: foo7:
136; CHECK:       ; %bb.0:
137; CHECK-NEXT:    push r28
138; CHECK-NEXT:    push r29
139; CHECK-NEXT:    in r28, 61
140; CHECK-NEXT:    in r29, 62
141; CHECK-NEXT:    ldd r24, Y+5
142; CHECK-NEXT:    add r24, r22
143; CHECK-NEXT:    pop r29
144; CHECK-NEXT:    pop r28
145; CHECK-NEXT:    ret
146  %3 = extractvalue [3 x i8] %0, 0
147  %4 = extractvalue [3 x i8] %1, 0
148  %5 = add i8 %3, %4
149  ret i8 %5
150}
151
152; NOTE: %0 costs four registers, and %1 costs two registers, while %2 is
153;       passed via the stack, though there is one vacant register.
154; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows
155;        how arguments are passed.
156define i8 @foo8([3 x i8] %0, i8 %1, i8 %2) {
157; CHECK-LABEL: foo8:
158; CHECK:       ; %bb.0:
159; CHECK-NEXT:    push r28
160; CHECK-NEXT:    push r29
161; CHECK-NEXT:    in r28, 61
162; CHECK-NEXT:    in r29, 62
163; CHECK-NEXT:    add r22, r20
164; CHECK-NEXT:    ldd r24, Y+5
165; CHECK-NEXT:    sub r24, r22
166; CHECK-NEXT:    pop r29
167; CHECK-NEXT:    pop r28
168; CHECK-NEXT:    ret
169  %4 = extractvalue [3 x i8] %0, 0
170  %5 = add i8 %4, %1
171  %6 = sub i8 %2, %5
172  ret i8 %6
173}
174
175; NOTE: %0 is passed via registers, though there are 6 vacant registers.
176; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows
177;        how arguments are passed.
178define i8 @foo9([7 x i8] %0) {
179; CHECK-LABEL: foo9:
180; CHECK:       ; %bb.0:
181; CHECK-NEXT:    push r28
182; CHECK-NEXT:    push r29
183; CHECK-NEXT:    in r28, 61
184; CHECK-NEXT:    in r29, 62
185; CHECK-NEXT:    ldd r25, Y+6
186; CHECK-NEXT:    ldd r24, Y+5
187; CHECK-NEXT:    add r24, r25
188; CHECK-NEXT:    pop r29
189; CHECK-NEXT:    pop r28
190; CHECK-NEXT:    ret
191  %2 = extractvalue [7 x i8] %0, 0
192  %3 = extractvalue [7 x i8] %0, 1
193  %4 = add i8 %2, %3
194  ret i8 %4
195}
196
197; NOTE: %0 costs six registers, while %1 and %2 are passed via the stack.
198; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows
199;        how arguments are passed.
200define i8 @fooa([6 x i8] %0, i8 %1, i8 %2) {
201; CHECK-LABEL: fooa:
202; CHECK:       ; %bb.0:
203; CHECK-NEXT:    push r28
204; CHECK-NEXT:    push r29
205; CHECK-NEXT:    in r28, 61
206; CHECK-NEXT:    in r29, 62
207; CHECK-NEXT:    ldd r25, Y+5
208; CHECK-NEXT:    ldd r24, Y+6
209; CHECK-NEXT:    sub r24, r25
210; CHECK-NEXT:    sub r24, r20
211; CHECK-NEXT:    pop r29
212; CHECK-NEXT:    pop r28
213; CHECK-NEXT:    ret
214  %4 = extractvalue [6 x i8] %0, 0
215  %5 = sub i8 %2, %1
216  %6 = sub i8 %5, %4
217  ret i8 %6
218}
219