Files
clang-p2996/llvm/test/CodeGen/AVR/zeroreg.ll
Ayke van Laethem a560e57a7e [AVR] Only push and clear R1 in interrupts when necessary
R1 is a reserved register, but LLVM gives the APIs to know when it is
used or not. So this patch uses these APIs to only save/clear/restore R1
in interrupts when necessary.

The main issue here was getting inline assembly to work. One could argue
that this is the job of Clang, but for consistency I've made sure that
R1 is always usable in inline assembly even if that means clearing it
when it might not be needed.

Information on inline assembly in AVR can be found here:

https://www.nongnu.org/avr-libc/user-manual/inline_asm.html#asm_code

Essentially, this seems to suggest that r1 can be freely used in avr-gcc
inline assembly, even without specifying it as an input operand.

Differential Revision: https://reviews.llvm.org/D117426
2022-08-15 14:29:38 +02:00

28 lines
697 B
LLVM

; RUN: llc -mattr=avr6,sram < %s -march=avr | FileCheck %s
; This file tests whether the compiler correctly works with the r1 register,
; clearing it when needed.
; Test regular use of r1 as a zero register.
; CHECK-LABEL: store8zero:
; CHECK: st {{[XYZ]}}, r1
; CHECK-NEXT: mov r24, r1
; CHECK-NEXT: ret
define i8 @store8zero(i8* %x) {
store i8 0, i8* %x
ret i8 0
}
; Test that mulitplication instructions (mul, muls, etc) clobber r1 and require
; a "clr r1" instruction.
; CHECK-LABEL: mul:
; CHECK: muls
; CHECK-NEXT: clr r1
; CHECK-NEXT: st {{[XYZ]}}, r0
; CHECK-NEXT: ret
define void @mul(i8* %ptr, i8 %n) {
%result = mul i8 %n, 3
store i8 %result, i8* %ptr
ret void
}