xref: /llvm-project/llvm/test/CodeGen/X86/2013-10-14-FastISel-incorrect-vreg.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; RUN: llc -mtriple x86_64-apple-darwin -O0 < %s -o - | FileCheck %s
2;
3; During X86 fastisel, the address of indirect call was resolved
4; through bitcast, ptrtoint, and inttoptr instructions. This is valid
5; only if the related instructions are in that same basic block, otherwise
6; we may reference variables that were not live across basic blocks
7; resulting in undefined virtual registers.
8;
9; In this example, this is illustrated by a spill/reload of the
10; LOADED_PTR_SLOT.
11;
12; Before this patch, the compiler was accessing two different spill
13; slots.
14; <rdar://problem/15192473>
15
16; CHECK-LABEL: @test_bitcast
17; Load the value of the function pointer: %loaded_ptr
18; Spill %arg2.
19; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]
20; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]
21; Spill %loaded_ptr.
22; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]
23; Perform the indirect call.
24; Load the function pointer.
25; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]
26; Load the third argument
27; CHECK: movq [[ARG2_SLOT]], %rdx
28; Load the first argument
29; CHECK: movq %rdx, %rdi
30; Load the second argument
31; CHECK: movq %rdx, %rsi
32; Call.
33; CHECK: callq *[[FCT_PTR]]
34; CHECK: ret
35define i64 @test_bitcast(ptr %arg, i1 %bool, i64 %arg2) {
36entry:
37  %loaded_ptr = load ptr, ptr %arg, align 8
38  switch i1 %bool, label %default [
39    i1 true, label %label_true
40    i1 false, label %label_end
41  ]
42default:
43  br label %label_end
44
45label_true:
46  br label %label_end
47
48label_end:
49  %res = call i64 %loaded_ptr(i64 %arg2, i64 %arg2, i64 %arg2)
50  ret i64 %res
51}
52
53; CHECK-LABEL: @test_inttoptr
54; Load the value of the function pointer: %loaded_ptr
55; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]
56; Spill %loaded_ptr.
57; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]
58; Spill %arg2.
59; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]
60; Perform the indirect call.
61; Load the function pointer.
62; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]
63; Load the third argument
64; CHECK: movq [[ARG2_SLOT]], %rdx
65; Load the first argument
66; CHECK: movq %rdx, %rdi
67; Load the second argument
68; CHECK: movq %rdx, %rsi
69; Call.
70; CHECK: callq *[[FCT_PTR]]
71; CHECK: ret
72define i64 @test_inttoptr(ptr %arg, i1 %bool, i64 %arg2) {
73entry:
74  %loaded_ptr = load ptr, ptr %arg, align 8
75  %raw = ptrtoint ptr %loaded_ptr to i64
76  switch i1 %bool, label %default [
77    i1 true, label %label_true
78    i1 false, label %label_end
79  ]
80default:
81  br label %label_end
82
83label_true:
84  br label %label_end
85
86label_end:
87  %fct_ptr = inttoptr i64 %raw to ptr
88  %res = call i64 %fct_ptr(i64 %arg2, i64 %arg2, i64 %arg2)
89  ret i64 %res
90}
91
92; CHECK-LABEL: @test_ptrtoint
93; Spill %arg2.
94; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]
95; Load the value of the function pointer: %loaded_ptr
96; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]
97; Spill %loaded_ptr.
98; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]
99; Perform the indirect call.
100; Load the function pointer.
101; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]
102; Load the third argument
103; CHECK: movq [[ARG2_SLOT]], %rdx
104; Load the first argument
105; CHECK: movq %rdx, %rdi
106; Load the second argument
107; CHECK: movq %rdx, %rsi
108; Call.
109; CHECK: callq *[[FCT_PTR]]
110; CHECK: ret
111define i64 @test_ptrtoint(ptr %arg, i1 %bool, i64 %arg2) {
112entry:
113  %loaded_ptr = load ptr, ptr %arg, align 8
114  switch i1 %bool, label %default [
115    i1 true, label %label_true
116    i1 false, label %label_end
117  ]
118default:
119  br label %label_end
120
121label_true:
122  br label %label_end
123
124label_end:
125  %fct_int = ptrtoint ptr %loaded_ptr to i64
126  %fct_ptr = inttoptr i64 %fct_int to ptr
127  %res = call i64 %fct_ptr(i64 %arg2, i64 %arg2, i64 %arg2)
128  ret i64 %res
129}
130