[llvm] f452b9d - [AVR] Fix wrong ABI of AVRTiny.

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 22 17:33:32 PST 2022


Author: Ben Shi
Date: 2022-11-23T09:32:47+08:00
New Revision: f452b9dcaff5e6b0fe123a0bba775eeb2194208a

URL: https://github.com/llvm/llvm-project/commit/f452b9dcaff5e6b0fe123a0bba775eeb2194208a
DIFF: https://github.com/llvm/llvm-project/commit/f452b9dcaff5e6b0fe123a0bba775eeb2194208a.diff

LOG: [AVR] Fix wrong ABI of AVRTiny.

A scalar which exceeds 4 bytes should be returned via stack, other
than via registers, on an AVRTiny device.

Reviewed By: aykevl

Differential Revision: https://reviews.llvm.org/D138201

Added: 
    

Modified: 
    llvm/lib/Target/AVR/AVRISelLowering.cpp
    llvm/test/CodeGen/AVR/return.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 0e8b5123b66a8..4daec6aef29e7 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1216,8 +1216,12 @@ static void analyzeReturnValues(const SmallVectorImpl<ArgT> &Args,
   unsigned NumArgs = Args.size();
   unsigned TotalBytes = getTotalArgumentsSizeInBytes(Args);
   // CanLowerReturn() guarantees this assertion.
-  assert(TotalBytes <= 8 &&
-         "return values greater than 8 bytes cannot be lowered");
+  if (Tiny)
+    assert(TotalBytes <= 4 &&
+           "return values greater than 4 bytes cannot be lowered on AVRTiny");
+  else
+    assert(TotalBytes <= 8 &&
+           "return values greater than 8 bytes cannot be lowered on AVR");
 
   // Choose the proper register list for argument passing according to the ABI.
   ArrayRef<MCPhysReg> RegList8;
@@ -1578,7 +1582,7 @@ bool AVRTargetLowering::CanLowerReturn(
   }
 
   unsigned TotalBytes = getTotalArgumentsSizeInBytes(Outs);
-  return TotalBytes <= 8;
+  return TotalBytes <= (Subtarget.hasTinyEncoding() ? 4 : 8);
 }
 
 SDValue

