Home | History | Annotate | Download | only in Inline
      1 ; RUN: opt < %s -inline -S | FileCheck %s
      2 ; RUN: opt < %s -passes='cgscc(inline,function(instcombine))' -S | FileCheck %s
      3 
      4 declare void @ext_method(i8*, i32)
      5 declare signext i16 @vararg_fn(...) #0
      6 declare "cc 9" void @vararg_fn_cc9(i8* %p, ...)
      7 
      8 define linkonce_odr void @thunk(i8* %this, ...) {
      9   %this_adj = getelementptr i8, i8* %this, i32 4
     10   musttail call void (i8*, ...) bitcast (void (i8*, i32)* @ext_method to void (i8*, ...)*)(i8* nonnull %this_adj, ...)
     11   ret void
     12 }
     13 
     14 define void @thunk_caller(i8* %p) {
     15   call void (i8*, ...) @thunk(i8* %p, i32 42)
     16   ret void
     17 }
     18 ; CHECK-LABEL: define void @thunk_caller(i8* %p)
     19 ; CHECK: call void (i8*, ...) bitcast (void (i8*, i32)* @ext_method to void (i8*, ...)*)(i8* nonnull %this_adj.i, i32 42)
     20 
     21 define signext i16 @test_callee_2(...) {
     22   %res = musttail call signext i16 (...) @vararg_fn(...) #0
     23   ret i16 %res
     24 }
     25 
     26 define void @test_caller_2(i8* %p, i8* %q, i16 %r) {
     27   call signext i16 (...) @test_callee_2(i8* %p, i8* byval %q, i16 signext %r)
     28   ret void
     29 }
     30 ; CHECK-LABEL: define void @test_caller_2
     31 ; CHECK: call signext i16 (...) @vararg_fn(i8* %p, i8* byval %q, i16 signext %r) [[FN_ATTRS:#[0-9]+]]
     32 
     33 define void @test_callee_3(i8* %p, ...) {
     34   call signext i16 (...) @vararg_fn()
     35   ret void
     36 }
     37 
     38 define void @test_caller_3(i8* %p, i8* %q) {
     39   call void (i8*, ...) @test_callee_3(i8* nonnull %p, i8* %q)
     40   ret void
     41 }
     42 ; CHECK-LABEL: define void @test_caller_3
     43 ; CHECK: call signext i16 (...) @vararg_fn()
     44 
     45 define void @test_preserve_cc(i8* %p, ...) {
     46   musttail call "cc 9" void (i8*, ...) @vararg_fn_cc9(i8* %p, ...)
     47   ret void
     48 }
     49 
     50 define void @test_caller_preserve_cc(i8* %p, i8* %q) {
     51   call void (i8*, ...) @test_preserve_cc(i8* %p, i8* %q)
     52   ret void
     53 }
     54 ; CHECK-LABEL: define void @test_caller_preserve_cc
     55 ; CHECK: call "cc 9" void (i8*, ...) @vararg_fn_cc9(i8* %p, i8* %q)
     56 
     57 define internal i32 @varg_accessed(...) {
     58 entry:
     59   %vargs = alloca i8*, align 8
     60   %vargs.ptr = bitcast i8** %vargs to i8*
     61   call void @llvm.va_start(i8* %vargs.ptr)
     62   %va1 = va_arg i8** %vargs, i32
     63   call void @llvm.va_end(i8* %vargs.ptr)
     64   ret i32 %va1
     65 }
     66 
     67 define internal i32 @varg_accessed_alwaysinline(...) alwaysinline {
     68 entry:
     69   %vargs = alloca i8*, align 8
     70   %vargs.ptr = bitcast i8** %vargs to i8*
     71   call void @llvm.va_start(i8* %vargs.ptr)
     72   %va1 = va_arg i8** %vargs, i32
     73   call void @llvm.va_end(i8* %vargs.ptr)
     74   ret i32 %va1
     75 }
     76 
     77 define i32 @call_vargs() {
     78   %res1 = call i32 (...) @varg_accessed(i32 10)
     79   %res2 = call i32 (...) @varg_accessed_alwaysinline(i32 15)
     80   %res = add i32 %res1, %res2
     81   ret i32 %res
     82 }
     83 ; CHECK-LABEL: @call_vargs
     84 ; CHECK: %res1 = call i32 (...) @varg_accessed(i32 10)
     85 ; CHECK-NEXT: %res2 = call i32 (...) @varg_accessed_alwaysinline(i32 15)
     86 
     87 declare void @llvm.va_start(i8*)
     88 declare void @llvm.va_end(i8*)
     89 
     90 ; CHECK: attributes [[FN_ATTRS]] = { "foo"="bar" }
     91 attributes #0 = { "foo"="bar" }
     92