1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -stack-symbol-ordering=0 -tailcallopt -code-model=medium -mtriple=i686-linux-gnu -mcpu=pentium | FileCheck %s 3 4; Check the HiPE calling convention works (x86-32) 5 6define void @zap(i32 %a, i32 %b) nounwind { 7; CHECK-LABEL: zap: 8; CHECK: # %bb.0: # %entry 9; CHECK-NEXT: pushl %ebp 10; CHECK-NEXT: pushl %ebx 11; CHECK-NEXT: pushl %edi 12; CHECK-NEXT: pushl %esi 13; CHECK-NEXT: subl $20, %esp 14; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 15; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 16; CHECK-NEXT: movl $8, %ecx 17; CHECK-NEXT: calll addfour@PLT 18; CHECK-NEXT: movl %eax, {{[0-9]+}}(%esp) 19; CHECK-NEXT: movl $2, {{[0-9]+}}(%esp) 20; CHECK-NEXT: movl $1, {{[0-9]+}}(%esp) 21; CHECK-NEXT: calll foo@PLT 22; CHECK-NEXT: addl $20, %esp 23; CHECK-NEXT: popl %esi 24; CHECK-NEXT: popl %edi 25; CHECK-NEXT: popl %ebx 26; CHECK-NEXT: popl %ebp 27; CHECK-NEXT: retl 28entry: 29 %0 = call cc 11 {i32, i32, i32} @addfour(i32 undef, i32 undef, i32 %a, i32 %b, i32 8) 30 %res = extractvalue {i32, i32, i32} %0, 2 31 32 tail call void @foo(i32 undef, i32 undef, i32 1, i32 2, i32 %res) nounwind 33 ret void 34} 35 36define cc 11 {i32, i32, i32} @addfour(i32 %hp, i32 %p, i32 %x, i32 %y, i32 %z) nounwind { 37; CHECK-LABEL: addfour: 38; CHECK: # %bb.0: # %entry 39; CHECK-NEXT: addl %edx, %eax 40; CHECK-NEXT: addl %ecx, %eax 41; CHECK-NEXT: retl 42entry: 43 %0 = add i32 %x, %y 44 %1 = add i32 %0, %z 45 46 %res = insertvalue {i32, i32, i32} undef, i32 %1, 2 47 ret {i32, i32, i32} %res 48} 49 50define cc 11 void @foo(i32 %hp, i32 %p, i32 %arg0, i32 %arg1, i32 %arg2) nounwind { 51; CHECK-LABEL: foo: 52; CHECK: # %bb.0: # %entry 53; CHECK-NEXT: subl $20, %esp 54; CHECK-NEXT: movl %esi, {{[0-9]+}}(%esp) 55; CHECK-NEXT: movl %ebp, {{[0-9]+}}(%esp) 56; CHECK-NEXT: movl %eax, {{[0-9]+}}(%esp) 57; CHECK-NEXT: movl %edx, {{[0-9]+}}(%esp) 58; CHECK-NEXT: movl %ecx, (%esp) 59; CHECK-NEXT: addl $20, %esp 60; CHECK-NEXT: jmp bar@PLT # TAILCALL 61entry: 62 %hp_var = alloca i32 63 %p_var = alloca i32 64 %arg0_var = alloca i32 65 %arg1_var = alloca i32 66 %arg2_var = alloca i32 67 store i32 %hp, ptr %hp_var 68 store i32 %p, ptr %p_var 69 store i32 %arg0, ptr %arg0_var 70 store i32 %arg1, ptr %arg1_var 71 store i32 %arg2, ptr %arg2_var 72 ; These loads are loading the values from their previous stores and are optimized away. 73 %0 = load i32, ptr %hp_var 74 %1 = load i32, ptr %p_var 75 %2 = load i32, ptr %arg0_var 76 %3 = load i32, ptr %arg1_var 77 %4 = load i32, ptr %arg2_var 78 tail call cc 11 void @bar(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4) nounwind 79 ret void 80} 81 82define cc 11 void @baz() nounwind { 83; CHECK-LABEL: baz: 84; CHECK: # %bb.0: 85; CHECK-NEXT: movl $42, %eax 86; CHECK-NEXT: jmpl *clos # TAILCALL 87 %tmp_clos = load i32, ptr @clos 88 %tmp_clos2 = inttoptr i32 %tmp_clos to ptr 89 tail call cc 11 void %tmp_clos2(i32 undef, i32 undef, i32 42) nounwind 90 ret void 91} 92 93; Sanity-check the tail call sequence. Number of arguments was chosen as to 94; expose a bug where the tail call sequence clobbered the stack. 95define cc 11 { i32, i32, i32 } @tailcaller(i32 %hp, i32 %p) nounwind { 96; CHECK-LABEL: tailcaller: 97; CHECK: # %bb.0: 98; CHECK-NEXT: subl $8, %esp 99; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 100; CHECK-NEXT: movl %eax, {{[0-9]+}}(%esp) 101; CHECK-NEXT: movl $63, {{[0-9]+}}(%esp) 102; CHECK-NEXT: movl $15, %eax 103; CHECK-NEXT: movl $31, %edx 104; CHECK-NEXT: movl $47, %ecx 105; CHECK-NEXT: popl %edi 106; CHECK-NEXT: jmp tailcallee@PLT # TAILCALL 107 %ret = tail call cc11 { i32, i32, i32 } @tailcallee(i32 %hp, i32 %p, i32 15, 108 i32 31, i32 47, i32 63) nounwind 109 ret { i32, i32, i32 } %ret 110} 111 112!hipe.literals = !{ !0, !1, !2 } 113!0 = !{ !"P_NSP_LIMIT", i32 84 } 114!1 = !{ !"X86_LEAF_WORDS", i32 24 } 115!2 = !{ !"AMD64_LEAF_WORDS", i32 24 } 116@clos = external dso_local constant i32 117declare cc 11 void @bar(i32, i32, i32, i32, i32) 118declare cc 11 { i32, i32, i32 } @tailcallee(i32, i32, i32, i32, i32, i32) 119 120!llvm.module.flags = !{!3} 121!3 = !{i32 2, !"override-stack-alignment", i32 4} 122