1*9880d681SAndroid Build Coastguard Worker; RUN: llc -fast-isel -O0 -mcpu=generic -mtriple=i386-apple-darwin10 -relocation-model=pic < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -fast-isel -O0 -mcpu=generic -mtriple=i386-apple-darwin10 -relocation-model=pic < %s -fast-isel-verbose 2>&1 >/dev/null | FileCheck -check-prefix=STDERR -allow-empty %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; This should use flds to set the return value. 5*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test0: 6*9880d681SAndroid Build Coastguard Worker; CHECK: flds 7*9880d681SAndroid Build Coastguard Worker; CHECK: retl 8*9880d681SAndroid Build Coastguard Worker@G = external global float 9*9880d681SAndroid Build Coastguard Workerdefine float @test0() nounwind { 10*9880d681SAndroid Build Coastguard Worker %t = load float, float* @G 11*9880d681SAndroid Build Coastguard Worker ret float %t 12*9880d681SAndroid Build Coastguard Worker} 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker; This should pop 4 bytes on return. 15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test1: 16*9880d681SAndroid Build Coastguard Worker; CHECK: retl $4 17*9880d681SAndroid Build Coastguard Workerdefine void @test1({i32, i32, i32, i32}* sret %p) nounwind { 18*9880d681SAndroid Build Coastguard Worker store {i32, i32, i32, i32} zeroinitializer, {i32, i32, i32, i32}* %p 19*9880d681SAndroid Build Coastguard Worker ret void 20*9880d681SAndroid Build Coastguard Worker} 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker; This should pop 8 bytes on return. 23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: thiscallfun: 24*9880d681SAndroid Build Coastguard Worker; CHECK: retl $8 25*9880d681SAndroid Build Coastguard Workerdefine x86_thiscallcc i32 @thiscallfun(i32* %this, i32 %a, i32 %b) nounwind { 26*9880d681SAndroid Build Coastguard Worker; STDERR-NOT: FastISel missed terminator: ret i32 12345 27*9880d681SAndroid Build Coastguard Worker ret i32 12345 28*9880d681SAndroid Build Coastguard Worker} 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker; Here, the callee pop doesn't fit the 16 bit immediate -- see x86-big-ret.ll 31*9880d681SAndroid Build Coastguard Worker; This checks that -fast-isel doesn't miscompile this. 32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: thiscall_large: 33*9880d681SAndroid Build Coastguard Worker; CHECK: popl %ecx 34*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: addl $65536, %esp 35*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: pushl %ecx 36*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retl 37*9880d681SAndroid Build Coastguard Workerdefine x86_thiscallcc void @thiscall_large(i32* %this, [65533 x i8]* byval %b) nounwind { 38*9880d681SAndroid Build Coastguard Worker ret void 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker; This should pop 4 bytes on return. 42*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: stdcallfun: 43*9880d681SAndroid Build Coastguard Worker; CHECK: retl $4 44*9880d681SAndroid Build Coastguard Workerdefine x86_stdcallcc i32 @stdcallfun(i32 %a) nounwind { 45*9880d681SAndroid Build Coastguard Worker; STDERR-NOT: FastISel missed terminator: ret i32 54321 46*9880d681SAndroid Build Coastguard Worker ret i32 54321 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; Properly initialize the pic base. 50*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test2: 51*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: HHH 52*9880d681SAndroid Build Coastguard Worker; CHECK: call{{.*}}L5$pb 53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: L5$pb: 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: pop 55*9880d681SAndroid Build Coastguard Worker; CHECK: HHH 56*9880d681SAndroid Build Coastguard Worker; CHECK: retl 57*9880d681SAndroid Build Coastguard Worker@HHH = external global i32 58*9880d681SAndroid Build Coastguard Workerdefine i32 @test2() nounwind { 59*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* @HHH 60*9880d681SAndroid Build Coastguard Worker ret i32 %t 61*9880d681SAndroid Build Coastguard Worker} 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker; Check that we fast-isel sret, and handle the callee-pops behavior correctly. 64*9880d681SAndroid Build Coastguard Worker%struct.a = type { i64, i64, i64 } 65*9880d681SAndroid Build Coastguard Workerdefine void @test3() nounwind ssp { 66*9880d681SAndroid Build Coastguard Workerentry: 67*9880d681SAndroid Build Coastguard Worker %tmp = alloca %struct.a, align 8 68*9880d681SAndroid Build Coastguard Worker call void @test3sret(%struct.a* sret %tmp) 69*9880d681SAndroid Build Coastguard Worker ret void 70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3: 71*9880d681SAndroid Build Coastguard Worker; CHECK: subl $44 72*9880d681SAndroid Build Coastguard Worker; CHECK: leal 16(%esp) 73*9880d681SAndroid Build Coastguard Worker; CHECK: calll _test3sret 74*9880d681SAndroid Build Coastguard Worker; CHECK: addl $40 75*9880d681SAndroid Build Coastguard Worker} 76*9880d681SAndroid Build Coastguard Workerdeclare void @test3sret(%struct.a* sret) 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker; Check that fast-isel sret works with fastcc (and does not callee-pop) 79*9880d681SAndroid Build Coastguard Workerdefine void @test4() nounwind ssp { 80*9880d681SAndroid Build Coastguard Workerentry: 81*9880d681SAndroid Build Coastguard Worker %tmp = alloca %struct.a, align 8 82*9880d681SAndroid Build Coastguard Worker call fastcc void @test4fastccsret(%struct.a* sret %tmp) 83*9880d681SAndroid Build Coastguard Worker ret void 84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test4: 85*9880d681SAndroid Build Coastguard Worker; CHECK: subl $28 86*9880d681SAndroid Build Coastguard Worker; CHECK: leal (%esp), %ecx 87*9880d681SAndroid Build Coastguard Worker; CHECK: calll _test4fastccsret 88*9880d681SAndroid Build Coastguard Worker; CHECK: addl $28 89*9880d681SAndroid Build Coastguard Worker} 90*9880d681SAndroid Build Coastguard Workerdeclare fastcc void @test4fastccsret(%struct.a* sret) 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker; Check that fast-isel cleans up when it fails to lower a call instruction. 94*9880d681SAndroid Build Coastguard Workerdefine void @test5() { 95*9880d681SAndroid Build Coastguard Workerentry: 96*9880d681SAndroid Build Coastguard Worker %call = call i32 @test5dllimport(i32 42) 97*9880d681SAndroid Build Coastguard Worker ret void 98*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test5: 99*9880d681SAndroid Build Coastguard Worker; Local value area is still there: 100*9880d681SAndroid Build Coastguard Worker; CHECK: movl $42, {{%[a-z]+}} 101*9880d681SAndroid Build Coastguard Worker; Fast-ISel's arg push is not here: 102*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: movl $42, (%esp) 103*9880d681SAndroid Build Coastguard Worker; SDag-ISel's arg push: 104*9880d681SAndroid Build Coastguard Worker; CHECK: movl %esp, [[REGISTER:%[a-z]+]] 105*9880d681SAndroid Build Coastguard Worker; CHECK: movl $42, ([[REGISTER]]) 106*9880d681SAndroid Build Coastguard Worker; CHECK: movl L_test5dllimport$non_lazy_ptr-L8$pb(%eax), %eax 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker} 109*9880d681SAndroid Build Coastguard Workerdeclare dllimport i32 @test5dllimport(i32) 110