diff  --git a/llvm/test/CodeGen/AVR/return.ll b/llvm/test/CodeGen/AVR/return.ll
index f5f62aedc958d..770e40b6fdc0b 100644
--- a/llvm/test/CodeGen/AVR/return.ll
+++ b/llvm/test/CodeGen/AVR/return.ll
@@ -1,136 +1,348 @@
-; RUN: llc -mattr=avr6,sram < %s -march=avr | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mattr=avr6,sram -mtriple=avr < %s | FileCheck %s --check-prefix=AVR
+; RUN: llc -mattr=tinyencoding -mtriple=avr < %s | FileCheck %s --check-prefix=TINY
 
 ;TODO: test returning byval structs
 ; TODO: test naked functions
 
 define void @return_void() {
-; CHECK: return_void:{{[a-zA-Z0-9 #@]*}}
-; CHECK-NEXT: {{.*}}:
-; CHECK-NEXT: ret
+; AVR-LABEL: return_void:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return_void:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ret
     ret void
 }
 
 define i8 @return8_imm() {
-; CHECK-LABEL: return8_imm:
-; CHECK: ldi r24, 5
+; AVR-LABEL: return8_imm:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ldi r24, 5
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return8_imm:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ldi r24, 5
+; TINY-NEXT:    ret
     ret i8 5
 }
 
 define i8 @return8_arg(i8 %x) {
-; CHECK: return8_arg:{{[a-zA-Z0-9 #@]*}}
-; CHECK-NEXT: {{.*}}:
-; CHECK-NEXT: ret
+; AVR-LABEL: return8_arg:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return8_arg:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ret
     ret i8 %x
 }
 
 define i8 @return8_arg2(i8 %x, i8 %y, i8 %z) {
-; CHECK-LABEL: return8_arg2:
-; CHECK: mov r24, r20
+; AVR-LABEL: return8_arg2:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    mov r24, r20
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return8_arg2:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    mov r24, r20
+; TINY-NEXT:    ret
     ret i8 %z
 }
 
 define i16 @return16_imm() {
-; CHECK-LABEL: return16_imm:
-; CHECK: ldi r24, 57
-; CHECK: ldi r25, 48
+; AVR-LABEL: return16_imm:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ldi r24, 57
+; AVR-NEXT:    ldi r25, 48
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return16_imm:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ldi r24, 57
+; TINY-NEXT:    ldi r25, 48
+; TINY-NEXT:    ret
     ret i16 12345
 }
 
 define i16 @return16_arg(i16 %x) {
-; CHECK: return16_arg:{{[a-zA-Z0-9 #@]*}}
-; CHECK-NEXT: {{.*}}:
-; CHECK-NEXT: ret
+; AVR-LABEL: return16_arg:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return16_arg:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ret
     ret i16 %x
 }
 
 define i16 @return16_arg2(i16 %x, i16 %y, i16 %z) {
-; CHECK-LABEL: return16_arg2:
-; CHECK: movw r24, r20
+; AVR-LABEL: return16_arg2:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    movw r24, r20
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return16_arg2:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    mov r24, r20
+; TINY-NEXT:    mov r25, r21
+; TINY-NEXT:    ret
     ret i16 %z
 }
 
 define i32 @return32_imm() {
-; CHECK-LABEL: return32_imm:
-; CHECK: ldi r22, 21
-; CHECK: ldi r23, 205
-; CHECK: ldi r24, 91
-; CHECK: ldi r25, 7
+; AVR-LABEL: return32_imm:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ldi r22, 21
+; AVR-NEXT:    ldi r23, 205
+; AVR-NEXT:    ldi r24, 91
+; AVR-NEXT:    ldi r25, 7
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return32_imm:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ldi r22, 21
+; TINY-NEXT:    ldi r23, 205
+; TINY-NEXT:    ldi r24, 91
+; TINY-NEXT:    ldi r25, 7
+; TINY-NEXT:    ret
     ret i32 123456789
 }
 
 define i32 @return32_arg(i32 %x) {
-; CHECK: return32_arg:{{[a-zA-Z0-9 #@]*}}
-; CHECK-NEXT: {{.*}}:
-; CHECK-NEXT: ret
+; AVR-LABEL: return32_arg:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return32_arg:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ret
     ret i32 %x
 }
 
 define i32 @return32_arg2(i32 %x, i32 %y, i32 %z) {
-; CHECK-LABEL: return32_arg2:
-; CHECK: movw r22, r14
-; CHECK: movw r24, r16
+; AVR-LABEL: return32_arg2:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    movw r22, r14
+; AVR-NEXT:    movw r24, r16
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return32_arg2:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    push r28
+; TINY-NEXT:    push r29
+; TINY-NEXT:    in r28, 61
+; TINY-NEXT:    in r29, 62
+; TINY-NEXT:    ldd r22, Y+9
+; TINY-NEXT:    ldd r23, Y+10
+; TINY-NEXT:    ldd r24, Y+11
+; TINY-NEXT:    ldd r25, Y+12
+; TINY-NEXT:    pop r29
+; TINY-NEXT:    pop r28
+; TINY-NEXT:    ret
     ret i32 %z
 }
 
 define i64 @return64_imm() {
-; CHECK-LABEL: return64_imm:
-; CHECK: ldi r18, 204
-; CHECK: ldi r19, 204
-; CHECK: ldi r20, 104
-; CHECK: ldi r21, 37
-; CHECK: ldi r22, 25
-; CHECK: ldi r23, 22
-; CHECK: ldi r24, 236
-; CHECK: ldi r25, 190
+; AVR-LABEL: return64_imm:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ldi r18, 204
+; AVR-NEXT:    ldi r19, 204
+; AVR-NEXT:    ldi r20, 104
+; AVR-NEXT:    ldi r21, 37
+; AVR-NEXT:    ldi r22, 25
+; AVR-NEXT:    ldi r23, 22
+; AVR-NEXT:    ldi r24, 236
+; AVR-NEXT:    ldi r25, 190
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return64_imm:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    ldi r20, 236
+; TINY-NEXT:    ldi r21, 190
+; TINY-NEXT:    mov r30, r24
+; TINY-NEXT:    mov r31, r25
+; TINY-NEXT:    std Z+6, r20
+; TINY-NEXT:    std Z+7, r21
+; TINY-NEXT:    ldi r24, 25
+; TINY-NEXT:    ldi r25, 22
+; TINY-NEXT:    std Z+4, r24
+; TINY-NEXT:    std Z+5, r25
+; TINY-NEXT:    ldi r24, 104
+; TINY-NEXT:    ldi r25, 37
+; TINY-NEXT:    std Z+2, r24
+; TINY-NEXT:    std Z+3, r25
+; TINY-NEXT:    ldi r24, 204
+; TINY-NEXT:    ldi r25, 204
+; TINY-NEXT:    st Z, r24
+; TINY-NEXT:    std Z+1, r25
+; TINY-NEXT:    ret
     ret i64 13757395258967641292
 }
 
 define i64 @return64_arg(i64 %x) {
-; CHECK: return64_arg:{{[a-zA-Z0-9 #@]*}}
-; CHECK-NEXT: {{.*}}:
-; CHECK-NEXT: ret
+; AVR-LABEL: return64_arg:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return64_arg:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    push r28
+; TINY-NEXT:    push r29
+; TINY-NEXT:    in r28, 61
+; TINY-NEXT:    in r29, 62
+; TINY-NEXT:    ldd r20, Y+11
+; TINY-NEXT:    ldd r21, Y+12
+; TINY-NEXT:    mov r30, r24
+; TINY-NEXT:    mov r31, r25
+; TINY-NEXT:    std Z+6, r20
+; TINY-NEXT:    std Z+7, r21
+; TINY-NEXT:    ldd r24, Y+9
+; TINY-NEXT:    ldd r25, Y+10
+; TINY-NEXT:    std Z+4, r24
+; TINY-NEXT:    std Z+5, r25
+; TINY-NEXT:    ldd r24, Y+7
+; TINY-NEXT:    ldd r25, Y+8
+; TINY-NEXT:    std Z+2, r24
+; TINY-NEXT:    std Z+3, r25
+; TINY-NEXT:    ldd r24, Y+5
+; TINY-NEXT:    ldd r25, Y+6
+; TINY-NEXT:    st Z, r24
+; TINY-NEXT:    std Z+1, r25
+; TINY-NEXT:    pop r29
+; TINY-NEXT:    pop r28
+; TINY-NEXT:    ret
     ret i64 %x
 }
 
 define i64 @return64_arg2(i64 %x, i64 %y, i64 %z) {
-; CHECK-LABEL: return64_arg2:
-; CHECK: push r28
-; CHECK: push r29
-; CHECK: ldd r18, Y+5
-; CHECK: ldd r19, Y+6
-; CHECK: ldd r20, Y+7
-; CHECK: ldd r21, Y+8
-; CHECK: ldd r22, Y+9
-; CHECK: ldd r23, Y+10
-; CHECK: ldd r24, Y+11
-; CHECK: ldd r25, Y+12
-; CHECK: pop r29
-; CHECK: pop r28
+; AVR-LABEL: return64_arg2:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    push r28
+; AVR-NEXT:    push r29
+; AVR-NEXT:    in r28, 61
+; AVR-NEXT:    in r29, 62
+; AVR-NEXT:    ldd r18, Y+5
+; AVR-NEXT:    ldd r19, Y+6
+; AVR-NEXT:    ldd r20, Y+7
+; AVR-NEXT:    ldd r21, Y+8
+; AVR-NEXT:    ldd r22, Y+9
+; AVR-NEXT:    ldd r23, Y+10
+; AVR-NEXT:    ldd r24, Y+11
+; AVR-NEXT:    ldd r25, Y+12
+; AVR-NEXT:    pop r29
+; AVR-NEXT:    pop r28
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return64_arg2:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    push r28
+; TINY-NEXT:    push r29
+; TINY-NEXT:    in r28, 61
+; TINY-NEXT:    in r29, 62
+; TINY-NEXT:    ldd r20, Y+27
+; TINY-NEXT:    ldd r21, Y+28
+; TINY-NEXT:    mov r30, r24
+; TINY-NEXT:    mov r31, r25
+; TINY-NEXT:    std Z+6, r20
+; TINY-NEXT:    std Z+7, r21
+; TINY-NEXT:    ldd r24, Y+25
+; TINY-NEXT:    ldd r25, Y+26
+; TINY-NEXT:    std Z+4, r24
+; TINY-NEXT:    std Z+5, r25
+; TINY-NEXT:    ldd r24, Y+23
+; TINY-NEXT:    ldd r25, Y+24
+; TINY-NEXT:    std Z+2, r24
+; TINY-NEXT:    std Z+3, r25
+; TINY-NEXT:    ldd r24, Y+21
+; TINY-NEXT:    ldd r25, Y+22
+; TINY-NEXT:    st Z, r24
+; TINY-NEXT:    std Z+1, r25
+; TINY-NEXT:    pop r29
+; TINY-NEXT:    pop r28
+; TINY-NEXT:    ret
     ret i64 %z
 }
 
 define i32 @return64_trunc(i32 %a, i32 %b, i32 %c, i64 %d) {
-; CHECK-LABEL: return64_trunc:
-; CHECK: push r28
-; CHECK: push r29
-; CHECK: ldd r22, Y+5
-; CHECK: ldd r23, Y+6
-; CHECK: ldd r24, Y+7
-; CHECK: ldd r25, Y+8
-; CHECK: pop r29
-; CHECK: pop r28
+; AVR-LABEL: return64_trunc:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    push r28
+; AVR-NEXT:    push r29
+; AVR-NEXT:    in r28, 61
+; AVR-NEXT:    in r29, 62
+; AVR-NEXT:    ldd r22, Y+5
+; AVR-NEXT:    ldd r23, Y+6
+; AVR-NEXT:    ldd r24, Y+7
+; AVR-NEXT:    ldd r25, Y+8
+; AVR-NEXT:    pop r29
+; AVR-NEXT:    pop r28
+; AVR-NEXT:    ret
+;
+; TINY-LABEL: return64_trunc:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    push r28
+; TINY-NEXT:    push r29
+; TINY-NEXT:    in r28, 61
+; TINY-NEXT:    in r29, 62
+; TINY-NEXT:    ldd r22, Y+13
+; TINY-NEXT:    ldd r23, Y+14
+; TINY-NEXT:    ldd r24, Y+15
+; TINY-NEXT:    ldd r25, Y+16
+; TINY-NEXT:    pop r29
+; TINY-NEXT:    pop r28
+; TINY-NEXT:    ret
   %result = trunc i64 %d to i32
   ret i32 %result
 }
 
 define avr_intrcc void @interrupt_handler() {
-; CHECK-LABEL: interrupt_handler:
-; CHECK: reti
+; AVR-LABEL: interrupt_handler:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    sei
+; AVR-NEXT:    push r0
+; AVR-NEXT:    in r0, 63
+; AVR-NEXT:    push r0
+; AVR-NEXT:    pop r0
+; AVR-NEXT:    out 63, r0
+; AVR-NEXT:    pop r0
+; AVR-NEXT:    reti
+;
+; TINY-LABEL: interrupt_handler:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    sei
+; TINY-NEXT:    push r0
+; TINY-NEXT:    in r0, 63
+; TINY-NEXT:    push r0
+; TINY-NEXT:    pop r0
+; TINY-NEXT:    out 63, r0
+; TINY-NEXT:    pop r0
+; TINY-NEXT:    reti
   ret void
 }
 
 define avr_signalcc void @signal_handler() {
-; CHECK-LABEL: signal_handler:
-; CHECK: reti
+; AVR-LABEL: signal_handler:
+; AVR:       ; %bb.0:
+; AVR-NEXT:    push r0
+; AVR-NEXT:    in r0, 63
+; AVR-NEXT:    push r0
+; AVR-NEXT:    pop r0
+; AVR-NEXT:    out 63, r0
+; AVR-NEXT:    pop r0
+; AVR-NEXT:    reti
+;
+; TINY-LABEL: signal_handler:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    push r0
+; TINY-NEXT:    in r0, 63
+; TINY-NEXT:    push r0
+; TINY-NEXT:    pop r0
+; TINY-NEXT:    out 63, r0
+; TINY-NEXT:    pop r0
+; TINY-NEXT:    reti
   ret void
 }


        


More information about the llvm-commits mailing list