1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 < %s | FileCheck -check-prefix=RV32 %s 3; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefix=RV64 %s 4; RUN: llc -mtriple=riscv32 -frame-pointer=all -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32-WITHFP %s 6; RUN: llc -mtriple=riscv64 -frame-pointer=all -verify-machineinstrs < %s \ 7; RUN: | FileCheck -check-prefix=RV64-WITHFP %s 8 9define void @trivial() { 10; RV32-LABEL: trivial: 11; RV32: # %bb.0: 12; RV32-NEXT: ret 13; 14; RV64-LABEL: trivial: 15; RV64: # %bb.0: 16; RV64-NEXT: ret 17; 18; RV32-WITHFP-LABEL: trivial: 19; RV32-WITHFP: # %bb.0: 20; RV32-WITHFP-NEXT: addi sp, sp, -16 21; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 16 22; RV32-WITHFP-NEXT: sw ra, 12(sp) 23; RV32-WITHFP-NEXT: sw s0, 8(sp) 24; RV32-WITHFP-NEXT: .cfi_offset ra, -4 25; RV32-WITHFP-NEXT: .cfi_offset s0, -8 26; RV32-WITHFP-NEXT: addi s0, sp, 16 27; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 0 28; RV32-WITHFP-NEXT: lw s0, 8(sp) 29; RV32-WITHFP-NEXT: lw ra, 12(sp) 30; RV32-WITHFP-NEXT: addi sp, sp, 16 31; RV32-WITHFP-NEXT: ret 32; 33; RV64-WITHFP-LABEL: trivial: 34; RV64-WITHFP: # %bb.0: 35; RV64-WITHFP-NEXT: addi sp, sp, -16 36; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 16 37; RV64-WITHFP-NEXT: sd ra, 8(sp) 38; RV64-WITHFP-NEXT: sd s0, 0(sp) 39; RV64-WITHFP-NEXT: .cfi_offset ra, -8 40; RV64-WITHFP-NEXT: .cfi_offset s0, -16 41; RV64-WITHFP-NEXT: addi s0, sp, 16 42; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 0 43; RV64-WITHFP-NEXT: ld s0, 0(sp) 44; RV64-WITHFP-NEXT: ld ra, 8(sp) 45; RV64-WITHFP-NEXT: addi sp, sp, 16 46; RV64-WITHFP-NEXT: ret 47 ret void 48} 49 50define void @stack_alloc(i32 signext %size) { 51; RV32-LABEL: stack_alloc: 52; RV32: # %bb.0: # %entry 53; RV32-NEXT: addi sp, sp, -16 54; RV32-NEXT: .cfi_def_cfa_offset 16 55; RV32-NEXT: sw ra, 12(sp) 56; RV32-NEXT: sw s0, 8(sp) 57; RV32-NEXT: .cfi_offset ra, -4 58; RV32-NEXT: .cfi_offset s0, -8 59; RV32-NEXT: addi s0, sp, 16 60; RV32-NEXT: .cfi_def_cfa s0, 0 61; RV32-NEXT: addi a0, a0, 15 62; RV32-NEXT: andi a0, a0, -16 63; RV32-NEXT: sub a0, sp, a0 64; RV32-NEXT: mv sp, a0 65; RV32-NEXT: call callee_with_args 66; RV32-NEXT: addi sp, s0, -16 67; RV32-NEXT: lw s0, 8(sp) 68; RV32-NEXT: lw ra, 12(sp) 69; RV32-NEXT: addi sp, sp, 16 70; RV32-NEXT: ret 71; 72; RV64-LABEL: stack_alloc: 73; RV64: # %bb.0: # %entry 74; RV64-NEXT: addi sp, sp, -16 75; RV64-NEXT: .cfi_def_cfa_offset 16 76; RV64-NEXT: sd ra, 8(sp) 77; RV64-NEXT: sd s0, 0(sp) 78; RV64-NEXT: .cfi_offset ra, -8 79; RV64-NEXT: .cfi_offset s0, -16 80; RV64-NEXT: addi s0, sp, 16 81; RV64-NEXT: .cfi_def_cfa s0, 0 82; RV64-NEXT: slli a0, a0, 32 83; RV64-NEXT: srli a0, a0, 32 84; RV64-NEXT: addi a0, a0, 15 85; RV64-NEXT: addi a1, zero, 1 86; RV64-NEXT: slli a1, a1, 33 87; RV64-NEXT: addi a1, a1, -16 88; RV64-NEXT: and a0, a0, a1 89; RV64-NEXT: sub a0, sp, a0 90; RV64-NEXT: mv sp, a0 91; RV64-NEXT: call callee_with_args 92; RV64-NEXT: addi sp, s0, -16 93; RV64-NEXT: ld s0, 0(sp) 94; RV64-NEXT: ld ra, 8(sp) 95; RV64-NEXT: addi sp, sp, 16 96; RV64-NEXT: ret 97; 98; RV32-WITHFP-LABEL: stack_alloc: 99; RV32-WITHFP: # %bb.0: # %entry 100; RV32-WITHFP-NEXT: addi sp, sp, -16 101; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 16 102; RV32-WITHFP-NEXT: sw ra, 12(sp) 103; RV32-WITHFP-NEXT: sw s0, 8(sp) 104; RV32-WITHFP-NEXT: .cfi_offset ra, -4 105; RV32-WITHFP-NEXT: .cfi_offset s0, -8 106; RV32-WITHFP-NEXT: addi s0, sp, 16 107; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 0 108; RV32-WITHFP-NEXT: addi a0, a0, 15 109; RV32-WITHFP-NEXT: andi a0, a0, -16 110; RV32-WITHFP-NEXT: sub a0, sp, a0 111; RV32-WITHFP-NEXT: mv sp, a0 112; RV32-WITHFP-NEXT: call callee_with_args 113; RV32-WITHFP-NEXT: addi sp, s0, -16 114; RV32-WITHFP-NEXT: lw s0, 8(sp) 115; RV32-WITHFP-NEXT: lw ra, 12(sp) 116; RV32-WITHFP-NEXT: addi sp, sp, 16 117; RV32-WITHFP-NEXT: ret 118; 119; RV64-WITHFP-LABEL: stack_alloc: 120; RV64-WITHFP: # %bb.0: # %entry 121; RV64-WITHFP-NEXT: addi sp, sp, -16 122; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 16 123; RV64-WITHFP-NEXT: sd ra, 8(sp) 124; RV64-WITHFP-NEXT: sd s0, 0(sp) 125; RV64-WITHFP-NEXT: .cfi_offset ra, -8 126; RV64-WITHFP-NEXT: .cfi_offset s0, -16 127; RV64-WITHFP-NEXT: addi s0, sp, 16 128; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 0 129; RV64-WITHFP-NEXT: slli a0, a0, 32 130; RV64-WITHFP-NEXT: srli a0, a0, 32 131; RV64-WITHFP-NEXT: addi a0, a0, 15 132; RV64-WITHFP-NEXT: addi a1, zero, 1 133; RV64-WITHFP-NEXT: slli a1, a1, 33 134; RV64-WITHFP-NEXT: addi a1, a1, -16 135; RV64-WITHFP-NEXT: and a0, a0, a1 136; RV64-WITHFP-NEXT: sub a0, sp, a0 137; RV64-WITHFP-NEXT: mv sp, a0 138; RV64-WITHFP-NEXT: call callee_with_args 139; RV64-WITHFP-NEXT: addi sp, s0, -16 140; RV64-WITHFP-NEXT: ld s0, 0(sp) 141; RV64-WITHFP-NEXT: ld ra, 8(sp) 142; RV64-WITHFP-NEXT: addi sp, sp, 16 143; RV64-WITHFP-NEXT: ret 144entry: 145 %0 = alloca i8, i32 %size, align 16 146 call void @callee_with_args(i8* nonnull %0) 147 ret void 148} 149 150define void @branch_and_tail_call(i1 %a) { 151; RV32-LABEL: branch_and_tail_call: 152; RV32: # %bb.0: 153; RV32-NEXT: addi sp, sp, -16 154; RV32-NEXT: .cfi_def_cfa_offset 16 155; RV32-NEXT: sw ra, 12(sp) 156; RV32-NEXT: .cfi_offset ra, -4 157; RV32-NEXT: andi a0, a0, 1 158; RV32-NEXT: beqz a0, .LBB2_2 159; RV32-NEXT: # %bb.1: # %blue_pill 160; RV32-NEXT: lw ra, 12(sp) 161; RV32-NEXT: addi sp, sp, 16 162; RV32-NEXT: tail callee1 163; RV32-NEXT: .LBB2_2: # %red_pill 164; RV32-NEXT: call callee2 165; RV32-NEXT: lw ra, 12(sp) 166; RV32-NEXT: addi sp, sp, 16 167; RV32-NEXT: ret 168; 169; RV64-LABEL: branch_and_tail_call: 170; RV64: # %bb.0: 171; RV64-NEXT: addi sp, sp, -16 172; RV64-NEXT: .cfi_def_cfa_offset 16 173; RV64-NEXT: sd ra, 8(sp) 174; RV64-NEXT: .cfi_offset ra, -8 175; RV64-NEXT: andi a0, a0, 1 176; RV64-NEXT: beqz a0, .LBB2_2 177; RV64-NEXT: # %bb.1: # %blue_pill 178; RV64-NEXT: ld ra, 8(sp) 179; RV64-NEXT: addi sp, sp, 16 180; RV64-NEXT: tail callee1 181; RV64-NEXT: .LBB2_2: # %red_pill 182; RV64-NEXT: call callee2 183; RV64-NEXT: ld ra, 8(sp) 184; RV64-NEXT: addi sp, sp, 16 185; RV64-NEXT: ret 186; 187; RV32-WITHFP-LABEL: branch_and_tail_call: 188; RV32-WITHFP: # %bb.0: 189; RV32-WITHFP-NEXT: addi sp, sp, -16 190; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 16 191; RV32-WITHFP-NEXT: sw ra, 12(sp) 192; RV32-WITHFP-NEXT: sw s0, 8(sp) 193; RV32-WITHFP-NEXT: .cfi_offset ra, -4 194; RV32-WITHFP-NEXT: .cfi_offset s0, -8 195; RV32-WITHFP-NEXT: addi s0, sp, 16 196; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 0 197; RV32-WITHFP-NEXT: andi a0, a0, 1 198; RV32-WITHFP-NEXT: beqz a0, .LBB2_2 199; RV32-WITHFP-NEXT: # %bb.1: # %blue_pill 200; RV32-WITHFP-NEXT: lw s0, 8(sp) 201; RV32-WITHFP-NEXT: lw ra, 12(sp) 202; RV32-WITHFP-NEXT: addi sp, sp, 16 203; RV32-WITHFP-NEXT: tail callee1 204; RV32-WITHFP-NEXT: .LBB2_2: # %red_pill 205; RV32-WITHFP-NEXT: call callee2 206; RV32-WITHFP-NEXT: lw s0, 8(sp) 207; RV32-WITHFP-NEXT: lw ra, 12(sp) 208; RV32-WITHFP-NEXT: addi sp, sp, 16 209; RV32-WITHFP-NEXT: ret 210; 211; RV64-WITHFP-LABEL: branch_and_tail_call: 212; RV64-WITHFP: # %bb.0: 213; RV64-WITHFP-NEXT: addi sp, sp, -16 214; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 16 215; RV64-WITHFP-NEXT: sd ra, 8(sp) 216; RV64-WITHFP-NEXT: sd s0, 0(sp) 217; RV64-WITHFP-NEXT: .cfi_offset ra, -8 218; RV64-WITHFP-NEXT: .cfi_offset s0, -16 219; RV64-WITHFP-NEXT: addi s0, sp, 16 220; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 0 221; RV64-WITHFP-NEXT: andi a0, a0, 1 222; RV64-WITHFP-NEXT: beqz a0, .LBB2_2 223; RV64-WITHFP-NEXT: # %bb.1: # %blue_pill 224; RV64-WITHFP-NEXT: ld s0, 0(sp) 225; RV64-WITHFP-NEXT: ld ra, 8(sp) 226; RV64-WITHFP-NEXT: addi sp, sp, 16 227; RV64-WITHFP-NEXT: tail callee1 228; RV64-WITHFP-NEXT: .LBB2_2: # %red_pill 229; RV64-WITHFP-NEXT: call callee2 230; RV64-WITHFP-NEXT: ld s0, 0(sp) 231; RV64-WITHFP-NEXT: ld ra, 8(sp) 232; RV64-WITHFP-NEXT: addi sp, sp, 16 233; RV64-WITHFP-NEXT: ret 234 br i1 %a, label %blue_pill, label %red_pill 235blue_pill: 236 tail call void @callee1() 237 ret void 238red_pill: 239 call void @callee2() 240 ret void 241} 242 243declare void @callee1() 244declare void @callee2() 245declare void @callee_with_args(i8*) 246