Does armclang saves all needed register on stack with attribute("IRQ")?

  armclang, c++, interrupt

i’m working with Keil ARMCompiler 6.15 (armclang.exe) and i’m in doubt of the correctess of the generated assembler code.
It seems to me that the attribute ‘interrupt("IRQ")’ is ignored.
For me r1 and r2 should be saved on the stack, too.
When i remove the attribute ‘used’ my complete function is removed (optimization).

Can anyone see the mistake i made or what i’ve forgotten?

Originally the code was created for gcc.

Attributes used for interrupt routines:

#define INTERRUPT_PROCEDURE __attribute__((interrupt("IRQ"),used,section(".IsrSection")))
#define ISR_VARIABLE __attribute__((section(".IsrSection")))
#define FAST_SHARED_DATA __attribute__((section(".FastSharedDataSection")))

C++ Code:

uint64_t volatile FAST_SHARED_DATA systick_value = uint64_t(0);
extern "C" {
    void INTERRUPT_PROCEDURE SysTick_Handler()

Assembler Code:

0x08001280  push {r4, r6, r7, lr} 
0x08001282  add r7, sp, #8 
0x08001284  mov r4, sp 
0x08001286  bfc r4, #0, #3 
0x0800128a  mov sp, r4 
0x0800128c  movw r0, #8192  ; 0x2000 
0x08001290  movt r0, #8192  ; 0x2000 
0x08001294  ldrd r1, r2, [r0] 
0x08001298  adds r1, #1 
0x0800129a  adc.w r2, r2, #0 
0x0800129e  strd r1, r2, [r0] 
0x080012a2  sub.w r4, r7, #8 
0x080012a6  mov sp, r4 
0x080012a8  pop {r4, r6, r7, pc} 
0x080012aa  movs r0, r0 
0x080012ac  movs r0, r0 
0x080012ae  movs r0, r0 

Kind regards

Source: Windows Questions C++