brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · 85db6a0 Raw
324 lines · plain
1; RUN: llc -mtriple=riscv32 < %s | FileCheck %s -check-prefix=RV32I2; RUN: llc -mtriple=riscv64 < %s | FileCheck %s -check-prefix=RV64I3; RUN: llc -mtriple=riscv32 -mattr=+save-restore < %s | FileCheck %s -check-prefix=RV32I-SR4; RUN: llc -mtriple=riscv64 -mattr=+save-restore < %s | FileCheck %s -check-prefix=RV64I-SR5; RUN: llc -mtriple=riscv32 -mattr=+f,+save-restore -target-abi=ilp32f < %s | FileCheck %s -check-prefix=RV32I-FP-SR6; RUN: llc -mtriple=riscv64 -mattr=+f,+d,+save-restore -target-abi=lp64d < %s | FileCheck %s -check-prefix=RV64I-FP-SR7 8; Check that the correct save/restore libcalls are generated.9 10@var0 = global [18 x i32] zeroinitializer11@var1 = global [24 x i32] zeroinitializer12@var2 = global [30 x i32] zeroinitializer13 14define void @callee_saved0() nounwind {15; RV32I-LABEL: callee_saved0:16; RV32I-NOT:     call t0, __riscv_save17; RV32I-NOT:     tail __riscv_restore18;19; RV64I-LABEL: callee_saved0:20; RV64I-NOT:     call t0, __riscv_save21; RV64I-NOT:     tail __riscv_restore22;23; RV32I-SR-LABEL: callee_saved0:24; RV32I-SR:         call t0, __riscv_save_425; RV32I-SR:         tail __riscv_restore_426;27; RV64I-SR-LABEL: callee_saved0:28; RV64I-SR:         call t0, __riscv_save_429; RV64I-SR:         tail __riscv_restore_430;31; RV32I-FP-SR-LABEL: callee_saved0:32; RV32I-FP-SR:         call t0, __riscv_save_433; RV32I-FP-SR:         tail __riscv_restore_434;35; RV64I-FP-SR-LABEL: callee_saved0:36; RV64I-FP-SR:         call t0, __riscv_save_437; RV64I-FP-SR:         tail __riscv_restore_438  %val = load [18 x i32], ptr @var039  store volatile [18 x i32] %val, ptr @var040  ret void41}42 43define void @callee_saved1() nounwind {44; RV32I-LABEL: callee_saved1:45; RV32I-NOT:     call t0, __riscv_save46; RV32I-NOT:     tail __riscv_restore47;48; RV64I-LABEL: callee_saved1:49; RV64I-NOT:     call t0, __riscv_save50; RV64I-NOT:     tail __riscv_restore51;52; RV32I-SR-LABEL: callee_saved1:53; RV32I-SR:         call t0, __riscv_save_1054; RV32I-SR:         tail __riscv_restore_1055;56; RV64I-SR-LABEL: callee_saved1:57; RV64I-SR:         call t0, __riscv_save_1058; RV64I-SR:         tail __riscv_restore_1059;60; RV32I-FP-SR-LABEL: callee_saved1:61; RV32I-FP-SR:         call t0, __riscv_save_1062; RV32I-FP-SR:         tail __riscv_restore_1063;64; RV64I-FP-SR-LABEL: callee_saved1:65; RV64I-FP-SR:         call t0, __riscv_save_1066; RV64I-FP-SR:         tail __riscv_restore_1067  %val = load [24 x i32], ptr @var168  store volatile [24 x i32] %val, ptr @var169  ret void70}71 72define void @callee_saved2() nounwind {73; RV32I-LABEL: callee_saved2:74; RV32I-NOT:     call t0, __riscv_save75; RV32I-NOT:     tail __riscv_restore76;77; RV64I-LABEL: callee_saved2:78; RV64I-NOT:     call t0, __riscv_save79; RV64I-NOT:     tail __riscv_restore80;81; RV32I-SR-LABEL: callee_saved2:82; RV32I-SR:         call t0, __riscv_save_1283; RV32I-SR:         tail __riscv_restore_1284;85; RV64I-SR-LABEL: callee_saved2:86; RV64I-SR:         call t0, __riscv_save_1287; RV64I-SR:         tail __riscv_restore_1288;89; RV32I-FP-SR-LABEL: callee_saved2:90; RV32I-FP-SR:         call t0, __riscv_save_1291; RV32I-FP-SR:         tail __riscv_restore_1292;93; RV64I-FP-SR-LABEL: callee_saved2:94; RV64I-FP-SR:         call t0, __riscv_save_1295; RV64I-FP-SR:         tail __riscv_restore_1296  %val = load [30 x i32], ptr @var297  store volatile [30 x i32] %val, ptr @var298  ret void99}100 101; Check that floating point callee saved registers are still manually saved and102; restored.103 104define void @callee_saved_fp() nounwind {105; RV32I-LABEL: callee_saved_fp:106; RV32I-NOT:     call t0, __riscv_save107; RV32I-NOT:     tail __riscv_restore108;109; RV64I-LABEL: callee_saved_fp:110; RV64I-NOT:     call t0, __riscv_save111; RV64I-NOT:     tail __riscv_restore112;113; RV32I-SR-LABEL: callee_saved_fp:114; RV32I-SR:         call t0, __riscv_save_7115; RV32I-SR:         tail __riscv_restore_7116;117; RV64I-SR-LABEL: callee_saved_fp:118; RV64I-SR:         call t0, __riscv_save_7119; RV64I-SR:         tail __riscv_restore_7120;121; RV32I-FP-SR-LABEL: callee_saved_fp:122; RV32I-FP-SR:         call t0, __riscv_save_7123; RV32I-FP-SR-NEXT:    addi sp, sp, -16124; RV32I-FP-SR-NEXT:    fsw fs0, 12(sp)125; RV32I-FP-SR:         flw fs0, 12(sp)126; RV32I-FP-SR-NEXT:    addi sp, sp, 16127; RV32I-FP-SR-NEXT:    tail __riscv_restore_7128;129; RV64I-FP-SR-LABEL: callee_saved_fp:130; RV64I-FP-SR:         call t0, __riscv_save_7131; RV64I-FP-SR-NEXT:    addi sp, sp, -16132; RV64I-FP-SR-NEXT:    fsd fs0, 8(sp)133; RV64I-FP-SR:         fld fs0, 8(sp)134; RV64I-FP-SR-NEXT:    addi sp, sp, 16135; RV64I-FP-SR-NEXT:    tail __riscv_restore_7136  call void asm sideeffect "", "~{f8},~{x9},~{x18},~{x19},~{x20},~{x21},~{x22}"()137  ret void138}139 140; Check that preserving tail calls is preferred over save/restore141 142declare i32 @tail_callee(i32 %i)143 144define i32 @tail_call(i32 %i) nounwind {145; RV32I-LABEL: tail_call:146; RV32I-NOT:     call t0, __riscv_save147; RV32I:         tail tail_callee148; RV32I-NOT:     tail __riscv_restore149;150; RV64I-LABEL: tail_call:151; RV64I-NOT:     call t0, __riscv_save152; RV64I:         tail tail_callee153; RV64I-NOT:     tail __riscv_restore154;155; RV32I-SR-LABEL: tail_call:156; RV32I-SR-NOT:     call t0, __riscv_save157; RV32I-SR:         tail tail_callee158; RV32I-SR-NOT:     tail __riscv_restore159;160; RV64I-SR-LABEL: tail_call:161; RV64I-SR-NOT:     call t0, __riscv_save162; RV64I-SR:         tail tail_callee163; RV64I-SR-NOT:     tail __riscv_restore164;165; RV32I-FP-SR-LABEL: tail_call:166; RV32I-FP-SR-NOT:     call t0, __riscv_save167; RV32I-FP-SR:         tail tail_callee168; RV32I-FP-SR-NOT:     tail __riscv_restore169;170; RV64I-FP-SR-LABEL: tail_call:171; RV64I-FP-SR-NOT:     call t0, __riscv_save172; RV64I-FP-SR:         tail tail_callee173; RV64I-FP-SR-NOT:     tail __riscv_restore174entry:175  %val = load [18 x i32], ptr @var0176  store volatile [18 x i32] %val, ptr @var0177  %r = tail call i32 @tail_callee(i32 %i)178  ret i32 %r179}180 181; Check that functions with varargs do not use save/restore code182 183define i32 @varargs(ptr %fmt, ...) nounwind {184; RV32I-LABEL: varargs:185; RV32I-NOT:     call t0, __riscv_save186; RV32I-NOT:     tail __riscv_restore187;188; RV64I-LABEL: varargs:189; RV64I-NOT:     call t0, __riscv_save190; RV64I-NOT:     tail __riscv_restore191;192; RV32I-SR-LABEL: varargs:193; RV32I-SR-NOT:     call t0, __riscv_save194; RV32I-SR-NOT:     tail __riscv_restore195;196; RV64I-SR-LABEL: varargs:197; RV64I-SR-NOT:     call t0, __riscv_save198; RV64I-SR-NOT:     tail __riscv_restore199;200; RV32I-FP-SR-LABEL: varargs:201; RV32I-FP-SR-NOT:     call t0, __riscv_save202; RV32I-FP-SR-NOT:     tail __riscv_restore203;204; RV64I-FP-SR-LABEL: varargs:205; RV64I-FP-SR-NOT:     call t0, __riscv_save206; RV64I-FP-SR-NOT:     tail __riscv_restore207  %va = alloca ptr, align 4208  call void @llvm.va_start(ptr %va)209  %argp.cur = load ptr, ptr %va, align 4210  %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4211  store ptr %argp.next, ptr %va, align 4212  %1 = load i32, ptr %argp.cur, align 4213  call void @llvm.va_end(ptr %va)214  ret i32 %1215}216 217define void @many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32) nounwind {218; RV32I-LABEL: many_args:219; RV32I-NOT:     call t0, __riscv_save220; RV32I-NOT:     tail __riscv_restore221;222; RV64I-LABEL: many_args:223; RV64I-NOT:     call t0, __riscv_save224; RV64I-NOT:     tail __riscv_restore225;226; RV32I-SR-LABEL: many_args:227; RV32I-SR:         call t0, __riscv_save_4228; RV32I-SR:         tail __riscv_restore_4229;230; RV64I-SR-LABEL: many_args:231; RV64I-SR:         call t0, __riscv_save_4232; RV64I-SR:         tail __riscv_restore_4233;234; RV32I-FP-SR-LABEL: many_args:235; RV32I-FP-SR:         call t0, __riscv_save_4236; RV32I-FP-SR:         tail __riscv_restore_4237;238; RV64I-FP-SR-LABEL: many_args:239; RV64I-FP-SR:         call t0, __riscv_save_4240; RV64I-FP-SR:         tail __riscv_restore_4241entry:242  %val = load [18 x i32], ptr @var0243  store volatile [18 x i32] %val, ptr @var0244  ret void245}246 247; Check that dynamic allocation calculations remain correct248 249declare void @notdead(ptr)250 251define void @alloca(i32 %n) nounwind {252; RV32I-LABEL: alloca:253; RV32I-NOT:     call t0, __riscv_save254; RV32I:         addi s0, sp, 16255; RV32I:         addi sp, s0, -16256; RV32I-NOT:     tail __riscv_restore257;258; RV64I-LABEL: alloca:259; RV64I-NOT:     call t0, __riscv_save260; RV64I:         addi s0, sp, 32261; RV64I:         addi sp, s0, -32262; RV64I-NOT:     tail __riscv_restore263;264; RV32I-SR-LABEL: alloca:265; RV32I-SR:         call t0, __riscv_save_2266; RV32I-SR:         addi s0, sp, 16267; RV32I-SR:         addi sp, s0, -16268; RV32I-SR:         tail __riscv_restore_2269;270; RV64I-SR-LABEL: alloca:271; RV64I-SR:         call t0, __riscv_save_2272; RV64I-SR:         addi s0, sp, 32273; RV64I-SR:         addi sp, s0, -32274; RV64I-SR:         tail __riscv_restore_2275;276; RV32I-FP-SR-LABEL: alloca:277; RV32I-FP-SR:         call t0, __riscv_save_2278; RV32I-FP-SR:         addi s0, sp, 16279; RV32I-FP-SR:         addi sp, s0, -16280; RV32I-FP-SR:         tail __riscv_restore_2281;282; RV64I-FP-SR-LABEL: alloca:283; RV64I-FP-SR:         call t0, __riscv_save_2284; RV64I-FP-SR:         addi s0, sp, 32285; RV64I-FP-SR:         addi sp, s0, -32286; RV64I-FP-SR:         tail __riscv_restore_2287  %sp = call ptr @llvm.stacksave()288  %addr = alloca i8, i32 %n289  call void @notdead(ptr %addr)290  call void @llvm.stackrestore(ptr %sp)291  ret void292}293 294; Check that functions with interrupt attribute do not use save/restore code295 296declare i32 @foo(...)297define void @interrupt() nounwind "interrupt"="supervisor" {298; RV32I-LABEL: interrupt:299; RV32I-NOT:     call t0, __riscv_save300; RV32I-NOT:     tail __riscv_restore301;302; RV64I-LABEL: interrupt:303; RV64I-NOT:     call t0, __riscv_save304; RV64I-NOT:     tail __riscv_restore305;306; RV32I-SR-LABEL: interrupt:307; RV32I-SR-NOT:     call t0, __riscv_save308; RV32I-SR-NOT:     tail __riscv_restore309;310; RV64I-SR-LABEL: interrupt:311; RV64I-SR-NOT:     call t0, __riscv_save312; RV64I-SR-NOT:     tail __riscv_restore313;314; RV32I-FP-SR-LABEL: interrupt:315; RV32I-FP-SR-NOT:     call t0, __riscv_save316; RV32I-FP-SR-NOT:     tail __riscv_restore317;318; RV64I-FP-SR-LABEL: interrupt:319; RV64I-FP-SR-NOT:     call t0, __riscv_save320; RV64I-FP-SR-NOT:     tail __riscv_restore321  %call = call i32 @foo()322  ret void323}324