• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]
19; Spill %arg2.
20; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[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 first argument
25; CHECK: movq [[ARG2_SLOT]], %rdi
26; Load the second argument
27; CHECK: movq [[ARG2_SLOT]], %rsi
28; Load the third argument
29; CHECK: movq [[ARG2_SLOT]], %rdx
30; Load the function pointer.
31; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]
32; Call.
33; CHECK: callq *[[FCT_PTR]]
34; CHECK: ret
35define i64 @test_bitcast(i64 (i64, i64, i64)** %arg, i1 %bool, i64 %arg2) {
36entry:
37  %loaded_ptr = load i64 (i64, i64, i64)*, i64 (i64, i64, i64)** %arg, align 8
38  %raw = bitcast i64 (i64, i64, i64)* %loaded_ptr to i8*
39  switch i1 %bool, label %default [
40    i1 true, label %label_true
41    i1 false, label %label_end
42  ]
43default:
44  br label %label_end
45
46label_true:
47  br label %label_end
48
49label_end:
50  %fct_ptr = bitcast i8* %raw to i64 (i64, i64, i64)*
51  %res = call i64 %fct_ptr(i64 %arg2, i64 %arg2, i64 %arg2)
52  ret i64 %res
53}
54
55; CHECK-LABEL: @test_inttoptr
56; Load the value of the function pointer: %loaded_ptr
57; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]
58; Spill %arg2.
59; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]
60; Spill %loaded_ptr.
61; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]
62; Perform the indirect call.
63; Load the first argument
64; CHECK: movq [[ARG2_SLOT]], %rdi
65; Load the second argument
66; CHECK: movq [[ARG2_SLOT]], %rsi
67; Load the third argument
68; CHECK: movq [[ARG2_SLOT]], %rdx
69; Load the function pointer.
70; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]
71; Call.
72; CHECK: callq *[[FCT_PTR]]
73; CHECK: ret
74define i64 @test_inttoptr(i64 (i64, i64, i64)** %arg, i1 %bool, i64 %arg2) {
75entry:
76  %loaded_ptr = load i64 (i64, i64, i64)*, i64 (i64, i64, i64)** %arg, align 8
77  %raw = ptrtoint i64 (i64, i64, i64)* %loaded_ptr to i64
78  switch i1 %bool, label %default [
79    i1 true, label %label_true
80    i1 false, label %label_end
81  ]
82default:
83  br label %label_end
84
85label_true:
86  br label %label_end
87
88label_end:
89  %fct_ptr = inttoptr i64 %raw to i64 (i64, i64, i64)*
90  %res = call i64 %fct_ptr(i64 %arg2, i64 %arg2, i64 %arg2)
91  ret i64 %res
92}
93
94; CHECK-LABEL: @test_ptrtoint
95; Load the value of the function pointer: %loaded_ptr
96; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]
97; Spill %arg2.
98; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]
99; Spill %loaded_ptr.
100; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]
101; Perform the indirect call.
102; Load the first argument
103; CHECK: movq [[ARG2_SLOT]], %rdi
104; Load the second argument
105; CHECK: movq [[ARG2_SLOT]], %rsi
106; Load the third argument
107; CHECK: movq [[ARG2_SLOT]], %rdx
108; Load the function pointer.
109; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]
110; Call.
111; CHECK: callq *[[FCT_PTR]]
112; CHECK: ret
113define i64 @test_ptrtoint(i64 (i64, i64, i64)** %arg, i1 %bool, i64 %arg2) {
114entry:
115  %loaded_ptr = load i64 (i64, i64, i64)*, i64 (i64, i64, i64)** %arg, align 8
116  %raw = bitcast i64 (i64, i64, i64)* %loaded_ptr to i8*
117  switch i1 %bool, label %default [
118    i1 true, label %label_true
119    i1 false, label %label_end
120  ]
121default:
122  br label %label_end
123
124label_true:
125  br label %label_end
126
127label_end:
128  %fct_int = ptrtoint i8* %raw to i64
129  %fct_ptr = inttoptr i64 %fct_int to i64 (i64, i64, i64)*
130  %res = call i64 %fct_ptr(i64 %arg2, i64 %arg2, i64 %arg2)
131  ret i64 %res
132}
133