2016-08-27 08:18:31 +08:00
|
|
|
; RUN: not llc -O0 -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR
|
2016-09-01 02:43:04 +08:00
|
|
|
; RUN: llc -O0 -global-isel -global-isel-abort=0 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=FALLBACK
|
2017-02-24 05:05:42 +08:00
|
|
|
; RUN: llc -O0 -global-isel -global-isel-abort=2 -pass-remarks-missed='gisel*' -verify-machineinstrs %s -o %t.out 2> %t.err
|
2016-12-06 05:40:33 +08:00
|
|
|
; RUN: FileCheck %s --check-prefix=FALLBACK-WITH-REPORT-OUT < %t.out
|
|
|
|
; RUN: FileCheck %s --check-prefix=FALLBACK-WITH-REPORT-ERR < %t.err
|
2016-08-27 08:18:31 +08:00
|
|
|
; This file checks that the fallback path to selection dag works.
|
|
|
|
; The test is fragile in the sense that it must be updated to expose
|
|
|
|
; something that fails with global-isel.
|
|
|
|
; When we cannot produce a test case anymore, that means we can remove
|
|
|
|
; the fallback path.
|
|
|
|
|
|
|
|
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
2016-10-14 18:19:40 +08:00
|
|
|
target triple = "aarch64--"
|
2016-08-27 08:18:31 +08:00
|
|
|
|
2016-10-14 18:19:40 +08:00
|
|
|
; We use __fixunstfti as the common denominator for __fixunstfti on Linux and
|
|
|
|
; ___fixunstfti on iOS
|
2017-02-24 05:05:42 +08:00
|
|
|
; ERROR: unable to lower arguments: i128 (i128)* (in function: ABIi128)
|
2016-08-27 08:18:31 +08:00
|
|
|
; FALLBACK: ldr q0,
|
2016-10-14 18:19:40 +08:00
|
|
|
; FALLBACK-NEXT: bl __fixunstfti
|
2016-09-01 02:43:04 +08:00
|
|
|
;
|
2017-02-24 05:05:42 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower arguments: i128 (i128)* (in function: ABIi128)
|
2016-12-06 05:40:33 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for ABIi128
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: ABIi128:
|
|
|
|
; FALLBACK-WITH-REPORT-OUT: ldr q0,
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-NEXT: bl __fixunstfti
|
2016-08-27 08:18:31 +08:00
|
|
|
define i128 @ABIi128(i128 %arg1) {
|
2016-12-06 05:40:33 +08:00
|
|
|
%farg1 = bitcast i128 %arg1 to fp128
|
2016-08-27 08:18:31 +08:00
|
|
|
%res = fptoui fp128 %farg1 to i128
|
|
|
|
ret i128 %res
|
|
|
|
}
|
2016-12-06 05:40:33 +08:00
|
|
|
|
|
|
|
; It happens that we don't handle ConstantArray instances yet during
|
|
|
|
; translation. Any other constant would be fine too.
|
|
|
|
|
2017-02-24 05:05:42 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate constant: [1 x double] (in function: constant)
|
2016-12-06 05:40:33 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for constant
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: constant:
|
|
|
|
; FALLBACK-WITH-REPORT-OUT: fmov d0, #1.0
|
|
|
|
define [1 x double] @constant() {
|
|
|
|
ret [1 x double] [double 1.0]
|
2016-12-06 07:10:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
; The key problem here is that we may fail to create an MBB referenced by a
|
|
|
|
; PHI. If so, we cannot complete the G_PHI and mustn't try or bad things
|
|
|
|
; happen.
|
2017-10-10 04:07:43 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: G_STORE %vreg6, %vreg2; mem:ST4[%addr] GPR:%vreg6,%vreg2 (in function: pending_phis)
|
2016-12-06 07:10:19 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for pending_phis
|
2016-12-07 02:38:29 +08:00
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: pending_phis:
|
2016-12-06 07:10:19 +08:00
|
|
|
define i32 @pending_phis(i1 %tst, i32 %val, i32* %addr) {
|
|
|
|
br i1 %tst, label %true, label %false
|
|
|
|
|
|
|
|
end:
|
|
|
|
%res = phi i32 [%val, %true], [42, %false]
|
|
|
|
ret i32 %res
|
|
|
|
|
|
|
|
true:
|
|
|
|
store atomic i32 42, i32* %addr seq_cst, align 4
|
|
|
|
br label %end
|
|
|
|
|
|
|
|
false:
|
|
|
|
br label %end
|
|
|
|
|
2016-12-06 05:40:33 +08:00
|
|
|
}
|
2016-12-07 02:38:29 +08:00
|
|
|
|
2016-12-07 02:38:38 +08:00
|
|
|
; General legalizer inability to handle types whose size wasn't a power of 2.
|
2017-02-24 05:05:42 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg1<def>(s42) = G_LOAD %vreg0; mem:LD6[%addr](align=8) (in function: odd_type)
|
2016-12-07 02:38:29 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for odd_type
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: odd_type:
|
|
|
|
define void @odd_type(i42* %addr) {
|
|
|
|
%val42 = load i42, i42* %addr
|
|
|
|
ret void
|
|
|
|
}
|
2016-12-07 02:38:38 +08:00
|
|
|
|
[GlobalISel] LegalizerInfo: Enable legalization of non-power-of-2 types
Summary: Legalize only if the type is marked as Legal or Custom. If not, return Unsupported as LegalizerHelper is not able to handle non-power-of-2 types right now.
Reviewers: qcolombet, aditya_nandakumar, dsanders, t.p.northover, kristof.beyls, javed.absar, ab
Reviewed By: kristof.beyls, ab
Subscribers: dberris, rovka, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31711
llvm-svn: 299929
2017-04-11 18:10:14 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg1<def>(<7 x s32>) = G_LOAD %vreg0; mem:LD28[%addr](align=32) (in function: odd_vector)
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for odd_vector
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: odd_vector:
|
|
|
|
define void @odd_vector(<7 x i32>* %addr) {
|
|
|
|
%vec = load <7 x i32>, <7 x i32>* %addr
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
2017-02-07 05:57:06 +08:00
|
|
|
; AArch64 was asserting instead of returning an invalid mapping for unknown
|
|
|
|
; sizes.
|
2017-02-24 05:05:42 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: ret: ' ret i128 undef' (in function: sequence_sizes)
|
2017-02-07 05:57:06 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for sequence_sizes
|
|
|
|
; FALLBACK-WITH-REPORT-LABEL: sequence_sizes:
|
|
|
|
define i128 @sequence_sizes([8 x i8] %in) {
|
|
|
|
ret i128 undef
|
|
|
|
}
|
2017-02-14 06:14:16 +08:00
|
|
|
|
|
|
|
; Just to make sure we don't accidentally emit a normal load/store.
|
2017-02-24 05:05:42 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: %vreg2<def>(s64) = G_LOAD %vreg0; mem:LD8[%addr] GPR:%vreg2,%vreg0 (in function: atomic_ops)
|
2017-02-14 06:14:16 +08:00
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for atomic_ops
|
|
|
|
; FALLBACK-WITH-REPORT-LABEL: atomic_ops:
|
|
|
|
define i64 @atomic_ops(i64* %addr) {
|
|
|
|
store atomic i64 0, i64* %addr unordered, align 8
|
|
|
|
%res = load atomic i64, i64* %addr seq_cst, align 8
|
|
|
|
ret i64 %res
|
|
|
|
}
|
2017-03-08 04:53:09 +08:00
|
|
|
|
|
|
|
; Make sure we don't mess up metadata arguments.
|
|
|
|
declare void @llvm.write_register.i64(metadata, i64)
|
|
|
|
|
|
|
|
; 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)
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_write_register_intrin
|
|
|
|
; FALLBACK-WITH-REPORT-LABEL: test_write_register_intrin:
|
|
|
|
define void @test_write_register_intrin() {
|
|
|
|
call void @llvm.write_register.i64(metadata !{!"sp"}, i64 0)
|
|
|
|
ret void
|
|
|
|
}
|
2017-03-10 08:25:35 +08:00
|
|
|
|
|
|
|
@_ZTIi = external global i8*
|
|
|
|
declare i32 @__gxx_personality_v0(...)
|
|
|
|
|
|
|
|
; Check that we fallback on invoke translation failures.
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: invoke: ' invoke void %callee(i128 0)
|
|
|
|
; FALLBACK-WITH-REPORT-NEXT: to label %continue unwind label %broken' (in function: invoke_weird_type)
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for invoke_weird_type
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: invoke_weird_type:
|
|
|
|
define void @invoke_weird_type(void(i128)* %callee) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
|
|
|
invoke void %callee(i128 0)
|
|
|
|
to label %continue unwind label %broken
|
|
|
|
|
|
|
|
broken:
|
|
|
|
landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
|
|
|
|
ret void
|
|
|
|
|
|
|
|
continue:
|
|
|
|
ret void
|
|
|
|
}
|
2017-03-21 00:52:08 +08:00
|
|
|
|
|
|
|
; Check that we fallback on invoke translation failures.
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg0<def>(s128) = G_FCONSTANT quad 2
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_quad_dump
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: test_quad_dump:
|
|
|
|
define fp128 @test_quad_dump() {
|
|
|
|
ret fp128 0xL00000000000000004000000000000000
|
|
|
|
}
|
2017-04-19 15:23:57 +08:00
|
|
|
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg0<def>(p0) = G_EXTRACT_VECTOR_ELT %vreg1, %vreg2; (in function: vector_of_pointers_extractelement)
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for vector_of_pointers_extractelement
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: vector_of_pointers_extractelement:
|
2017-07-01 04:27:36 +08:00
|
|
|
@var = global <2 x i16*> zeroinitializer
|
2017-04-19 15:23:57 +08:00
|
|
|
define void @vector_of_pointers_extractelement() {
|
2017-07-01 04:27:36 +08:00
|
|
|
br label %end
|
|
|
|
|
|
|
|
block:
|
|
|
|
%dummy = extractelement <2 x i16*> %vec, i32 0
|
2017-04-19 15:23:57 +08:00
|
|
|
ret void
|
2017-07-01 04:27:36 +08:00
|
|
|
|
|
|
|
end:
|
|
|
|
%vec = load <2 x i16*>, <2 x i16*>* undef
|
|
|
|
br label %block
|
2017-04-19 15:23:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %vreg0<def>(<2 x p0>) = G_INSERT_VECTOR_ELT %vreg1, %vreg2, %vreg3; (in function: vector_of_pointers_insertelement
|
|
|
|
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for vector_of_pointers_insertelement
|
|
|
|
; FALLBACK-WITH-REPORT-OUT-LABEL: vector_of_pointers_insertelement:
|
|
|
|
define void @vector_of_pointers_insertelement() {
|
2017-07-01 04:27:36 +08:00
|
|
|
br label %end
|
|
|
|
|
|
|
|
block:
|
|
|
|
%dummy = insertelement <2 x i16*> %vec, i16* null, i32 0
|
2017-04-19 15:23:57 +08:00
|
|
|
ret void
|
2017-07-01 04:27:36 +08:00
|
|
|
|
|
|
|
end:
|
|
|
|
%vec = load <2 x i16*>, <2 x i16*>* undef
|
|
|
|
br label %block
|
2017-04-19 15:23:57 +08:00
|
|
|
}
|