1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple riscv32 -enable-shrink-wrap=false < %s \
3; RUN:   | FileCheck %s -check-prefix=RV32I-SW-NO
4; RUN: llc -mtriple riscv32 < %s \
5; RUN:   | FileCheck %s -check-prefix=RV32I-SW
6; RUN: llc -mtriple riscv32 -mattr=+save-restore < %s \
7; RUN:   | FileCheck %s -check-prefix=RV32I-SW-SR
8; RUN: llc -mtriple riscv64 < %s \
9; RUN:   | FileCheck %s -check-prefix=RV64I-SW
10
11declare void @abort()
12
13define void @eliminate_restore(i32 %n) nounwind {
14; RV32I-SW-NO-LABEL: eliminate_restore:
15; RV32I-SW-NO:       # %bb.0:
16; RV32I-SW-NO-NEXT:    addi sp, sp, -16
17; RV32I-SW-NO-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
18; RV32I-SW-NO-NEXT:    li a1, 32
19; RV32I-SW-NO-NEXT:    bgeu a1, a0, .LBB0_2
20; RV32I-SW-NO-NEXT:  # %bb.1: # %if.end
21; RV32I-SW-NO-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
22; RV32I-SW-NO-NEXT:    addi sp, sp, 16
23; RV32I-SW-NO-NEXT:    ret
24; RV32I-SW-NO-NEXT:  .LBB0_2: # %if.then
25; RV32I-SW-NO-NEXT:    call abort@plt
26;
27; RV32I-SW-LABEL: eliminate_restore:
28; RV32I-SW:       # %bb.0:
29; RV32I-SW-NEXT:    li a1, 32
30; RV32I-SW-NEXT:    bgeu a1, a0, .LBB0_2
31; RV32I-SW-NEXT:  # %bb.1: # %if.end
32; RV32I-SW-NEXT:    ret
33; RV32I-SW-NEXT:  .LBB0_2: # %if.then
34; RV32I-SW-NEXT:    addi sp, sp, -16
35; RV32I-SW-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
36; RV32I-SW-NEXT:    call abort@plt
37;
38; RV32I-SW-SR-LABEL: eliminate_restore:
39; RV32I-SW-SR:       # %bb.0:
40; RV32I-SW-SR-NEXT:    li a1, 32
41; RV32I-SW-SR-NEXT:    bgeu a1, a0, .LBB0_2
42; RV32I-SW-SR-NEXT:  # %bb.1: # %if.end
43; RV32I-SW-SR-NEXT:    ret
44; RV32I-SW-SR-NEXT:  .LBB0_2: # %if.then
45; RV32I-SW-SR-NEXT:    call t0, __riscv_save_0
46; RV32I-SW-SR-NEXT:    call abort@plt
47;
48; RV64I-SW-LABEL: eliminate_restore:
49; RV64I-SW:       # %bb.0:
50; RV64I-SW-NEXT:    sext.w a0, a0
51; RV64I-SW-NEXT:    li a1, 32
52; RV64I-SW-NEXT:    bgeu a1, a0, .LBB0_2
53; RV64I-SW-NEXT:  # %bb.1: # %if.end
54; RV64I-SW-NEXT:    ret
55; RV64I-SW-NEXT:  .LBB0_2: # %if.then
56; RV64I-SW-NEXT:    addi sp, sp, -16
57; RV64I-SW-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
58; RV64I-SW-NEXT:    call abort@plt
59  %cmp = icmp ule i32 %n, 32
60  br i1 %cmp, label %if.then, label %if.end
61
62if.then:
63  call void @abort()
64  unreachable
65
66if.end:
67  ret void
68}
69
70declare void @notdead(i8*)
71
72define void @conditional_alloca(i32 %n) nounwind {
73; RV32I-SW-NO-LABEL: conditional_alloca:
74; RV32I-SW-NO:       # %bb.0:
75; RV32I-SW-NO-NEXT:    addi sp, sp, -16
76; RV32I-SW-NO-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
77; RV32I-SW-NO-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
78; RV32I-SW-NO-NEXT:    addi s0, sp, 16
79; RV32I-SW-NO-NEXT:    li a1, 32
80; RV32I-SW-NO-NEXT:    bltu a1, a0, .LBB1_2
81; RV32I-SW-NO-NEXT:  # %bb.1: # %if.then
82; RV32I-SW-NO-NEXT:    addi a0, a0, 15
83; RV32I-SW-NO-NEXT:    andi a0, a0, -16
84; RV32I-SW-NO-NEXT:    sub a0, sp, a0
85; RV32I-SW-NO-NEXT:    mv sp, a0
86; RV32I-SW-NO-NEXT:    call notdead@plt
87; RV32I-SW-NO-NEXT:  .LBB1_2: # %if.end
88; RV32I-SW-NO-NEXT:    addi sp, s0, -16
89; RV32I-SW-NO-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
90; RV32I-SW-NO-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
91; RV32I-SW-NO-NEXT:    addi sp, sp, 16
92; RV32I-SW-NO-NEXT:    ret
93;
94; RV32I-SW-LABEL: conditional_alloca:
95; RV32I-SW:       # %bb.0:
96; RV32I-SW-NEXT:    li a1, 32
97; RV32I-SW-NEXT:    bltu a1, a0, .LBB1_2
98; RV32I-SW-NEXT:  # %bb.1: # %if.then
99; RV32I-SW-NEXT:    addi sp, sp, -16
100; RV32I-SW-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
101; RV32I-SW-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
102; RV32I-SW-NEXT:    addi s0, sp, 16
103; RV32I-SW-NEXT:    addi a0, a0, 15
104; RV32I-SW-NEXT:    andi a0, a0, -16
105; RV32I-SW-NEXT:    sub a0, sp, a0
106; RV32I-SW-NEXT:    mv sp, a0
107; RV32I-SW-NEXT:    call notdead@plt
108; RV32I-SW-NEXT:    addi sp, s0, -16
109; RV32I-SW-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
110; RV32I-SW-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
111; RV32I-SW-NEXT:    addi sp, sp, 16
112; RV32I-SW-NEXT:  .LBB1_2: # %if.end
113; RV32I-SW-NEXT:    ret
114;
115; RV32I-SW-SR-LABEL: conditional_alloca:
116; RV32I-SW-SR:       # %bb.0:
117; RV32I-SW-SR-NEXT:    li a1, 32
118; RV32I-SW-SR-NEXT:    bltu a1, a0, .LBB1_2
119; RV32I-SW-SR-NEXT:  # %bb.1: # %if.then
120; RV32I-SW-SR-NEXT:    call t0, __riscv_save_1
121; RV32I-SW-SR-NEXT:    addi s0, sp, 16
122; RV32I-SW-SR-NEXT:    addi a0, a0, 15
123; RV32I-SW-SR-NEXT:    andi a0, a0, -16
124; RV32I-SW-SR-NEXT:    sub a0, sp, a0
125; RV32I-SW-SR-NEXT:    mv sp, a0
126; RV32I-SW-SR-NEXT:    call notdead@plt
127; RV32I-SW-SR-NEXT:    addi sp, s0, -16
128; RV32I-SW-SR-NEXT:    tail __riscv_restore_1
129; RV32I-SW-SR-NEXT:  .LBB1_2: # %if.end
130; RV32I-SW-SR-NEXT:    ret
131;
132; RV64I-SW-LABEL: conditional_alloca:
133; RV64I-SW:       # %bb.0:
134; RV64I-SW-NEXT:    sext.w a1, a0
135; RV64I-SW-NEXT:    li a2, 32
136; RV64I-SW-NEXT:    bltu a2, a1, .LBB1_2
137; RV64I-SW-NEXT:  # %bb.1: # %if.then
138; RV64I-SW-NEXT:    addi sp, sp, -16
139; RV64I-SW-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
140; RV64I-SW-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
141; RV64I-SW-NEXT:    addi s0, sp, 16
142; RV64I-SW-NEXT:    slli a0, a0, 32
143; RV64I-SW-NEXT:    srli a0, a0, 32
144; RV64I-SW-NEXT:    addi a0, a0, 15
145; RV64I-SW-NEXT:    andi a0, a0, -16
146; RV64I-SW-NEXT:    sub a0, sp, a0
147; RV64I-SW-NEXT:    mv sp, a0
148; RV64I-SW-NEXT:    call notdead@plt
149; RV64I-SW-NEXT:    addi sp, s0, -16
150; RV64I-SW-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
151; RV64I-SW-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
152; RV64I-SW-NEXT:    addi sp, sp, 16
153; RV64I-SW-NEXT:  .LBB1_2: # %if.end
154; RV64I-SW-NEXT:    ret
155  %cmp = icmp ule i32 %n, 32
156  br i1 %cmp, label %if.then, label %if.end
157
158if.then:
159  %addr = alloca i8, i32 %n
160  call void @notdead(i8* %addr)
161  br label %if.end
162
163if.end:
164  ret void
165}
166