; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=avr -mcpu=avrtiny | FileCheck %s ; NOTE: Both %a(i8) and %b(i8) cost two registers. define i8 @foo0(i8 %a, i8 %b) { ; CHECK-LABEL: foo0: ; CHECK: ; %bb.0: ; CHECK-NEXT: sub r24, r22 ; CHECK-NEXT: ret %c = sub i8 %a, %b ret i8 %c } ; NOTE: Both %a(i16) and %b(i16) cost two registers. define i16 @foo1(i16 %a, i16 %b) { ; CHECK-LABEL: foo1: ; CHECK: ; %bb.0: ; CHECK-NEXT: sub r24, r22 ; CHECK-NEXT: sbc r25, r23 ; CHECK-NEXT: ret %c = sub i16 %a, %b ret i16 %c } ; NOTE: %a(i16), %b(i16) and %c(i16) each costs two registers. define i16 @foo2(i16 %a, i16 %b, i16 %c) { ; CHECK-LABEL: foo2: ; CHECK: ; %bb.0: ; CHECK-NEXT: sub r22, r24 ; CHECK-NEXT: sbc r23, r25 ; CHECK-NEXT: add r22, r20 ; CHECK-NEXT: adc r23, r21 ; CHECK-NEXT: mov r24, r22 ; CHECK-NEXT: mov r25, r23 ; CHECK-NEXT: ret %d = sub i16 %a, %b %e = sub i16 %c, %d ret i16 %e } ; NOTE: %a(i16), %b(i16) and %c(i16) each costs two registers, ; while %d(i16) is passed via the stack. ; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows ; how arguments are passed. define i16 @foo3(i16 %a, i16 %b, i16 %c, i16 %d) { ; CHECK-LABEL: foo3: ; CHECK: ; %bb.0: ; CHECK-NEXT: push r28 ; CHECK-NEXT: push r29 ; CHECK-NEXT: in r28, 61 ; CHECK-NEXT: in r29, 62 ; CHECK-NEXT: ldd r30, Y+5 ; CHECK-NEXT: ldd r31, Y+6 ; CHECK-NEXT: sub r20, r30 ; CHECK-NEXT: sbc r21, r31 ; CHECK-NEXT: sub r24, r22 ; CHECK-NEXT: sbc r25, r23 ; CHECK-NEXT: add r24, r20 ; CHECK-NEXT: adc r25, r21 ; CHECK-NEXT: pop r29 ; CHECK-NEXT: pop r28 ; CHECK-NEXT: ret %e = sub i16 %a, %b %g = sub i16 %c, %d %h = add i16 %e, %g ret i16 %h } ; NOTE: %a(i32) costs four registers, while %b(i32) is passed via the stack. ; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows ; how arguments are passed. define i32 @foo4(i32 %a, i32 %b) { ; CHECK-LABEL: foo4: ; CHECK: ; %bb.0: ; CHECK-NEXT: push r28 ; CHECK-NEXT: push r29 ; CHECK-NEXT: in r28, 61 ; CHECK-NEXT: in r29, 62 ; CHECK-NEXT: ldd r20, Y+5 ; CHECK-NEXT: ldd r21, Y+6 ; CHECK-NEXT: ldd r30, Y+7 ; CHECK-NEXT: ldd r31, Y+8 ; CHECK-NEXT: sub r20, r22 ; CHECK-NEXT: sbc r21, r23 ; CHECK-NEXT: sbc r30, r24 ; CHECK-NEXT: sbc r31, r25 ; CHECK-NEXT: mov r22, r20 ; CHECK-NEXT: mov r23, r21 ; CHECK-NEXT: mov r24, r30 ; CHECK-NEXT: mov r25, r31 ; CHECK-NEXT: pop r29 ; CHECK-NEXT: pop r28 ; CHECK-NEXT: ret %c = sub i32 %b, %a ret i32 %c } ; NOTE: %0 costs six registers, while %1 is passed via the stack. ; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows ; how arguments are passed. define i8 @foo5([5 x i8] %0, i8 %1) { ; CHECK-LABEL: foo5: ; CHECK: ; %bb.0: ; CHECK-NEXT: push r28 ; CHECK-NEXT: push r29 ; CHECK-NEXT: in r28, 61 ; CHECK-NEXT: in r29, 62 ; CHECK-NEXT: ldd r24, Y+5 ; CHECK-NEXT: add r24, r20 ; CHECK-NEXT: pop r29 ; CHECK-NEXT: pop r28 ; CHECK-NEXT: ret %3 = extractvalue [5 x i8] %0, 0 %4 = add i8 %3, %1 ret i8 %4 } ; NOTE: %0 costs two registers and %1 costs four registers. define i8 @foo6([2 x i8] %0, [4 x i8] %1) { ; CHECK-LABEL: foo6: ; CHECK: ; %bb.0: ; CHECK-NEXT: add r24, r20 ; CHECK-NEXT: ret %3 = extractvalue [2 x i8] %0, 0 %4 = extractvalue [4 x i8] %1, 0 %5 = add i8 %3, %4 ret i8 %5 } ; NOTE: %0 cost four registers, while %1 is passed via the stack, ; though there are two vacant registers. ; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows ; how arguments are passed. define i8 @foo7([3 x i8] %0, [3 x i8] %1) { ; CHECK-LABEL: foo7: ; CHECK: ; %bb.0: ; CHECK-NEXT: push r28 ; CHECK-NEXT: push r29 ; CHECK-NEXT: in r28, 61 ; CHECK-NEXT: in r29, 62 ; CHECK-NEXT: ldd r24, Y+5 ; CHECK-NEXT: add r24, r22 ; CHECK-NEXT: pop r29 ; CHECK-NEXT: pop r28 ; CHECK-NEXT: ret %3 = extractvalue [3 x i8] %0, 0 %4 = extractvalue [3 x i8] %1, 0 %5 = add i8 %3, %4 ret i8 %5 } ; NOTE: %0 costs four registers, and %1 costs two registers, while %2 is ; passed via the stack, though there is one vacant register. ; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows ; how arguments are passed. define i8 @foo8([3 x i8] %0, i8 %1, i8 %2) { ; CHECK-LABEL: foo8: ; CHECK: ; %bb.0: ; CHECK-NEXT: push r28 ; CHECK-NEXT: push r29 ; CHECK-NEXT: in r28, 61 ; CHECK-NEXT: in r29, 62 ; CHECK-NEXT: add r22, r20 ; CHECK-NEXT: ldd r24, Y+5 ; CHECK-NEXT: sub r24, r22 ; CHECK-NEXT: pop r29 ; CHECK-NEXT: pop r28 ; CHECK-NEXT: ret %4 = extractvalue [3 x i8] %0, 0 %5 = add i8 %4, %1 %6 = sub i8 %2, %5 ret i8 %6 } ; NOTE: %0 is passed via registers, though there are 6 vacant registers. ; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows ; how arguments are passed. define i8 @foo9([7 x i8] %0) { ; CHECK-LABEL: foo9: ; CHECK: ; %bb.0: ; CHECK-NEXT: push r28 ; CHECK-NEXT: push r29 ; CHECK-NEXT: in r28, 61 ; CHECK-NEXT: in r29, 62 ; CHECK-NEXT: ldd r25, Y+6 ; CHECK-NEXT: ldd r24, Y+5 ; CHECK-NEXT: add r24, r25 ; CHECK-NEXT: pop r29 ; CHECK-NEXT: pop r28 ; CHECK-NEXT: ret %2 = extractvalue [7 x i8] %0, 0 %3 = extractvalue [7 x i8] %0, 1 %4 = add i8 %2, %3 ret i8 %4 } ; NOTE: %0 costs six registers, while %1 and %2 are passed via the stack. ; FIXME: The `ldd` instruction is invalid on avrtiny, this test just shows ; how arguments are passed. define i8 @fooa([6 x i8] %0, i8 %1, i8 %2) { ; CHECK-LABEL: fooa: ; CHECK: ; %bb.0: ; CHECK-NEXT: push r28 ; CHECK-NEXT: push r29 ; CHECK-NEXT: in r28, 61 ; CHECK-NEXT: in r29, 62 ; CHECK-NEXT: ldd r25, Y+5 ; CHECK-NEXT: ldd r24, Y+6 ; CHECK-NEXT: sub r24, r25 ; CHECK-NEXT: sub r24, r20 ; CHECK-NEXT: pop r29 ; CHECK-NEXT: pop r28 ; CHECK-NEXT: ret %4 = extractvalue [6 x i8] %0, 0 %5 = sub i8 %2, %1 %6 = sub i8 %5, %4 ret i8 %6 }