1
+ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1
2
; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck %s
2
3
3
4
declare x86_regcallcc i32 @callee (i32 %a0 , i32 %b0 , i32 %c0 , i32 %d0 , i32 %e0 );
4
5
5
6
; In RegCall calling convention, ESI and EDI are callee saved registers.
6
7
; One might think that the caller could assume that ESI value is the same before
7
8
; and after calling the callee.
8
- ; However, RegCall also says that a register that was used for
9
+ ; However, RegCall also says that a register that was used for
9
10
; passing/returning argumnets, can be assumed to be modified by the callee.
10
11
; In other words, it is no longer a callee saved register.
11
12
; In this case we want to see that EDX/ECX values are saved and EDI/ESI are assumed
12
13
; to be modified by the callee.
13
14
; This is a hipe CC function that doesn't save any register for the caller.
14
15
; So we can be sure that there is no other reason to save EDX/ECX.
15
- ; The caller arguments are expected to be passed (in the following order)
16
+ ; The caller arguments are expected to be passed (in the following order)
16
17
; in registers: ESI, EBP, EAX, EDX and ECX.
17
18
define cc 11 i32 @caller (i32 %a0 , i32 %b0 , i32 %c0 , i32 %d0 , i32 %e0 ) nounwind {
19
+ ; CHECK-LABEL: caller:
20
+ ; CHECK: # %bb.0:
21
+ ; CHECK-NEXT: subl $12, %esp
22
+ ; CHECK-NEXT: movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
23
+ ; CHECK-NEXT: movl %edx, %ebx
24
+ ; CHECK-NEXT: movl %eax, %edx
25
+ ; CHECK-NEXT: movl %esi, %eax
26
+ ; CHECK-NEXT: movl %ebp, %ecx
27
+ ; CHECK-NEXT: movl %ebx, %edi
28
+ ; CHECK-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ebp # 4-byte Reload
29
+ ; CHECK-NEXT: movl %ebp, %esi
30
+ ; CHECK-NEXT: calll callee
31
+ ; CHECK-NEXT: leal (%eax,%ebx), %esi
32
+ ; CHECK-NEXT: addl %ebp, %esi
33
+ ; CHECK-NEXT: addl $12, %esp
34
+ ; CHECK-NEXT: retl
18
35
%b1 = call x86_regcallcc i32 @callee (i32 %a0 , i32 %b0 , i32 %c0 , i32 %d0 , i32 %e0 )
19
36
%b2 = add i32 %b1 , %d0
20
37
%b3 = add i32 %b2 , %e0
21
38
ret i32 %b3
22
39
}
23
- ; CHECK-LABEL: caller
24
- ; CHECK: subl $12, %esp
25
- ; CHECK-NEXT: movl %ecx, 8(%esp)
26
- ; CHECK-NEXT: movl %edx, %ebx
27
- ; CHECK-NEXT: movl %eax, %edx
28
- ; CHECK-NEXT: movl %esi, %eax
29
- ; CHECK-NEXT: movl %ebp, %ecx
30
- ; CHECK-NEXT: movl %ebx, %edi
31
- ; CHECK-NEXT: movl 8(%esp), %ebp
32
- ; CHECK-NEXT: movl %ebp, %esi
33
- ; CHECK-NEXT: calll callee
34
- ; CHECK-NEXT: leal (%eax,%ebx), %esi
35
- ; CHECK-NEXT: addl %ebp, %esi
36
- ; CHECK-NEXT: addl $12, %esp
37
- ; CHECK-NEXT: retl
38
-
39
40
!hipe.literals = !{ !0 , !1 , !2 }
40
41
!0 = !{ !"P_NSP_LIMIT" , i32 120 }
41
42
!1 = !{ !"X86_LEAF_WORDS" , i32 24 }
42
43
!2 = !{ !"AMD64_LEAF_WORDS" , i32 18 }
43
44
44
45
; Make sure that the callee doesn't save parameters that were passed as arguments.
45
- ; The caller arguments are expected to be passed (in the following order)
46
+ ; The caller arguments are expected to be passed (in the following order)
46
47
; in registers: EAX, ECX, EDX, EDI and ESI.
47
48
; The result will return in EAX, ECX and EDX.
48
49
define x86_regcallcc {i32 , i32 , i32 } @test_callee (i32 %a0 , i32 %b0 , i32 %c0 , i32 %d0 , i32 %e0 ) nounwind {
50
+ ; CHECK-LABEL: test_callee:
51
+ ; CHECK: # %bb.0:
52
+ ; CHECK-NEXT: leal (,%esi,8), %ecx
53
+ ; CHECK-NEXT: subl %esi, %ecx
54
+ ; CHECK-NEXT: movl $5, %eax
55
+ ; CHECK-NEXT: xorl %edx, %edx
56
+ ; CHECK-NEXT: divl %esi
57
+ ; CHECK-NEXT: movl %eax, %esi
58
+ ; CHECK-NEXT: leal (,%edi,8), %edx
59
+ ; CHECK-NEXT: subl %edi, %edx
60
+ ; CHECK-NEXT: movl %ecx, %eax
61
+ ; CHECK-NEXT: movl %esi, %ecx
62
+ ; CHECK-NEXT: retl
49
63
%b1 = mul i32 7 , %e0
50
64
%b2 = udiv i32 5 , %e0
51
65
%b3 = mul i32 7 , %d0
@@ -54,7 +68,3 @@ define x86_regcallcc {i32, i32, i32} @test_callee(i32 %a0, i32 %b0, i32 %c0, i32
54
68
%b6 = insertvalue {i32 , i32 , i32 } %b5 , i32 %b3 , 2
55
69
ret {i32 , i32 , i32 } %b6
56
70
}
57
- ; CHECK-LABEL: test_callee
58
- ; CHECK-NOT: pushl %esi
59
- ; CHECK-NOT: pushl %edi
60
- ; CHECK: retl
0 commit comments