xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/x32-function_pointer-3.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-linux-gnux32 | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-linux-gnux32 -fast-isel | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; Test calling function pointer passed in struct
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker;    The function argument `h' in
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker;    struct foo {
9*9880d681SAndroid Build Coastguard Worker;      void (*f) (void);
10*9880d681SAndroid Build Coastguard Worker;      int i;
11*9880d681SAndroid Build Coastguard Worker;    };
12*9880d681SAndroid Build Coastguard Worker;    void
13*9880d681SAndroid Build Coastguard Worker;    bar (struct foo h)
14*9880d681SAndroid Build Coastguard Worker;    {
15*9880d681SAndroid Build Coastguard Worker;      h.f ();
16*9880d681SAndroid Build Coastguard Worker;    }
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker;    is passed in the 64-bit %rdi register.  The `f' field is in the lower 32
19*9880d681SAndroid Build Coastguard Worker;    bits of %rdi register and the `i' field is in the upper 32 bits of %rdi
20*9880d681SAndroid Build Coastguard Worker;    register.  We need to zero-extend %edi to %rdi before branching via %rdi.
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Workerdefine void @bar(i64 %h.coerce) nounwind {
23*9880d681SAndroid Build Coastguard Workerentry:
24*9880d681SAndroid Build Coastguard Worker  %h.sroa.0.0.extract.trunc = trunc i64 %h.coerce to i32
25*9880d681SAndroid Build Coastguard Worker  %0 = inttoptr i32 %h.sroa.0.0.extract.trunc to void ()*
26*9880d681SAndroid Build Coastguard Worker; CHECK: movl	%edi, %e[[REG:.*]]
27*9880d681SAndroid Build Coastguard Worker  tail call void %0() nounwind
28*9880d681SAndroid Build Coastguard Worker; CHECK: jmpq	*%r[[REG]]
29*9880d681SAndroid Build Coastguard Worker  ret void
30*9880d681SAndroid Build Coastguard Worker}
31