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