; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=LIN32 ; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=LIN64 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=WIN64 ; Check that we only fold the address computation (load) into a tail call ; when we're sure there is enough volatile registers available. @globl = global ptr null ; CHECK-LABEL: test0: define i32 @test0(ptr %a, ptr %b) { entry: %func = load ptr, ptr %a %call = tail call i32 %func() ret i32 %call ; Call address load gets folded into the tail call. ; LIN32: jmpl *(% ; LIN64: jmpq *(% ; WIN64: jmpq *(% } ; CHECK-LABEL: test1: define i32 @test1(ptr %a, ptr %b) { entry: %func = load ptr, ptr %a %call = tail call i32 %func(i32 inreg 1) ret i32 %call ; Call address load gets folded into the tail call. ; LIN32: jmpl *(% ; LIN64: jmpq *(% ; WIN64: jmpq *(% } ; CHECK-LABEL: test2: define i32 @test2(ptr %a, ptr %b) { entry: %func = load ptr, ptr %a %call = tail call i32 %func(i32 inreg 1, i32 inreg 2) ret i32 %call ; On 32-bit we're not sure there is enough register to fold the load. ; LIN32: jmpl *% ; LIN64: jmpq *(% ; WIN64: jmpq *(% } ; CHECK-LABEL: test2_globl: define i32 @test2_globl(ptr %a, ptr %b) { entry: %func = load ptr, ptr @globl %call = tail call i32 %func(i32 inreg 1, i32 inreg 2) ret i32 %call ; .. but if the load is from a global, we can fold it. ; LIN32: jmpl *globl ; LIN64: jmpq *(% ; WIN64: jmpq *globl(%rip) } ; CHECK-LABEL: test2_stack: define i32 @test2_stack(ptr %func, ptr %b) { entry: %call = tail call i32 %func(i32 inreg 1, i32 inreg 2) ret i32 %call ; and if the load is from the stack (on 32-bit, %func is passed on the stack): ; LIN32: jmpl *4(%esp) } define i32 @test6(ptr %a, ptr %b) { entry: %func = load ptr, ptr %a %call = tail call i32 %func(i32 inreg 1, i32 inreg 2, i32 inreg 3, i32 inreg 4, i32 inreg 5, i32 inreg 6) ret i32 %call ; LIN64: jmpq *(% ; I wasn't able to pass more than 4 arguments in registers on Win64. ; WIN64: callq *( }