1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple riscv32-unknown-elf -o - %s \
3; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32
4; RUN: llc -mtriple riscv32-unknown-elf -mattr=+f -o - %s \
5; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32-F
6; RUN: llc -mtriple riscv32-unknown-elf -mattr=+f,+d -o - %s \
7; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32-FD
8;
9; The test case check that the function call in an interrupt handler will use
10; the correct CallPreservedMask as normal function. So only callee saved
11; registers could live through the function call.
12
13define dso_local void @handler() nounwind {
14; CHECK-RV32-LABEL: handler:
15; CHECK-RV32:       # %bb.0: # %entry
16; CHECK-RV32-NEXT:    addi sp, sp, -16
17; CHECK-RV32-NEXT:    sw ra, 12(sp)
18; CHECK-RV32-NEXT:    sw s0, 8(sp)
19; CHECK-RV32-NEXT:    lui a0, 2
20; CHECK-RV32-NEXT:    addi a0, a0, 4
21; CHECK-RV32-NEXT:    call read
22; CHECK-RV32-NEXT:    mv s0, a0
23; CHECK-RV32-NEXT:    call callee
24; CHECK-RV32-NEXT:    mv a0, s0
25; CHECK-RV32-NEXT:    lw s0, 8(sp)
26; CHECK-RV32-NEXT:    lw ra, 12(sp)
27; CHECK-RV32-NEXT:    addi sp, sp, 16
28; CHECK-RV32-NEXT:    tail write
29;
30; CHECK-RV32-F-LABEL: handler:
31; CHECK-RV32-F:       # %bb.0: # %entry
32; CHECK-RV32-F-NEXT:    addi sp, sp, -16
33; CHECK-RV32-F-NEXT:    sw ra, 12(sp)
34; CHECK-RV32-F-NEXT:    sw s0, 8(sp)
35; CHECK-RV32-F-NEXT:    lui a0, 2
36; CHECK-RV32-F-NEXT:    addi a0, a0, 4
37; CHECK-RV32-F-NEXT:    call read
38; CHECK-RV32-F-NEXT:    mv s0, a0
39; CHECK-RV32-F-NEXT:    call callee
40; CHECK-RV32-F-NEXT:    mv a0, s0
41; CHECK-RV32-F-NEXT:    lw s0, 8(sp)
42; CHECK-RV32-F-NEXT:    lw ra, 12(sp)
43; CHECK-RV32-F-NEXT:    addi sp, sp, 16
44; CHECK-RV32-F-NEXT:    tail write
45;
46; CHECK-RV32-FD-LABEL: handler:
47; CHECK-RV32-FD:       # %bb.0: # %entry
48; CHECK-RV32-FD-NEXT:    addi sp, sp, -16
49; CHECK-RV32-FD-NEXT:    sw ra, 12(sp)
50; CHECK-RV32-FD-NEXT:    sw s0, 8(sp)
51; CHECK-RV32-FD-NEXT:    lui a0, 2
52; CHECK-RV32-FD-NEXT:    addi a0, a0, 4
53; CHECK-RV32-FD-NEXT:    call read
54; CHECK-RV32-FD-NEXT:    mv s0, a0
55; CHECK-RV32-FD-NEXT:    call callee
56; CHECK-RV32-FD-NEXT:    mv a0, s0
57; CHECK-RV32-FD-NEXT:    lw s0, 8(sp)
58; CHECK-RV32-FD-NEXT:    lw ra, 12(sp)
59; CHECK-RV32-FD-NEXT:    addi sp, sp, 16
60; CHECK-RV32-FD-NEXT:    tail write
61entry:
62  %call = tail call i32 @read(i32 8196)
63  tail call void bitcast (void (...)* @callee to void ()*)()
64  tail call void @write(i32 %call)
65  ret void
66}
67
68declare i32 @read(i32)
69declare void @callee(...)
70declare void @write(i32)
71