• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Tests desired and undesired folding of load instructions into cast
2; instructions.  The folding is only done when liveness analysis is performed,
3; so only O2 is tested.
4
5; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 | FileCheck %s
6
7; Not testing trunc, or 32-bit bitcast, because the lowered code uses pretty
8; much the same mov instructions regardless of whether folding is done.
9
10define internal i32 @zext_fold(i32 %arg) {
11entry:
12  %ptr = add i32 %arg, 200
13  %addr = inttoptr i32 %ptr to i8*
14  %load = load i8, i8* %addr, align 1
15  %result = zext i8 %load to i32
16  ret i32 %result
17}
18; CHECK-LABEL: zext_fold
19; CHECK: movzx {{.*}},BYTE PTR [{{.*}}+0xc8]
20
21define internal i32 @zext_nofold(i32 %arg) {
22entry:
23  %ptr = add i32 %arg, 200
24  %addr = inttoptr i32 %ptr to i8*
25  %load = load i8, i8* %addr, align 1
26  %tmp1 = zext i8 %load to i32
27  %tmp2 = zext i8 %load to i32
28  %result = add i32 %tmp1, %tmp2
29  ret i32 %result
30}
31; Test that load folding does not happen.
32; CHECK-LABEL: zext_nofold
33; CHECK-NOT: movzx {{.*}},BYTE PTR [{{.*}}+0xc8]
34
35define internal i32 @sext_fold(i32 %arg) {
36entry:
37  %ptr = add i32 %arg, 200
38  %addr = inttoptr i32 %ptr to i8*
39  %load = load i8, i8* %addr, align 1
40  %result = sext i8 %load to i32
41  ret i32 %result
42}
43; CHECK-LABEL: sext_fold
44; CHECK: movsx {{.*}},BYTE PTR [{{.*}}+0xc8]
45
46define internal i32 @sext_nofold(i32 %arg) {
47entry:
48  %ptr = add i32 %arg, 200
49  %addr = inttoptr i32 %ptr to i8*
50  %load = load i8, i8* %addr, align 1
51  %tmp1 = sext i8 %load to i32
52  %tmp2 = sext i8 %load to i32
53  %result = add i32 %tmp1, %tmp2
54  ret i32 %result
55}
56; Test that load folding does not happen.
57; CHECK-LABEL: sext_nofold
58; CHECK-NOT: movsx {{.*}},BYTE PTR [{{.*}}+0xc8]
59
60define internal float @fptrunc_fold(i32 %arg) {
61entry:
62  %ptr = add i32 %arg, 200
63  %addr = inttoptr i32 %ptr to double*
64  %load = load double, double* %addr, align 8
65  %result = fptrunc double %load to float
66  ret float %result
67}
68; CHECK-LABEL: fptrunc_fold
69; CHECK: cvtsd2ss {{.*}},QWORD PTR [{{.*}}+0xc8]
70
71define internal float @fptrunc_nofold(i32 %arg) {
72entry:
73  %ptr = add i32 %arg, 200
74  %addr = inttoptr i32 %ptr to double*
75  %load = load double, double* %addr, align 8
76  %tmp1 = fptrunc double %load to float
77  %tmp2 = fptrunc double %load to float
78  %result = fadd float %tmp1, %tmp2
79  ret float %result
80}
81; Test that load folding does not happen.
82; CHECK-LABEL: fptrunc_nofold
83; CHECK-NOT: cvtsd2ss {{.*}},QWORD PTR [{{.*}}+0xc8]
84
85define internal double @fpext_fold(i32 %arg) {
86entry:
87  %ptr = add i32 %arg, 200
88  %addr = inttoptr i32 %ptr to float*
89  %load = load float, float* %addr, align 4
90  %result = fpext float %load to double
91  ret double %result
92}
93; CHECK-LABEL: fpext_fold
94; CHECK: cvtss2sd {{.*}},DWORD PTR [{{.*}}+0xc8]
95
96define internal double @fpext_nofold(i32 %arg) {
97entry:
98  %ptr = add i32 %arg, 200
99  %addr = inttoptr i32 %ptr to float*
100  %load = load float, float* %addr, align 4
101  %tmp1 = fpext float %load to double
102  %tmp2 = fpext float %load to double
103  %result = fadd double %tmp1, %tmp2
104  ret double %result
105}
106; Test that load folding does not happen.
107; CHECK-LABEL: fpext_nofold
108; CHECK-NOT: cvtss2sd {{.*}},DWORD PTR [{{.*}}+0xc8]
109
110define internal i32 @fptoui_fold(i32 %arg) {
111entry:
112  %ptr = add i32 %arg, 200
113  %addr = inttoptr i32 %ptr to double*
114  %load = load double, double* %addr, align 8
115  %result = fptoui double %load to i16
116  %result2 = zext i16 %result to i32
117  ret i32 %result2
118}
119; CHECK-LABEL: fptoui_fold
120; CHECK: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8]
121
122define internal i32 @fptoui_nofold(i32 %arg) {
123entry:
124  %ptr = add i32 %arg, 200
125  %addr = inttoptr i32 %ptr to double*
126  %load = load double, double* %addr, align 8
127  %tmp1 = fptoui double %load to i16
128  %tmp2 = fptoui double %load to i16
129  %result = add i16 %tmp1, %tmp2
130  %result2 = zext i16 %result to i32
131  ret i32 %result2
132}
133; Test that load folding does not happen.
134; CHECK-LABEL: fptoui_nofold
135; CHECK-NOT: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8]
136
137define internal i32 @fptosi_fold(i32 %arg) {
138entry:
139  %ptr = add i32 %arg, 200
140  %addr = inttoptr i32 %ptr to double*
141  %load = load double, double* %addr, align 8
142  %result = fptosi double %load to i16
143  %result2 = zext i16 %result to i32
144  ret i32 %result2
145}
146; CHECK-LABEL: fptosi_fold
147; CHECK: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8]
148
149define internal i32 @fptosi_nofold(i32 %arg) {
150entry:
151  %ptr = add i32 %arg, 200
152  %addr = inttoptr i32 %ptr to double*
153  %load = load double, double* %addr, align 8
154  %tmp1 = fptosi double %load to i16
155  %tmp2 = fptosi double %load to i16
156  %result = add i16 %tmp1, %tmp2
157  %result2 = zext i16 %result to i32
158  ret i32 %result2
159}
160; Test that load folding does not happen.
161; CHECK-LABEL: fptosi_nofold
162; CHECK-NOT: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8]
163
164define internal double @uitofp_fold(i32 %arg) {
165entry:
166  %ptr = add i32 %arg, 200
167  %addr = inttoptr i32 %ptr to i16*
168  %load = load i16, i16* %addr, align 1
169  %result = uitofp i16 %load to double
170  ret double %result
171}
172; CHECK-LABEL: uitofp_fold
173; CHECK: movzx {{.*}},WORD PTR [{{.*}}+0xc8]
174
175define internal double @uitofp_nofold(i32 %arg) {
176entry:
177  %ptr = add i32 %arg, 200
178  %addr = inttoptr i32 %ptr to i16*
179  %load = load i16, i16* %addr, align 1
180  %tmp1 = uitofp i16 %load to double
181  %tmp2 = uitofp i16 %load to double
182  %result = fadd double %tmp1, %tmp2
183  ret double %result
184}
185; Test that load folding does not happen.
186; CHECK-LABEL: uitofp_nofold
187; CHECK-NOT: movzx {{.*}},WORD PTR [{{.*}}+0xc8]
188
189define internal double @sitofp_fold(i32 %arg) {
190entry:
191  %ptr = add i32 %arg, 200
192  %addr = inttoptr i32 %ptr to i16*
193  %load = load i16, i16* %addr, align 1
194  %result = sitofp i16 %load to double
195  ret double %result
196}
197; CHECK-LABEL: sitofp_fold
198; CHECK: movsx {{.*}},WORD PTR [{{.*}}+0xc8]
199
200define internal double @sitofp_nofold(i32 %arg) {
201entry:
202  %ptr = add i32 %arg, 200
203  %addr = inttoptr i32 %ptr to i16*
204  %load = load i16, i16* %addr, align 1
205  %tmp1 = sitofp i16 %load to double
206  %tmp2 = sitofp i16 %load to double
207  %result = fadd double %tmp1, %tmp2
208  ret double %result
209}
210; Test that load folding does not happen.
211; CHECK-LABEL: sitofp_nofold
212; CHECK-NOT: movsx {{.*}},WORD PTR [{{.*}}+0xc8]
213
214define internal double @bitcast_i64_fold(i32 %arg) {
215entry:
216  %ptr = add i32 %arg, 200
217  %addr = inttoptr i32 %ptr to i64*
218  %load = load i64, i64* %addr, align 1
219  %result = bitcast i64 %load to double
220  ret double %result
221}
222; CHECK-LABEL: bitcast_i64_fold
223; CHECK: movq {{.*}},QWORD PTR [{{.*}}+0xc8]
224
225define internal double @bitcast_i64_nofold(i32 %arg) {
226entry:
227  %ptr = add i32 %arg, 200
228  %addr = inttoptr i32 %ptr to i64*
229  %load = load i64, i64* %addr, align 1
230  %tmp1 = bitcast i64 %load to double
231  %tmp2 = bitcast i64 %load to double
232  %result = fadd double %tmp1, %tmp2
233  ret double %result
234}
235; Test that load folding does not happen.
236; CHECK-LABEL: bitcast_i64_nofold
237; CHECK-NOT: movq {{.*}},QWORD PTR [{{.*}}+0xc8]
238
239define internal i64 @bitcast_double_fold(i32 %arg) {
240entry:
241  %ptr = add i32 %arg, 200
242  %addr = inttoptr i32 %ptr to double*
243  %load = load double, double* %addr, align 8
244  %result = bitcast double %load to i64
245  ret i64 %result
246}
247; CHECK-LABEL: bitcast_double_fold
248; CHECK-NOT: QWORD PTR
249; CHECK: mov {{.*}},DWORD PTR [{{.*}}+0xc8]
250; CHECK: mov {{.*}},DWORD PTR [{{.*}}+0xcc]
251; CHECK-NOT: QWORD PTR
252
253define internal i64 @bitcast_double_nofold(i32 %arg) {
254entry:
255  %ptr = add i32 %arg, 200
256  %addr = inttoptr i32 %ptr to double*
257  %load = load double, double* %addr, align 8
258  %tmp1 = bitcast double %load to i64
259  %tmp2 = bitcast double %load to i64
260  %result = add i64 %tmp1, %tmp2
261  ret i64 %result
262}
263; Test that load folding does not happen.
264; CHECK-LABEL: bitcast_double_nofold
265; CHECK: QWORD PTR
266; CHECK: QWORD PTR
267