• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: not llc -O0 -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR
2; RUN: llc -O0 -global-isel -global-isel-abort=0 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=FALLBACK
3; RUN: llc -O0 -global-isel -global-isel-abort=2 -pass-remarks-missed='gisel*' -verify-machineinstrs %s -o %t.out 2> %t.err
4; RUN: FileCheck %s --check-prefix=FALLBACK-WITH-REPORT-OUT < %t.out
5; RUN: FileCheck %s --check-prefix=FALLBACK-WITH-REPORT-ERR < %t.err
6; RUN: not llc -global-isel -mtriple aarch64_be %s -o - 2>&1 | FileCheck %s --check-prefix=BIG-ENDIAN
7; This file checks that the fallback path to selection dag works.
8; The test is fragile in the sense that it must be updated to expose
9; something that fails with global-isel.
10; When we cannot produce a test case anymore, that means we can remove
11; the fallback path.
12
13target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
14target triple = "aarch64--"
15
16; BIG-ENDIAN: unable to translate in big endian mode
17
18; We use __fixunstfti as the common denominator for __fixunstfti on Linux and
19; ___fixunstfti on iOS
20; ERROR: unable to lower arguments: i128 (i128)* (in function: ABIi128)
21; FALLBACK: ldr q0,
22; FALLBACK-NEXT: bl __fixunstfti
23;
24; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower arguments: i128 (i128)* (in function: ABIi128)
25; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for ABIi128
26; FALLBACK-WITH-REPORT-OUT-LABEL: ABIi128:
27; FALLBACK-WITH-REPORT-OUT: ldr q0,
28; FALLBACK-WITH-REPORT-OUT-NEXT: bl __fixunstfti
29define i128 @ABIi128(i128 %arg1) {
30  %farg1 =       bitcast i128 %arg1 to fp128
31  %res = fptoui fp128 %farg1 to i128
32  ret i128 %res
33}
34
35  ; The key problem here is that we may fail to create an MBB referenced by a
36  ; PHI. If so, we cannot complete the G_PHI and mustn't try or bad things
37  ; happen.
38; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: G_STORE %6:gpr(s32), %2:gpr(p0) :: (store seq_cst 4 into %ir.addr) (in function: pending_phis)
39; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for pending_phis
40; FALLBACK-WITH-REPORT-OUT-LABEL: pending_phis:
41define i32 @pending_phis(i1 %tst, i32 %val, i32* %addr) {
42  br i1 %tst, label %true, label %false
43
44end:
45  %res = phi i32 [%val, %true], [42, %false]
46  ret i32 %res
47
48true:
49  store atomic i32 42, i32* %addr seq_cst, align 4
50  br label %end
51
52false:
53  br label %end
54
55}
56
57; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %0:_(s24) = G_LOAD %1:_(p0) :: (load 3 from `i24* undef`, align 1) (in function: odd_type_load)
58; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for odd_type_load
59; FALLBACK-WITH-REPORT-OUT-LABEL: odd_type_load
60define i32 @odd_type_load() {
61entry:
62  %ld = load i24, i24* undef, align 1
63  %cst = zext i24 %ld to i32
64  ret i32 %cst
65}
66
67  ; General legalizer inability to handle types whose size wasn't a power of 2.
68; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: G_STORE %1:_(s42), %0:_(p0) :: (store 6 into %ir.addr, align 8) (in function: odd_type)
69; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for odd_type
70; FALLBACK-WITH-REPORT-OUT-LABEL: odd_type:
71define void @odd_type(i42* %addr) {
72  %val42 = load i42, i42* %addr
73  store i42 %val42, i42* %addr
74  ret void
75}
76
77; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: G_STORE %1:_(<7 x s32>), %0:_(p0) :: (store 28 into %ir.addr, align 32) (in function: odd_vector)
78; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for odd_vector
79; FALLBACK-WITH-REPORT-OUT-LABEL: odd_vector:
80define void @odd_vector(<7 x i32>* %addr) {
81  %vec = load <7 x i32>, <7 x i32>* %addr
82  store <7 x i32> %vec, <7 x i32>* %addr
83  ret void
84}
85
86  ; AArch64 was asserting instead of returning an invalid mapping for unknown
87  ; sizes.
88; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: ret: '  ret i128 undef' (in function: sequence_sizes)
89; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for sequence_sizes
90; FALLBACK-WITH-REPORT-LABEL: sequence_sizes:
91define i128 @sequence_sizes([8 x i8] %in) {
92  ret i128 undef
93}
94
95; Just to make sure we don't accidentally emit a normal load/store.
96; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: %2:gpr(s64) = G_LOAD %0:gpr(p0) :: (load seq_cst 8 from %ir.addr)  (in function: atomic_ops)
97; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for atomic_ops
98; FALLBACK-WITH-REPORT-LABEL: atomic_ops:
99define i64 @atomic_ops(i64* %addr) {
100  store atomic i64 0, i64* %addr unordered, align 8
101  %res = load atomic i64, i64* %addr seq_cst, align 8
102  ret i64 %res
103}
104
105; Make sure we don't mess up metadata arguments.
106declare void @llvm.write_register.i64(metadata, i64)
107
108; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: call: ' call void @llvm.write_register.i64(metadata !0, i64 0)' (in function: test_write_register_intrin)
109; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_write_register_intrin
110; FALLBACK-WITH-REPORT-LABEL: test_write_register_intrin:
111define void @test_write_register_intrin() {
112  call void @llvm.write_register.i64(metadata !{!"sp"}, i64 0)
113  ret void
114}
115
116@_ZTIi = external global i8*
117declare i32 @__gxx_personality_v0(...)
118
119; Check that we fallback on invoke translation failures.
120; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: invoke: '  invoke void %callee(i128 0)
121; FALLBACK-WITH-REPORT-NEXT:   to label %continue unwind label %broken' (in function: invoke_weird_type)
122; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for invoke_weird_type
123; FALLBACK-WITH-REPORT-OUT-LABEL: invoke_weird_type:
124define void @invoke_weird_type(void(i128)* %callee) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
125  invoke void %callee(i128 0)
126    to label %continue unwind label %broken
127
128broken:
129  landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
130  ret void
131
132continue:
133  ret void
134}
135
136; Check that we fallback on invoke translation failures.
137; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %0:_(s128) = G_FCONSTANT fp128 0xL00000000000000004000000000000000
138; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_quad_dump
139; FALLBACK-WITH-REPORT-OUT-LABEL: test_quad_dump:
140define fp128 @test_quad_dump() {
141  ret fp128 0xL00000000000000004000000000000000
142}
143
144; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %2:_(p0) = G_EXTRACT_VECTOR_ELT %0:_(<2 x p0>), %3:_(s32) (in function: vector_of_pointers_extractelement)
145; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for vector_of_pointers_extractelement
146; FALLBACK-WITH-REPORT-OUT-LABEL: vector_of_pointers_extractelement:
147@var = global <2 x i16*> zeroinitializer
148define void @vector_of_pointers_extractelement() {
149  br label %end
150
151block:
152  %dummy = extractelement <2 x i16*> %vec, i32 0
153  store i16* %dummy, i16** undef
154  ret void
155
156end:
157  %vec = load <2 x i16*>, <2 x i16*>* undef
158  br label %block
159}
160
161; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: G_STORE %2:_(<2 x p0>), %1:_(p0) :: (store 16 into `<2 x i16*>* undef`) (in function: vector_of_pointers_insertelement)
162; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for vector_of_pointers_insertelement
163; FALLBACK-WITH-REPORT-OUT-LABEL: vector_of_pointers_insertelement:
164define void @vector_of_pointers_insertelement() {
165  br label %end
166
167block:
168  %dummy = insertelement <2 x i16*> %vec, i16* null, i32 0
169  store <2 x i16*> %dummy, <2 x i16*>* undef
170  ret void
171
172end:
173  %vec = load <2 x i16*>, <2 x i16*>* undef
174  br label %block
175}
176
177; FALLBACK-WITH-REPORT-ERR remark: <unknown>:0:0: unable to legalize instruction: G_STORE %3, %4 :: (store 12 into `i96* undef`, align 16) (in function: nonpow2_add_narrowing)
178; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_add_narrowing
179; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_add_narrowing:
180define void @nonpow2_add_narrowing() {
181  %a = add i128 undef, undef
182  %b = trunc i128 %a to i96
183  %dummy = add i96 %b, %b
184  store i96 %dummy, i96* undef
185  ret void
186}
187
188; FALLBACK-WITH-REPORT-ERR remark: <unknown>:0:0: unable to legalize instruction: G_STORE %3, %4 :: (store 12 into `i96* undef`, align 16) (in function: nonpow2_add_narrowing)
189; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_or_narrowing
190; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_or_narrowing:
191define void @nonpow2_or_narrowing() {
192  %a = add i128 undef, undef
193  %b = trunc i128 %a to i96
194  %dummy = or i96 %b, %b
195  store i96 %dummy, i96* undef
196  ret void
197}
198
199; FALLBACK-WITH-REPORT-ERR remark: <unknown>:0:0: unable to legalize instruction: G_STORE %0, %1 :: (store 12 into `i96* undef`, align 16) (in function: nonpow2_load_narrowing)
200; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_load_narrowing
201; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_load_narrowing:
202define void @nonpow2_load_narrowing() {
203  %dummy = load i96, i96* undef
204  store i96 %dummy, i96* undef
205  ret void
206}
207
208; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: G_STORE %3:_(s96), %0:_(p0) :: (store 12 into %ir.c, align 16) (in function: nonpow2_store_narrowing
209; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_store_narrowing
210; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_store_narrowing:
211define void @nonpow2_store_narrowing(i96* %c) {
212  %a = add i128 undef, undef
213  %b = trunc i128 %a to i96
214  store i96 %b, i96* %c
215  ret void
216}
217
218; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: G_STORE %0:_(s96), %1:_(p0) :: (store 12 into `i96* undef`, align 16) (in function: nonpow2_constant_narrowing)
219; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_constant_narrowing
220; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_constant_narrowing:
221define void @nonpow2_constant_narrowing() {
222  store i96 0, i96* undef
223  ret void
224}
225
226; Currently can't handle vector lengths that aren't an exact multiple of
227; natively supported vector lengths. Test that the fall-back works for those.
228; FALLBACK-WITH-REPORT-ERR-G_IMPLICIT_DEF-LEGALIZABLE: (FIXME: this is what is expected once we can legalize non-pow-of-2 G_IMPLICIT_DEF) remark: <unknown>:0:0: unable to legalize instruction: %1:_(<7 x s64>) = G_ADD %0, %0 (in function: nonpow2_vector_add_fewerelements
229; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %2:_(s64) = G_EXTRACT_VECTOR_ELT %1:_(<7 x s64>), %3:_(s64) (in function: nonpow2_vector_add_fewerelements)
230; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_vector_add_fewerelements
231; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_vector_add_fewerelements:
232define void @nonpow2_vector_add_fewerelements() {
233  %dummy = add <7 x i64> undef, undef
234  %ex = extractelement <7 x i64> %dummy, i64 0
235  store i64 %ex, i64* undef
236  ret void
237}
238
239%swift_error = type {i64, i8}
240
241; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower arguments due to swifterror/swiftself: void (%swift_error**)* (in function: swifterror_param)
242; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for swifterror_param
243define void @swifterror_param(%swift_error** swifterror %error_ptr_ref) {
244  ret void
245}
246
247; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: alloca: '  %error_ptr_ref = alloca swifterror %swift_error*' (in function: swifterror_alloca)
248; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for swifterror_alloca
249; We can't currently test the call parameters being swifterror because the value
250; must come from a swifterror alloca or parameter, at which point we already
251; fallback. As long as those cases work however we should be fine.
252define void @swifterror_alloca(i8* %error_ref) {
253entry:
254  %error_ptr_ref = alloca swifterror %swift_error*
255  store %swift_error* null, %swift_error** %error_ptr_ref
256  call void @swifterror_param(%swift_error** swifterror %error_ptr_ref)
257  ret void
258}
259
260
261