brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · e9955ae Raw
309 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=sparc -verify-machineinstrs | FileCheck %s --check-prefix=V83; RUN: llc < %s -mtriple=sparcv9 -verify-machineinstrs | FileCheck %s --check-prefix=V94 5define i32 @simple_leaf(i32 %i) #0 {6; V8-LABEL: simple_leaf:7; V8:       ! %bb.0: ! %entry8; V8-NEXT:    mov %o7, %g19; V8-NEXT:    call foo10; V8-NEXT:    mov %g1, %o711;12; V9-LABEL: simple_leaf:13; V9:       ! %bb.0: ! %entry14; V9-NEXT:    mov %o7, %g115; V9-NEXT:    call foo16; V9-NEXT:    mov %g1, %o717entry:18  %call = tail call i32 @foo(i32 %i)19  ret i32 %call20}21 22define i32 @simple_standard(i32 %i) #1 {23; V8-LABEL: simple_standard:24; V8:       ! %bb.0: ! %entry25; V8-NEXT:    save %sp, -96, %sp26; V8-NEXT:    call foo27; V8-NEXT:    restore28;29; V9-LABEL: simple_standard:30; V9:       ! %bb.0: ! %entry31; V9-NEXT:    save %sp, -128, %sp32; V9-NEXT:    call foo33; V9-NEXT:    restore34entry:35  %call = tail call i32 @foo(i32 %i)36  ret i32 %call37}38 39define i32 @extra_arg_leaf(i32 %i) #0 {40; V8-LABEL: extra_arg_leaf:41; V8:       ! %bb.0: ! %entry42; V8-NEXT:    mov 12, %o143; V8-NEXT:    mov %o7, %g144; V8-NEXT:    call foo245; V8-NEXT:    mov %g1, %o746;47; V9-LABEL: extra_arg_leaf:48; V9:       ! %bb.0: ! %entry49; V9-NEXT:    mov 12, %o150; V9-NEXT:    mov %o7, %g151; V9-NEXT:    call foo252; V9-NEXT:    mov %g1, %o753entry:54  %call = tail call i32 @foo2(i32 %i, i32 12)55  ret i32 %call56}57 58define i32 @extra_arg_standard(i32 %i) #1 {59; V8-LABEL: extra_arg_standard:60; V8:       ! %bb.0: ! %entry61; V8-NEXT:    save %sp, -96, %sp62; V8-NEXT:    call foo263; V8-NEXT:    restore %g0, 12, %o164;65; V9-LABEL: extra_arg_standard:66; V9:       ! %bb.0: ! %entry67; V9-NEXT:    save %sp, -128, %sp68; V9-NEXT:    call foo269; V9-NEXT:    restore %g0, 12, %o170entry:71  %call = tail call i32 @foo2(i32 %i, i32 12)72  ret i32 %call73}74 75; Perform tail call optimization for external symbol.76 77define void @caller_extern(ptr %src) optsize #0 {78; V8-LABEL: caller_extern:79; V8:       ! %bb.0: ! %entry80; V8-NEXT:    sethi %hi(dest), %o181; V8-NEXT:    add %o1, %lo(dest), %o182; V8-NEXT:    mov 7, %o283; V8-NEXT:    mov %o0, %o384; V8-NEXT:    mov %o1, %o085; V8-NEXT:    mov %o3, %o186; V8-NEXT:    mov %o7, %g187; V8-NEXT:    call memcpy88; V8-NEXT:    mov %g1, %o789;90; V9-LABEL: caller_extern:91; V9:       ! %bb.0: ! %entry92; V9-NEXT:    sethi %h44(dest), %o193; V9-NEXT:    add %o1, %m44(dest), %o194; V9-NEXT:    sllx %o1, 12, %o195; V9-NEXT:    add %o1, %l44(dest), %o196; V9-NEXT:    mov 7, %o297; V9-NEXT:    mov %o0, %o398; V9-NEXT:    mov %o1, %o099; V9-NEXT:    mov %o3, %o1100; V9-NEXT:    mov %o7, %g1101; V9-NEXT:    call memcpy102; V9-NEXT:    mov %g1, %o7103entry:104  tail call void @llvm.memcpy.p0.p0.i32(105    ptr @dest,106    ptr %src, i32 7, i1 false)107  ret void108}109 110; Perform tail call optimization for function pointer.111 112define i32 @func_ptr_test(ptr nocapture %func_ptr) #0 {113; V8-LABEL: func_ptr_test:114; V8:       ! %bb.0: ! %entry115; V8-NEXT:    jmp %o0116; V8-NEXT:    nop117;118; V9-LABEL: func_ptr_test:119; V9:       ! %bb.0: ! %entry120; V9-NEXT:    jmp %o0121; V9-NEXT:    nop122entry:123  %call = tail call i32 %func_ptr() #1124  ret i32 %call125}126 127define i32 @func_ptr_test2(ptr nocapture %func_ptr,128; V8-LABEL: func_ptr_test2:129; V8:       ! %bb.0: ! %entry130; V8-NEXT:    save %sp, -96, %sp131; V8-NEXT:    mov 10, %i3132; V8-NEXT:    mov %i0, %i4133; V8-NEXT:    mov %i1, %i0134; V8-NEXT:    jmp %i4135; V8-NEXT:    restore %g0, %i3, %o1136;137; V9-LABEL: func_ptr_test2:138; V9:       ! %bb.0: ! %entry139; V9-NEXT:    save %sp, -128, %sp140; V9-NEXT:    mov 10, %i3141; V9-NEXT:    mov %i0, %i4142; V9-NEXT:    mov %i1, %i0143; V9-NEXT:    jmp %i4144; V9-NEXT:    restore %g0, %i3, %o1145                           i32 %r, i32 %q) #1 {146entry:147  %call = tail call i32 %func_ptr(i32 %r, i32 10, i32 %q) #1148  ret i32 %call149}150 151 152; Do not tail call optimize if stack is used to pass parameters.153 154define i32 @caller_args() #0 {155; V8-LABEL: caller_args:156; V8:       ! %bb.0: ! %entry157; V8-NEXT:    save %sp, -104, %sp158; V8-NEXT:    mov 6, %i0159; V8-NEXT:    mov 1, %o1160; V8-NEXT:    mov 2, %o2161; V8-NEXT:    mov 3, %o3162; V8-NEXT:    mov 4, %o4163; V8-NEXT:    mov 5, %o5164; V8-NEXT:    st %i0, [%sp+92]165; V8-NEXT:    call foo7166; V8-NEXT:    mov %g0, %o0167; V8-NEXT:    ret168; V8-NEXT:    restore %g0, %o0, %o0169;170; V9-LABEL: caller_args:171; V9:       ! %bb.0: ! %entry172; V9-NEXT:    save %sp, -192, %sp173; V9-NEXT:    mov 6, %i0174; V9-NEXT:    mov 1, %o1175; V9-NEXT:    mov 2, %o2176; V9-NEXT:    mov 3, %o3177; V9-NEXT:    mov 4, %o4178; V9-NEXT:    mov 5, %o5179; V9-NEXT:    stx %i0, [%sp+2223]180; V9-NEXT:    call foo7181; V9-NEXT:    mov %g0, %o0182; V9-NEXT:    ret183; V9-NEXT:    restore %g0, %o0, %o0184entry:185  %r = tail call i32 @foo7(i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6)186  ret i32 %r187}188 189; Byval parameters hand the function a pointer directly into the stack area190; we want to reuse during a tail call. Do not tail call optimize functions with191; byval parameters.192 193define i32 @caller_byval() #0 {194; V8-LABEL: caller_byval:195; V8:       ! %bb.0: ! %entry196; V8-NEXT:    save %sp, -104, %sp197; V8-NEXT:    ld [%fp+-4], %i0198; V8-NEXT:    st %i0, [%fp+-8]199; V8-NEXT:    call callee_byval200; V8-NEXT:    add %fp, -8, %o0201; V8-NEXT:    ret202; V8-NEXT:    restore %g0, %o0, %o0203;204; V9-LABEL: caller_byval:205; V9:       ! %bb.0: ! %entry206; V9-NEXT:    save %sp, -192, %sp207; V9-NEXT:    call callee_byval208; V9-NEXT:    add %fp, 2039, %o0209; V9-NEXT:    ret210; V9-NEXT:    restore %g0, %o0, %o0211entry:212  %a = alloca ptr213  %r = tail call i32 @callee_byval(ptr byval(ptr) %a)214  ret i32 %r215}216 217; Perform tail call optimization for sret function.218 219define void @sret_test(ptr noalias sret(%struct.a) %agg.result) #0 {220; V8-LABEL: sret_test:221; V8:       ! %bb.0: ! %entry222; V8-NEXT:    mov %o7, %g1223; V8-NEXT:    call sret_func224; V8-NEXT:    mov %g1, %o7225;226; V9-LABEL: sret_test:227; V9:       ! %bb.0: ! %entry228; V9-NEXT:    mov %o7, %g1229; V9-NEXT:    call sret_func230; V9-NEXT:    mov %g1, %o7231entry:232  tail call void @sret_func(ptr sret(%struct.a) %agg.result)233  ret void234}235 236; Do not tail call if either caller or callee returns237; a struct and the other does not. Returning a large238; struct will generate a memcpy as the tail function.239 240define void @ret_large_struct(ptr noalias sret(%struct.big) %agg.result) #0 {241; V8-LABEL: ret_large_struct:242; V8:       ! %bb.0: ! %entry243; V8-NEXT:    save %sp, -96, %sp244; V8-NEXT:    ld [%fp+64], %i0245; V8-NEXT:    sethi %hi(bigstruct), %i1246; V8-NEXT:    add %i1, %lo(bigstruct), %o1247; V8-NEXT:    mov 400, %o2248; V8-NEXT:    call memcpy249; V8-NEXT:    mov %i0, %o0250; V8-NEXT:    jmp %i7+12251; V8-NEXT:    restore252;253; V9-LABEL: ret_large_struct:254; V9:       ! %bb.0: ! %entry255; V9-NEXT:    save %sp, -176, %sp256; V9-NEXT:    mov %i0, %o0257; V9-NEXT:    sethi %h44(bigstruct), %i0258; V9-NEXT:    add %i0, %m44(bigstruct), %i0259; V9-NEXT:    sllx %i0, 12, %i0260; V9-NEXT:    add %i0, %l44(bigstruct), %o1261; V9-NEXT:    call memcpy262; V9-NEXT:    mov 400, %o2263; V9-NEXT:    ret264; V9-NEXT:    restore265entry:266  %0 = bitcast ptr %agg.result to ptr267  tail call void @llvm.memcpy.p0.p0.i32(ptr align 4 %0, ptr align 4 @bigstruct, i32 400, i1 false)268  ret void269}270 271; Test register + immediate pattern.272 273define void @addri_test(i32 %ptr) #0 {274; V8-LABEL: addri_test:275; V8:       ! %bb.0: ! %entry276; V8-NEXT:    jmp %o0+4277; V8-NEXT:    nop278;279; V9-LABEL: addri_test:280; V9:       ! %bb.0: ! %entry281; V9-NEXT:    add %o0, 4, %o0282; V9-NEXT:    srl %o0, 0, %o0283; V9-NEXT:    jmp %o0284; V9-NEXT:    nop285entry:286  %add = add nsw i32 %ptr, 4287  %0 = inttoptr i32 %add to ptr288  tail call void %0() #1289  ret void290}291 292%struct.a = type { i32, i32 }293@dest = global [2 x i8] zeroinitializer294 295%struct.big = type { [100 x i32] }296@bigstruct = global %struct.big zeroinitializer297 298declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1)299declare void @sret_func(ptr sret(%struct.a))300declare i32 @callee_byval(ptr byval(ptr) %a)301declare i32 @foo(i32)302declare i32 @foo2(i32, i32)303declare i32 @foo7(i32, i32, i32, i32, i32, i32, i32)304 305attributes #0 = { nounwind "disable-tail-calls"="false"306                  "frame-pointer"="none" }307attributes #1 = { nounwind "disable-tail-calls"="false"308                  "frame-pointer"="all" }309