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