175 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV32I3; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64I4 5; This test case test the LocalStackSlotAllocation pass that use a base register6; for the frame index that its offset is out-of-range (for RISC-V. the immediate7; is 12 bits for the load store instruction (excludes vector load / store))8define void @use_frame_base_reg() {9; RV32I-LABEL: use_frame_base_reg:10; RV32I: # %bb.0:11; RV32I-NEXT: lui a0, 2412; RV32I-NEXT: addi a0, a0, 171213; RV32I-NEXT: sub sp, sp, a014; RV32I-NEXT: .cfi_def_cfa_offset 10001615; RV32I-NEXT: lui a0, 2416; RV32I-NEXT: addi a0, a0, 170417; RV32I-NEXT: add a0, sp, a018; RV32I-NEXT: lbu zero, 4(a0)19; RV32I-NEXT: lbu zero, 0(a0)20; RV32I-NEXT: lui a0, 2421; RV32I-NEXT: addi a0, a0, 171222; RV32I-NEXT: add sp, sp, a023; RV32I-NEXT: .cfi_def_cfa_offset 024; RV32I-NEXT: ret25;26; RV64I-LABEL: use_frame_base_reg:27; RV64I: # %bb.0:28; RV64I-NEXT: lui a0, 2429; RV64I-NEXT: addi a0, a0, 171230; RV64I-NEXT: sub sp, sp, a031; RV64I-NEXT: .cfi_def_cfa_offset 10001632; RV64I-NEXT: lui a0, 2433; RV64I-NEXT: addi a0, a0, 170434; RV64I-NEXT: add a0, sp, a035; RV64I-NEXT: lbu zero, 4(a0)36; RV64I-NEXT: lbu zero, 0(a0)37; RV64I-NEXT: lui a0, 2438; RV64I-NEXT: addi a0, a0, 171239; RV64I-NEXT: add sp, sp, a040; RV64I-NEXT: .cfi_def_cfa_offset 041; RV64I-NEXT: ret42 43 %va = alloca i8, align 444 %va1 = alloca i8, align 445 %large = alloca [ 100000 x i8 ]46 %argp.cur = load volatile i8, ptr %va, align 447 %argp.next = load volatile i8, ptr %va1, align 448 ret void49}50 51; Test containing a load with its own local offset. Make sure isFrameOffsetLegal52; considers it and creates a virtual base register.53define void @load_with_offset() {54; RV32I-LABEL: load_with_offset:55; RV32I: # %bb.0:56; RV32I-NEXT: addi sp, sp, -204857; RV32I-NEXT: addi sp, sp, -46458; RV32I-NEXT: .cfi_def_cfa_offset 251259; RV32I-NEXT: addi a0, sp, 201260; RV32I-NEXT: lbu a1, 0(a0)61; RV32I-NEXT: sb a1, 0(a0)62; RV32I-NEXT: addi sp, sp, 203263; RV32I-NEXT: addi sp, sp, 48064; RV32I-NEXT: .cfi_def_cfa_offset 065; RV32I-NEXT: ret66;67; RV64I-LABEL: load_with_offset:68; RV64I: # %bb.0:69; RV64I-NEXT: addi sp, sp, -204870; RV64I-NEXT: addi sp, sp, -46471; RV64I-NEXT: .cfi_def_cfa_offset 251272; RV64I-NEXT: addi a0, sp, 201273; RV64I-NEXT: lbu a1, 0(a0)74; RV64I-NEXT: sb a1, 0(a0)75; RV64I-NEXT: addi sp, sp, 203276; RV64I-NEXT: addi sp, sp, 48077; RV64I-NEXT: .cfi_def_cfa_offset 078; RV64I-NEXT: ret79 80 %va = alloca [2500 x i8], align 481 %va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 200082 %load = load volatile i8, ptr %va_gep, align 483 store volatile i8 %load, ptr %va_gep, align 484 ret void85}86 87; Test containing a load with its own local offset that is smaller than the88; previous test case. Make sure we don't create a virtual base register.89define void @load_with_offset2() {90; RV32I-LABEL: load_with_offset2:91; RV32I: # %bb.0:92; RV32I-NEXT: addi sp, sp, -204893; RV32I-NEXT: addi sp, sp, -46494; RV32I-NEXT: .cfi_def_cfa_offset 251295; RV32I-NEXT: lbu a0, 1412(sp)96; RV32I-NEXT: sb a0, 1412(sp)97; RV32I-NEXT: addi sp, sp, 203298; RV32I-NEXT: addi sp, sp, 48099; RV32I-NEXT: .cfi_def_cfa_offset 0100; RV32I-NEXT: ret101;102; RV64I-LABEL: load_with_offset2:103; RV64I: # %bb.0:104; RV64I-NEXT: addi sp, sp, -2048105; RV64I-NEXT: addi sp, sp, -464106; RV64I-NEXT: .cfi_def_cfa_offset 2512107; RV64I-NEXT: lbu a0, 1412(sp)108; RV64I-NEXT: sb a0, 1412(sp)109; RV64I-NEXT: addi sp, sp, 2032110; RV64I-NEXT: addi sp, sp, 480111; RV64I-NEXT: .cfi_def_cfa_offset 0112; RV64I-NEXT: ret113 114 %va = alloca [2500 x i8], align 4115 %va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 1400116 %load = load volatile i8, ptr %va_gep, align 4117 store volatile i8 %load, ptr %va_gep, align 4118 ret void119}120 121define void @frame_pointer() "frame-pointer"="all" {122; RV32I-LABEL: frame_pointer:123; RV32I: # %bb.0:124; RV32I-NEXT: addi sp, sp, -2032125; RV32I-NEXT: .cfi_def_cfa_offset 2032126; RV32I-NEXT: sw ra, 2028(sp) # 4-byte Folded Spill127; RV32I-NEXT: sw s0, 2024(sp) # 4-byte Folded Spill128; RV32I-NEXT: .cfi_offset ra, -4129; RV32I-NEXT: .cfi_offset s0, -8130; RV32I-NEXT: addi s0, sp, 2032131; RV32I-NEXT: .cfi_def_cfa s0, 0132; RV32I-NEXT: addi sp, sp, -480133; RV32I-NEXT: lbu a0, -1960(s0)134; RV32I-NEXT: sb a0, -1960(s0)135; RV32I-NEXT: addi sp, sp, 480136; RV32I-NEXT: .cfi_def_cfa sp, 2032137; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload138; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload139; RV32I-NEXT: .cfi_restore ra140; RV32I-NEXT: .cfi_restore s0141; RV32I-NEXT: addi sp, sp, 2032142; RV32I-NEXT: .cfi_def_cfa_offset 0143; RV32I-NEXT: ret144;145; RV64I-LABEL: frame_pointer:146; RV64I: # %bb.0:147; RV64I-NEXT: addi sp, sp, -2032148; RV64I-NEXT: .cfi_def_cfa_offset 2032149; RV64I-NEXT: sd ra, 2024(sp) # 8-byte Folded Spill150; RV64I-NEXT: sd s0, 2016(sp) # 8-byte Folded Spill151; RV64I-NEXT: .cfi_offset ra, -8152; RV64I-NEXT: .cfi_offset s0, -16153; RV64I-NEXT: addi s0, sp, 2032154; RV64I-NEXT: .cfi_def_cfa s0, 0155; RV64I-NEXT: addi sp, sp, -496156; RV64I-NEXT: addi a0, s0, -1972157; RV64I-NEXT: lbu a1, 0(a0)158; RV64I-NEXT: sb a1, 0(a0)159; RV64I-NEXT: addi sp, sp, 496160; RV64I-NEXT: .cfi_def_cfa sp, 2032161; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload162; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload163; RV64I-NEXT: .cfi_restore ra164; RV64I-NEXT: .cfi_restore s0165; RV64I-NEXT: addi sp, sp, 2032166; RV64I-NEXT: .cfi_def_cfa_offset 0167; RV64I-NEXT: ret168 169 %va = alloca [2500 x i8], align 4170 %va_gep = getelementptr [2000 x i8], ptr %va, i64 0, i64 552171 %load = load volatile i8, ptr %va_gep, align 4172 store volatile i8 %load, ptr %va_gep, align 4173 ret void174}175