1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc --mtriple=loongarch32 -mattr=+d --verify-machineinstrs < %s \ 3; RUN: | FileCheck %s --check-prefix=LA32 4; RUN: llc --mtriple=loongarch64 -mattr=+d --verify-machineinstrs < %s \ 5; RUN: | FileCheck %s --check-prefix=LA64 6 7declare void @notdead(ptr) 8 9;; These tests must ensure the stack pointer is restored using the frame 10;; pointer 11 12define void @simple_alloca(i32 %n) nounwind { 13; LA32-LABEL: simple_alloca: 14; LA32: # %bb.0: 15; LA32-NEXT: addi.w $sp, $sp, -16 16; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill 17; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill 18; LA32-NEXT: addi.w $fp, $sp, 16 19; LA32-NEXT: addi.w $a0, $a0, 15 20; LA32-NEXT: bstrins.w $a0, $zero, 3, 0 21; LA32-NEXT: sub.w $a0, $sp, $a0 22; LA32-NEXT: move $sp, $a0 23; LA32-NEXT: bl %plt(notdead) 24; LA32-NEXT: addi.w $sp, $fp, -16 25; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload 26; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload 27; LA32-NEXT: addi.w $sp, $sp, 16 28; LA32-NEXT: ret 29; 30; LA64-LABEL: simple_alloca: 31; LA64: # %bb.0: 32; LA64-NEXT: addi.d $sp, $sp, -16 33; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill 34; LA64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill 35; LA64-NEXT: addi.d $fp, $sp, 16 36; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 37; LA64-NEXT: addi.d $a0, $a0, 15 38; LA64-NEXT: bstrpick.d $a0, $a0, 32, 4 39; LA64-NEXT: slli.d $a0, $a0, 4 40; LA64-NEXT: sub.d $a0, $sp, $a0 41; LA64-NEXT: move $sp, $a0 42; LA64-NEXT: bl %plt(notdead) 43; LA64-NEXT: addi.d $sp, $fp, -16 44; LA64-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload 45; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload 46; LA64-NEXT: addi.d $sp, $sp, 16 47; LA64-NEXT: ret 48 %1 = alloca i8, i32 %n 49 call void @notdead(ptr %1) 50 ret void 51} 52 53declare ptr @llvm.stacksave() 54declare void @llvm.stackrestore(ptr) 55 56define void @scoped_alloca(i32 %n) nounwind { 57; LA32-LABEL: scoped_alloca: 58; LA32: # %bb.0: 59; LA32-NEXT: addi.w $sp, $sp, -16 60; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill 61; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill 62; LA32-NEXT: st.w $s0, $sp, 4 # 4-byte Folded Spill 63; LA32-NEXT: addi.w $fp, $sp, 16 64; LA32-NEXT: move $s0, $sp 65; LA32-NEXT: addi.w $a0, $a0, 15 66; LA32-NEXT: bstrins.w $a0, $zero, 3, 0 67; LA32-NEXT: sub.w $a0, $sp, $a0 68; LA32-NEXT: move $sp, $a0 69; LA32-NEXT: bl %plt(notdead) 70; LA32-NEXT: move $sp, $s0 71; LA32-NEXT: addi.w $sp, $fp, -16 72; LA32-NEXT: ld.w $s0, $sp, 4 # 4-byte Folded Reload 73; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload 74; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload 75; LA32-NEXT: addi.w $sp, $sp, 16 76; LA32-NEXT: ret 77; 78; LA64-LABEL: scoped_alloca: 79; LA64: # %bb.0: 80; LA64-NEXT: addi.d $sp, $sp, -32 81; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill 82; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill 83; LA64-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill 84; LA64-NEXT: addi.d $fp, $sp, 32 85; LA64-NEXT: move $s0, $sp 86; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 87; LA64-NEXT: addi.d $a0, $a0, 15 88; LA64-NEXT: bstrpick.d $a0, $a0, 32, 4 89; LA64-NEXT: slli.d $a0, $a0, 4 90; LA64-NEXT: sub.d $a0, $sp, $a0 91; LA64-NEXT: move $sp, $a0 92; LA64-NEXT: bl %plt(notdead) 93; LA64-NEXT: move $sp, $s0 94; LA64-NEXT: addi.d $sp, $fp, -32 95; LA64-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload 96; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload 97; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload 98; LA64-NEXT: addi.d $sp, $sp, 32 99; LA64-NEXT: ret 100 %sp = call ptr @llvm.stacksave() 101 %addr = alloca i8, i32 %n 102 call void @notdead(ptr %addr) 103 call void @llvm.stackrestore(ptr %sp) 104 ret void 105} 106 107declare void @func(ptr, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) 108 109;; Check that outgoing arguments passed on the stack do not corrupt a 110;; variable-sized stack object. 111define void @alloca_callframe(i32 %n) nounwind { 112; LA32-LABEL: alloca_callframe: 113; LA32: # %bb.0: 114; LA32-NEXT: addi.w $sp, $sp, -16 115; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill 116; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill 117; LA32-NEXT: addi.w $fp, $sp, 16 118; LA32-NEXT: addi.w $a0, $a0, 15 119; LA32-NEXT: bstrins.w $a0, $zero, 3, 0 120; LA32-NEXT: sub.w $a0, $sp, $a0 121; LA32-NEXT: move $sp, $a0 122; LA32-NEXT: addi.w $sp, $sp, -16 123; LA32-NEXT: ori $a1, $zero, 12 124; LA32-NEXT: st.w $a1, $sp, 12 125; LA32-NEXT: ori $a1, $zero, 11 126; LA32-NEXT: st.w $a1, $sp, 8 127; LA32-NEXT: ori $a1, $zero, 10 128; LA32-NEXT: st.w $a1, $sp, 4 129; LA32-NEXT: ori $t0, $zero, 9 130; LA32-NEXT: ori $a1, $zero, 2 131; LA32-NEXT: ori $a2, $zero, 3 132; LA32-NEXT: ori $a3, $zero, 4 133; LA32-NEXT: ori $a4, $zero, 5 134; LA32-NEXT: ori $a5, $zero, 6 135; LA32-NEXT: ori $a6, $zero, 7 136; LA32-NEXT: ori $a7, $zero, 8 137; LA32-NEXT: st.w $t0, $sp, 0 138; LA32-NEXT: bl %plt(func) 139; LA32-NEXT: addi.w $sp, $sp, 16 140; LA32-NEXT: addi.w $sp, $fp, -16 141; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload 142; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload 143; LA32-NEXT: addi.w $sp, $sp, 16 144; LA32-NEXT: ret 145; 146; LA64-LABEL: alloca_callframe: 147; LA64: # %bb.0: 148; LA64-NEXT: addi.d $sp, $sp, -16 149; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill 150; LA64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill 151; LA64-NEXT: addi.d $fp, $sp, 16 152; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 153; LA64-NEXT: addi.d $a0, $a0, 15 154; LA64-NEXT: bstrpick.d $a0, $a0, 32, 4 155; LA64-NEXT: slli.d $a0, $a0, 4 156; LA64-NEXT: sub.d $a0, $sp, $a0 157; LA64-NEXT: move $sp, $a0 158; LA64-NEXT: addi.d $sp, $sp, -32 159; LA64-NEXT: ori $a1, $zero, 12 160; LA64-NEXT: st.d $a1, $sp, 24 161; LA64-NEXT: ori $a1, $zero, 11 162; LA64-NEXT: st.d $a1, $sp, 16 163; LA64-NEXT: ori $a1, $zero, 10 164; LA64-NEXT: st.d $a1, $sp, 8 165; LA64-NEXT: ori $t0, $zero, 9 166; LA64-NEXT: ori $a1, $zero, 2 167; LA64-NEXT: ori $a2, $zero, 3 168; LA64-NEXT: ori $a3, $zero, 4 169; LA64-NEXT: ori $a4, $zero, 5 170; LA64-NEXT: ori $a5, $zero, 6 171; LA64-NEXT: ori $a6, $zero, 7 172; LA64-NEXT: ori $a7, $zero, 8 173; LA64-NEXT: st.d $t0, $sp, 0 174; LA64-NEXT: bl %plt(func) 175; LA64-NEXT: addi.d $sp, $sp, 32 176; LA64-NEXT: addi.d $sp, $fp, -16 177; LA64-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload 178; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload 179; LA64-NEXT: addi.d $sp, $sp, 16 180; LA64-NEXT: ret 181 %1 = alloca i8, i32 %n 182 call void @func(ptr %1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, 183 i32 9, i32 10, i32 11, i32 12) 184 ret void 185} 186