Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt -instcombine -S < %s | FileCheck %s
      2 
      3 declare void @llvm.init.trampoline(i8*, i8*, i8*)
      4 declare i8* @llvm.adjust.trampoline(i8*)
      5 declare i32 @f(i8 * nest, i32)
      6 
      7 ; Most common case
      8 define i32 @test0(i32 %n) {
      9   %alloca = alloca [10 x i8], align 16
     10   %gep = getelementptr [10 x i8], [10 x i8]* %alloca, i32 0, i32 0
     11   call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*),
     12                                   i8* null)
     13   %tramp = call i8* @llvm.adjust.trampoline(i8* %gep)
     14   %function = bitcast i8* %tramp to i32(i32)*
     15   %ret = call i32 %function(i32 %n)
     16   ret i32 %ret
     17 
     18 ; CHECK: define i32 @test0(i32 %n) {
     19 ; CHECK: %ret = call i32 @f(i8* nest null, i32 %n)
     20 }
     21 
     22 define i32 @test1(i32 %n, i8* %trampmem) {
     23   call void @llvm.init.trampoline(i8* %trampmem,
     24                                   i8* bitcast (i32 (i8*, i32)* @f to i8*),
     25                                   i8* null)
     26   %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem)
     27   %function = bitcast i8* %tramp to i32(i32)*
     28   %ret = call i32 %function(i32 %n)
     29   ret i32 %ret
     30 ; CHECK: define i32 @test1(i32 %n, i8* %trampmem) {
     31 ; CHECK: %ret = call i32 @f(i8* nest null, i32 %n)
     32 }
     33 
     34 define i32 @test2(i32 %n, i8* %trampmem) {
     35   %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem)
     36   %functiona = bitcast i8* %tramp to i32(i32)*
     37   %ret = call i32 %functiona(i32 %n)
     38   ret i32 %ret
     39 ; CHECK: define i32 @test2(i32 %n, i8* %trampmem) {
     40 ; CHECK: %ret = call i32 %functiona(i32 %n)
     41 }
     42 
     43 define i32 @test3(i32 %n, i8* %trampmem) {
     44   call void @llvm.init.trampoline(i8* %trampmem,
     45                                   i8* bitcast (i32 (i8*, i32)* @f to i8*),
     46                                   i8* null)
     47 
     48 ; CHECK: define i32 @test3(i32 %n, i8* %trampmem) {
     49 ; CHECK: %ret0 = call i32 @f(i8* nest null, i32 %n)
     50   %tramp0 = call i8* @llvm.adjust.trampoline(i8* %trampmem)
     51   %function0 = bitcast i8* %tramp0 to i32(i32)*
     52   %ret0 = call i32 %function0(i32 %n)
     53 
     54   ;; Not optimized since previous call could be writing.
     55   %tramp1 = call i8* @llvm.adjust.trampoline(i8* %trampmem)
     56   %function1 = bitcast i8* %tramp1 to i32(i32)*
     57   %ret1 = call i32 %function1(i32 %n)
     58 ; CHECK: %ret1 = call i32 %function1(i32 %n)
     59 
     60   ret i32 %ret1
     61 }
     62 
     63 define i32 @test4(i32 %n) {
     64   %alloca = alloca [10 x i8], align 16
     65   %gep = getelementptr [10 x i8], [10 x i8]* %alloca, i32 0, i32 0
     66   call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*),
     67                                   i8* null)
     68 
     69   %tramp0 = call i8* @llvm.adjust.trampoline(i8* %gep)
     70   %function0 = bitcast i8* %tramp0 to i32(i32)*
     71   %ret0 = call i32 %function0(i32 %n)
     72 
     73   %tramp1 = call i8* @llvm.adjust.trampoline(i8* %gep)
     74   %function1 = bitcast i8* %tramp0 to i32(i32)*
     75   %ret1 = call i32 %function1(i32 %n)
     76 
     77   %tramp2 = call i8* @llvm.adjust.trampoline(i8* %gep)
     78   %function2 = bitcast i8* %tramp2 to i32(i32)*
     79   %ret2 = call i32 %function2(i32 %n)
     80 
     81   ret i32 %ret2
     82 
     83 ; CHECK: define i32 @test4(i32 %n) {
     84 ; CHECK: %ret0 = call i32 @f(i8* nest null, i32 %n)
     85 ; CHECK: %ret1 = call i32 @f(i8* nest null, i32 %n)
     86 ; CHECK: %ret2 = call i32 @f(i8* nest null, i32 %n)
     87 }
     88