xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/tail-call-attrs.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-apple-darwin -o - %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; Simple case: completely identical returns, even with extensions, shouldn't be
4*9880d681SAndroid Build Coastguard Worker; a barrier to tail calls.
5*9880d681SAndroid Build Coastguard Workerdeclare zeroext i1 @give_bool()
6*9880d681SAndroid Build Coastguard Workerdefine zeroext i1 @test_bool() {
7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_bool:
8*9880d681SAndroid Build Coastguard Worker; CHECK: jmp
9*9880d681SAndroid Build Coastguard Worker  %call = tail call zeroext i1 @give_bool()
10*9880d681SAndroid Build Coastguard Worker  ret i1 %call
11*9880d681SAndroid Build Coastguard Worker}
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker; Here, there's more zero extension to be done between the call and the return,
14*9880d681SAndroid Build Coastguard Worker; so a tail call is impossible (well, according to current Clang practice
15*9880d681SAndroid Build Coastguard Worker; anyway. The AMD64 ABI isn't crystal clear on the matter).
16*9880d681SAndroid Build Coastguard Worker; FIXME: The high 24 bits returned from test_i32 are undefined; do tail call!
17*9880d681SAndroid Build Coastguard Workerdeclare zeroext i32 @give_i32()
18*9880d681SAndroid Build Coastguard Workerdefine zeroext i8 @test_i32() {
19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_i32:
20*9880d681SAndroid Build Coastguard Worker; CHECK: callq _give_i32
21*9880d681SAndroid Build Coastguard Worker; CHECK: ret
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker  %call = tail call zeroext i32 @give_i32()
24*9880d681SAndroid Build Coastguard Worker  %val = trunc i32 %call to i8
25*9880d681SAndroid Build Coastguard Worker  ret i8 %val
26*9880d681SAndroid Build Coastguard Worker}
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker; Here, one function is zeroext and the other is signext. To the extent that
29*9880d681SAndroid Build Coastguard Worker; these both mean something they are incompatible so no tail call is possible.
30*9880d681SAndroid Build Coastguard Worker; FIXME: The high 16 bits returned are undefined; do tail call!
31*9880d681SAndroid Build Coastguard Workerdeclare zeroext i16 @give_unsigned_i16()
32*9880d681SAndroid Build Coastguard Workerdefine signext i16 @test_incompatible_i16() {
33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_incompatible_i16:
34*9880d681SAndroid Build Coastguard Worker; CHECK: callq _give_unsigned_i16
35*9880d681SAndroid Build Coastguard Worker; CHECK: ret
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker  %call = tail call zeroext i16 @give_unsigned_i16()
38*9880d681SAndroid Build Coastguard Worker  ret i16 %call
39*9880d681SAndroid Build Coastguard Worker}
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Workerdeclare inreg i32 @give_i32_inreg()
42*9880d681SAndroid Build Coastguard Workerdefine i32 @test_inreg_to_normal() {
43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_inreg_to_normal:
44*9880d681SAndroid Build Coastguard Worker; CHECK: callq _give_i32_inreg
45*9880d681SAndroid Build Coastguard Worker; CHECK: ret
46*9880d681SAndroid Build Coastguard Worker  %val = tail call inreg i32 @give_i32_inreg()
47*9880d681SAndroid Build Coastguard Worker  ret i32 %val
48*9880d681SAndroid Build Coastguard Worker}
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Workerdefine inreg i32 @test_normal_to_inreg() {
51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_normal_to_inreg:
52*9880d681SAndroid Build Coastguard Worker; CHECK: callq _give_i32
53*9880d681SAndroid Build Coastguard Worker; CHECK: ret
54*9880d681SAndroid Build Coastguard Worker  %val = tail call i32 @give_i32()
55*9880d681SAndroid Build Coastguard Worker  ret i32 %val
56*9880d681SAndroid Build Coastguard Worker}
57