1; RUN: llc -mtriple=avr < %s | FileCheck %s 2 3; CHECK-LABEL: ret_void_args_struct_i8_i32 4define void @ret_void_args_struct_i8_i32({ i8, i32 } %a) { 5start: 6 ; CHECK: sts 4, r20 7 %0 = extractvalue { i8, i32 } %a, 0 8 store volatile i8 %0, ptr inttoptr (i64 4 to ptr) 9 10 ; CHECK-NEXT: sts 8, r24 11 ; CHECK-NEXT: sts 7, r23 12 ; CHECK-NEXT: sts 6, r22 13 ; CHECK-NEXT: sts 5, r21 14 %1 = extractvalue { i8, i32 } %a, 1 15 store volatile i32 %1, ptr inttoptr (i64 5 to ptr) 16 ret void 17} 18 19; CHECK-LABEL: ret_void_args_struct_i8_i8_i8_i8 20define void @ret_void_args_struct_i8_i8_i8_i8({ i8, i8, i8, i8 } %a) { 21start: 22 ; CHECK: sts 4, r22 23 %0 = extractvalue { i8, i8, i8, i8 } %a, 0 24 store volatile i8 %0, ptr inttoptr (i64 4 to ptr) 25 ; CHECK-NEXT: sts 5, r23 26 %1 = extractvalue { i8, i8, i8, i8 } %a, 1 27 store volatile i8 %1, ptr inttoptr (i64 5 to ptr) 28 ; CHECK-NEXT: sts 6, r24 29 %2 = extractvalue { i8, i8, i8, i8 } %a, 2 30 store volatile i8 %2, ptr inttoptr (i64 6 to ptr) 31 ; CHECK-NEXT: sts 7, r25 32 %3 = extractvalue { i8, i8, i8, i8 } %a, 3 33 store volatile i8 %3, ptr inttoptr (i64 7 to ptr) 34 ret void 35} 36 37; CHECK-LABEL: ret_void_args_struct_i32_16_i8 38define void @ret_void_args_struct_i32_16_i8({ i32, i16, i8} %a) { 39start: 40 ; CHECK: sts 7, r21 41 ; CHECK-NEXT: sts 6, r20 42 ; CHECK-NEXT: sts 5, r19 43 ; CHECK-NEXT: sts 4, r18 44 %0 = extractvalue { i32, i16, i8 } %a, 0 45 store volatile i32 %0, ptr inttoptr (i64 4 to ptr) 46 47 ; CHECK-NEXT: sts 5, r23 48 ; CHECK-NEXT: sts 4, r22 49 %1 = extractvalue { i32, i16, i8 } %a, 1 50 store volatile i16 %1, ptr inttoptr (i64 4 to ptr) 51 52 ; CHECK-NEXT: sts 4, r24 53 %2 = extractvalue { i32, i16, i8 } %a, 2 54 store volatile i8 %2, ptr inttoptr (i64 4 to ptr) 55 ret void 56} 57 58; CHECK-LABEL: ret_void_args_struct_i8_i32_struct_i32_i8 59define void @ret_void_args_struct_i8_i32_struct_i32_i8({ i8, i32 } %a, { i32, i8 } %b) { 60start: 61 ; CHECK: sts 4, r20 62 %0 = extractvalue { i8, i32 } %a, 0 63 store volatile i8 %0, ptr inttoptr (i64 4 to ptr) 64 65 ; CHECK-NEXT: sts 8, r24 66 ; CHECK-NEXT: sts 7, r23 67 ; CHECK-NEXT: sts 6, r22 68 ; CHECK-NEXT: sts 5, r21 69 %1 = extractvalue { i8, i32 } %a, 1 70 store volatile i32 %1, ptr inttoptr (i64 5 to ptr) 71 72 ; CHECK-NEXT: sts 9, r17 73 ; CHECK-NEXT: sts 8, r16 74 ; CHECK-NEXT: sts 7, r15 75 ; CHECK-NEXT: sts 6, r14 76 %2 = extractvalue { i32, i8 } %b, 0 77 store volatile i32 %2, ptr inttoptr (i64 6 to ptr) 78 79 ; CHECK-NEXT: sts 7, r18 80 %3 = extractvalue { i32, i8 } %b, 1 81 store volatile i8 %3, ptr inttoptr (i64 7 to ptr) 82 ret void 83} 84 85; NOTE: The %0 (8-byte array) costs 8 registers and %1 (10-byte array) 86; NOTE: costs 10 registers. 87define i8 @foo0([8 x i8] %0, [10 x i8] %1) { 88; CHECK-LABEL: foo0: 89; CHECK: ; %bb.0: 90; CHECK-NEXT: sub r18, r8 91; CHECK-NEXT: mov r24, r18 92; CHECK-NEXT: ret 93 %3 = extractvalue [8 x i8] %0, 0 94 %4 = extractvalue [10 x i8] %1, 0 95 %5 = sub i8 %3, %4 96 ret i8 %5 97} 98 99; NOTE: The %0 (7-byte array) costs 8 registers and %1 (9-byte array) 100; NOTE: costs 10 registers. 101define i8 @foo1([7 x i8] %0, [9 x i8] %1) { 102; CHECK-LABEL: foo1: 103; CHECK: ; %bb.0: 104; CHECK-NEXT: sub r18, r8 105; CHECK-NEXT: mov r24, r18 106; CHECK-NEXT: ret 107 %3 = extractvalue [7 x i8] %0, 0 108 %4 = extractvalue [9 x i8] %1, 0 109 %5 = sub i8 %3, %4 110 ret i8 %5 111} 112 113; NOTE: Each argument (6-byte array) costs 6 registers. 114define i8 @foo2([6 x i8] %0, [6 x i8] %1, [6 x i8] %2) { 115; CHECK-LABEL: foo2: 116; CHECK: ; %bb.0: 117; CHECK-NEXT: sub r20, r14 118; CHECK-NEXT: add r20, r8 119; CHECK-NEXT: mov r24, r20 120; CHECK-NEXT: ret 121 %4 = extractvalue [6 x i8] %0, 0 122 %5 = extractvalue [6 x i8] %1, 0 123 %6 = extractvalue [6 x i8] %2, 0 124 %7 = sub i8 %4, %5 125 %8 = add i8 %7, %6 126 ret i8 %8 127} 128 129; NOTE: The %0 (9-byte array) costs 10 registers. Though there are 130; NOTE: 8 registers are vacant, the %b (9-byte array) has to be dropped 131; NOTE: to the stack. 132define i8 @foo3([9 x i8] %0, [9 x i8] %1) { 133; CHECK-LABEL: foo3: 134; CHECK: ; %bb.0: 135; CHECK-NEXT: push r16 136; CHECK-NEXT: push r28 137; CHECK-NEXT: push r29 138; CHECK-NEXT: in r28, 61 139; CHECK-NEXT: in r29, 62 140; CHECK-NEXT: ldd r24, Y+6 141; CHECK-NEXT: sub r16, r24 142; CHECK-NEXT: mov r24, r16 143; CHECK-NEXT: pop r29 144; CHECK-NEXT: pop r28 145; CHECK-NEXT: pop r16 146; CHECK-NEXT: ret 147 %3 = extractvalue [9 x i8] %0, 0 148 %4 = extractvalue [9 x i8] %1, 0 149 %5 = sub i8 %3, %4 150 ret i8 %5 151} 152 153; NOTE: Both %0 and %1 are 7-byte arrays, and cost total 16 registers. 154; NOTE: Though there are 2 registers are vacant, the %2 (7-byte array) has to 155; NOTE: be dropped to the stack. 156define i8 @foo4([7 x i8] %0, [7 x i8] %1, [7 x i8] %2) { 157; CHECK-LABEL: foo4: 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: sub r18, r10 164; CHECK-NEXT: ldd r24, Y+5 165; CHECK-NEXT: add r24, r18 166; CHECK-NEXT: pop r29 167; CHECK-NEXT: pop r28 168; CHECK-NEXT: ret 169 %4 = extractvalue [7 x i8] %0, 0 170 %5 = extractvalue [7 x i8] %1, 0 171 %6 = extractvalue [7 x i8] %2, 0 172 %7 = sub i8 %4, %5 173 %8 = add i8 %7, %6 174 ret i8 %8 175} 176