1; RUN: not --crash 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 --crash 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 translate instruction: ret 21; FALLBACK: ldr q0, 22; FALLBACK-NEXT: bl __fixunstfti 23; 24; FALLBACK-WITH-REPORT-ERR: unable to translate instruction: ret 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; 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) 36; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for odd_vector 37; FALLBACK-WITH-REPORT-OUT-LABEL: odd_vector: 38define void @odd_vector(<7 x i32>* %addr) { 39 %vec = load <7 x i32>, <7 x i32>* %addr 40 store <7 x i32> %vec, <7 x i32>* %addr 41 ret void 42} 43 44 ; AArch64 was asserting instead of returning an invalid mapping for unknown 45 ; sizes. 46; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: ret: ' ret i128 undef' (in function: sequence_sizes) 47; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for sequence_sizes 48; FALLBACK-WITH-REPORT-LABEL: sequence_sizes: 49define i128 @sequence_sizes([8 x i8] %in) { 50 ret i128 undef 51} 52 53; Make sure we don't mess up metadata arguments. 54declare void @llvm.write_register.i64(metadata, i64) 55 56; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: G_WRITE_REGISTER !0, %0:_(s64) (in function: test_write_register_intrin) 57; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_write_register_intrin 58; FALLBACK-WITH-REPORT-LABEL: test_write_register_intrin: 59define void @test_write_register_intrin() { 60 call void @llvm.write_register.i64(metadata !{!"sp"}, i64 0) 61 ret void 62} 63 64@_ZTIi = external global i8* 65declare i32 @__gxx_personality_v0(...) 66 67; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %0:_(s128) = G_FCONSTANT fp128 0xL00000000000000004000000000000000 68; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_quad_dump 69; FALLBACK-WITH-REPORT-OUT-LABEL: test_quad_dump: 70define fp128 @test_quad_dump() { 71 ret fp128 0xL00000000000000004000000000000000 72} 73 74; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %2:_(<2 x p0>) = G_INSERT_VECTOR_ELT %0:_, %{{[0-9]+}}:_(p0), %{{[0-9]+}}:_(s32) (in function: vector_of_pointers_insertelement) 75; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for vector_of_pointers_insertelement 76; FALLBACK-WITH-REPORT-OUT-LABEL: vector_of_pointers_insertelement: 77define void @vector_of_pointers_insertelement() { 78 br label %end 79 80block: 81 %dummy = insertelement <2 x i16*> %vec, i16* null, i32 0 82 store <2 x i16*> %dummy, <2 x i16*>* undef 83 ret void 84 85end: 86 %vec = load <2 x i16*>, <2 x i16*>* undef 87 br label %block 88} 89 90; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %{{[0-9]+}}:_(s96) = G_ADD %{{[0-9]+}}:_, %{{[0-9]+}}:_ (in function: nonpow2_add_narrowing) 91; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_add_narrowing 92; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_add_narrowing: 93define void @nonpow2_add_narrowing(i128 %x, i128 %y) { 94 %a = add i128 %x, %y 95 %b = trunc i128 %a to i96 96 %dummy = add i96 %b, %b 97 store i96 %dummy, i96* undef 98 ret void 99} 100 101; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %{{[0-9]+}}:_(s96) = G_INSERT %{{[0-9]+}}:_, %{{[0-9]+}}:_(s32), 64 (in function: nonpow2_or_narrowing) 102; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_or_narrowing 103; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_or_narrowing: 104define void @nonpow2_or_narrowing() { 105 %a = add i128 undef, undef 106 %b = trunc i128 %a to i96 107 %a2 = add i128 undef, undef 108 %b2 = trunc i128 %a2 to i96 109 %dummy = or i96 %b, %b2 110 store i96 %dummy, i96* undef 111 ret void 112} 113 114; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %0:_(s96) = G_INSERT %10:_, %8:_(s32), 64 (in function: nonpow2_load_narrowing) 115; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_load_narrowing 116; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_load_narrowing: 117define void @nonpow2_load_narrowing() { 118 %dummy = load i96, i96* undef 119 store i96 %dummy, i96* undef 120 ret void 121} 122 123; Currently can't handle vector lengths that aren't an exact multiple of 124; natively supported vector lengths. Test that the fall-back works for those. 125; 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 126; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %{{[0-9]+}}:_(s64) = G_EXTRACT_VECTOR_ELT %{{[0-9]+}}:_(<7 x s64>), %{{[0-9]+}}:_(s64) (in function: nonpow2_vector_add_fewerelements) 127; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for nonpow2_vector_add_fewerelements 128; FALLBACK-WITH-REPORT-OUT-LABEL: nonpow2_vector_add_fewerelements: 129define void @nonpow2_vector_add_fewerelements() { 130 %dummy = add <7 x i64> undef, undef 131 %ex = extractelement <7 x i64> %dummy, i64 0 132 store i64 %ex, i64* undef 133 ret void 134} 135 136; Currently can't handle dealing with a split type (s128 -> 2 x s64) on the stack yet. 137declare void @use_s128(i128 %a, i128 %b) 138; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower arguments: i32 (i32, i128, i32, i32, i32, i128, i32)* (in function: fn1) 139; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for fn1 140; FALLBACK-WITH-REPORT-OUT-LABEL: fn1: 141define i32 @fn1(i32 %p1, i128 %p2, i32 %p3, i32 %p4, i32 %p5, i128 %p6, i32 %p7) { 142entry: 143 call void @use_s128(i128 %p2, i128 %p6) 144 ret i32 0 145} 146 147; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: RET_ReallyLR implicit $x0 (in function: strict_align_feature) 148; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for strict_align_feature 149; FALLBACK-WITH-REPORT-OUT-LABEL: strict_align_feature 150define i64 @strict_align_feature(i64* %p) #0 { 151 %x = load i64, i64* %p, align 1 152 ret i64 %x 153} 154 155attributes #0 = { "target-features"="+strict-align" } 156 157; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: call 158; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for direct_mem 159; FALLBACK-WITH-REPORT-OUT-LABEL: direct_mem 160define void @direct_mem(i32 %x, i32 %y) { 161entry: 162 tail call void asm sideeffect "", "imr,imr,~{memory}"(i32 %x, i32 %y) 163 ret void 164} 165 166; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower function{{.*}}scalable_arg 167; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_arg 168define <vscale x 16 x i8> @scalable_arg(<vscale x 16 x i1> %pred, i8* %addr) #1 { 169 %res = call <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1> %pred, i8* %addr) 170 ret <vscale x 16 x i8> %res 171} 172 173; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower function{{.*}}scalable_ret 174; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_ret 175define <vscale x 16 x i8> @scalable_ret(i8* %addr) #1 { 176 %pred = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 0) 177 %res = call <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1> %pred, i8* %addr) 178 ret <vscale x 16 x i8> %res 179} 180 181; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction{{.*}}scalable_call 182; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_call 183define i8 @scalable_call(i8* %addr) #1 { 184 %pred = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 0) 185 %vec = call <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1> %pred, i8* %addr) 186 %res = extractelement <vscale x 16 x i8> %vec, i32 0 187 ret i8 %res 188} 189 190; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction{{.*}}scalable_alloca 191; FALLBACK-WITH-REPORT-OUT-LABEL: scalable_alloca 192define void @scalable_alloca() #1 { 193 %local0 = alloca <vscale x 16 x i8> 194 load volatile <vscale x 16 x i8>, <vscale x 16 x i8>* %local0 195 ret void 196} 197 198; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction{{.*}}asm_indirect_output 199; FALLBACK-WITH-REPORT-OUT-LABEL: asm_indirect_output 200define void @asm_indirect_output() { 201entry: 202 %ap = alloca i8*, align 8 203 %0 = load i8*, i8** %ap, align 8 204 call void asm sideeffect "", "=*r|m,0,~{memory}"(i8** %ap, i8* %0) 205 ret void 206} 207 208attributes #1 = { "target-features"="+sve" } 209 210declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 %pattern) 211declare <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1>, i8*) 212