334 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 42; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 < %s | FileCheck -check-prefix=NOFP16 %s3 4declare void @f16_user(half)5declare half @f16_result()6 7declare void @v2f16_user(<2 x half>)8declare <2 x half> @v2f16_result()9 10declare void @v4f16_user(<4 x half>)11declare <4 x half> @v4f16_result()12 13declare void @v8f16_user(<8 x half>)14declare <8 x half> @v8f16_result()15 16define void @f16_arg(half %arg, ptr %ptr) #0 {17; NOFP16-LABEL: f16_arg:18; NOFP16: // %bb.0:19; NOFP16-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill20; NOFP16-NEXT: .cfi_def_cfa_offset 1621; NOFP16-NEXT: .cfi_offset w19, -822; NOFP16-NEXT: .cfi_offset w30, -1623; NOFP16-NEXT: and w0, w0, #0xffff24; NOFP16-NEXT: mov x19, x125; NOFP16-NEXT: bl __extendhfsf226; NOFP16-NEXT: str w0, [x19]27; NOFP16-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload28; NOFP16-NEXT: ret29 %fpext = call float @llvm.experimental.constrained.fpext.f32.f16(half %arg, metadata !"fpexcept.strict")30 store float %fpext, ptr %ptr31 ret void32}33 34define void @v2f16_arg(<2 x half> %arg, ptr %ptr) #0 {35; NOFP16-LABEL: v2f16_arg:36; NOFP16: // %bb.0:37; NOFP16-NEXT: stp x30, x21, [sp, #-32]! // 16-byte Folded Spill38; NOFP16-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill39; NOFP16-NEXT: .cfi_def_cfa_offset 3240; NOFP16-NEXT: .cfi_offset w19, -841; NOFP16-NEXT: .cfi_offset w20, -1642; NOFP16-NEXT: .cfi_offset w21, -2443; NOFP16-NEXT: .cfi_offset w30, -3244; NOFP16-NEXT: and w0, w0, #0xffff45; NOFP16-NEXT: mov x19, x246; NOFP16-NEXT: mov w20, w147; NOFP16-NEXT: bl __extendhfsf248; NOFP16-NEXT: mov w21, w049; NOFP16-NEXT: and w0, w20, #0xffff50; NOFP16-NEXT: bl __extendhfsf251; NOFP16-NEXT: stp w21, w0, [x19]52; NOFP16-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload53; NOFP16-NEXT: ldp x30, x21, [sp], #32 // 16-byte Folded Reload54; NOFP16-NEXT: ret55 %fpext = call <2 x float> @llvm.experimental.constrained.fpext.v2f32.v2f16(<2 x half> %arg, metadata !"fpexcept.strict")56 store <2 x float> %fpext, ptr %ptr57 ret void58}59 60define void @v3f16_arg(<3 x half> %arg, ptr %ptr) #0 {61; NOFP16-LABEL: v3f16_arg:62; NOFP16: // %bb.0:63; NOFP16-NEXT: str x30, [sp, #-48]! // 8-byte Folded Spill64; NOFP16-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill65; NOFP16-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill66; NOFP16-NEXT: .cfi_def_cfa_offset 4867; NOFP16-NEXT: .cfi_offset w19, -868; NOFP16-NEXT: .cfi_offset w20, -1669; NOFP16-NEXT: .cfi_offset w21, -2470; NOFP16-NEXT: .cfi_offset w22, -3271; NOFP16-NEXT: .cfi_offset w30, -4872; NOFP16-NEXT: mov w21, w073; NOFP16-NEXT: and w0, w1, #0xffff74; NOFP16-NEXT: mov x19, x375; NOFP16-NEXT: mov w20, w276; NOFP16-NEXT: bl __extendhfsf277; NOFP16-NEXT: mov w22, w078; NOFP16-NEXT: and w0, w21, #0xffff79; NOFP16-NEXT: bl __extendhfsf280; NOFP16-NEXT: mov w8, w081; NOFP16-NEXT: and w0, w20, #0xffff82; NOFP16-NEXT: orr x21, x8, x22, lsl #3283; NOFP16-NEXT: bl __extendhfsf284; NOFP16-NEXT: str x21, [x19]85; NOFP16-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload86; NOFP16-NEXT: str w0, [x19, #8]87; NOFP16-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload88; NOFP16-NEXT: ldr x30, [sp], #48 // 8-byte Folded Reload89; NOFP16-NEXT: ret90 %fpext = call <3 x float> @llvm.experimental.constrained.fpext.v3f32.v3f16(<3 x half> %arg, metadata !"fpexcept.strict")91 store <3 x float> %fpext, ptr %ptr92 ret void93}94 95define void @v4f16_arg(<4 x half> %arg, ptr %ptr) #0 {96; NOFP16-LABEL: v4f16_arg:97; NOFP16: // %bb.0:98; NOFP16-NEXT: stp x30, x23, [sp, #-48]! // 16-byte Folded Spill99; NOFP16-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill100; NOFP16-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill101; NOFP16-NEXT: .cfi_def_cfa_offset 48102; NOFP16-NEXT: .cfi_offset w19, -8103; NOFP16-NEXT: .cfi_offset w20, -16104; NOFP16-NEXT: .cfi_offset w21, -24105; NOFP16-NEXT: .cfi_offset w22, -32106; NOFP16-NEXT: .cfi_offset w23, -40107; NOFP16-NEXT: .cfi_offset w30, -48108; NOFP16-NEXT: and w0, w0, #0xffff109; NOFP16-NEXT: mov x19, x4110; NOFP16-NEXT: mov w20, w3111; NOFP16-NEXT: mov w21, w2112; NOFP16-NEXT: mov w22, w1113; NOFP16-NEXT: bl __extendhfsf2114; NOFP16-NEXT: mov w23, w0115; NOFP16-NEXT: and w0, w22, #0xffff116; NOFP16-NEXT: bl __extendhfsf2117; NOFP16-NEXT: mov w22, w0118; NOFP16-NEXT: and w0, w21, #0xffff119; NOFP16-NEXT: bl __extendhfsf2120; NOFP16-NEXT: mov w21, w0121; NOFP16-NEXT: and w0, w20, #0xffff122; NOFP16-NEXT: bl __extendhfsf2123; NOFP16-NEXT: stp w21, w0, [x19, #8]124; NOFP16-NEXT: stp w23, w22, [x19]125; NOFP16-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload126; NOFP16-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload127; NOFP16-NEXT: ldp x30, x23, [sp], #48 // 16-byte Folded Reload128; NOFP16-NEXT: ret129 %fpext = call <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half> %arg, metadata !"fpexcept.strict")130 store <4 x float> %fpext, ptr %ptr131 ret void132}133 134 define half @f16_return(float %arg) #0 {135; NOFP16-LABEL: f16_return:136; NOFP16: // %bb.0:137; NOFP16-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill138; NOFP16-NEXT: .cfi_def_cfa_offset 16139; NOFP16-NEXT: .cfi_offset w30, -16140; NOFP16-NEXT: bl __truncsfhf2141; NOFP16-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload142; NOFP16-NEXT: ret143 %fptrunc = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %arg, metadata !"round.tonearest", metadata !"fpexcept.strict")144 ret half %fptrunc145 }146 147 define <2 x half> @v2f16_return(<2 x float> %arg) #0 {148; NOFP16-LABEL: v2f16_return:149; NOFP16: // %bb.0:150; NOFP16-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill151; NOFP16-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill152; NOFP16-NEXT: .cfi_def_cfa_offset 32153; NOFP16-NEXT: .cfi_offset w19, -8154; NOFP16-NEXT: .cfi_offset w20, -16155; NOFP16-NEXT: .cfi_offset w30, -32156; NOFP16-NEXT: mov w19, w0157; NOFP16-NEXT: mov w0, w1158; NOFP16-NEXT: bl __truncsfhf2159; NOFP16-NEXT: mov w20, w0160; NOFP16-NEXT: mov w0, w19161; NOFP16-NEXT: bl __truncsfhf2162; NOFP16-NEXT: mov w1, w20163; NOFP16-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload164; NOFP16-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload165; NOFP16-NEXT: ret166 %fptrunc = call <2 x half> @llvm.experimental.constrained.fptrunc.v2f16.v2f32(<2 x float> %arg, metadata !"round.tonearest", metadata !"fpexcept.strict")167 ret <2 x half> %fptrunc168 }169 170 define <3 x half> @v3f16_return(<3 x float> %arg) #0 {171; NOFP16-LABEL: v3f16_return:172; NOFP16: // %bb.0:173; NOFP16-NEXT: stp x30, x21, [sp, #-32]! // 16-byte Folded Spill174; NOFP16-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill175; NOFP16-NEXT: .cfi_def_cfa_offset 32176; NOFP16-NEXT: .cfi_offset w19, -8177; NOFP16-NEXT: .cfi_offset w20, -16178; NOFP16-NEXT: .cfi_offset w21, -24179; NOFP16-NEXT: .cfi_offset w30, -32180; NOFP16-NEXT: mov w20, w0181; NOFP16-NEXT: mov w0, w2182; NOFP16-NEXT: mov w19, w1183; NOFP16-NEXT: bl __truncsfhf2184; NOFP16-NEXT: mov w21, w0185; NOFP16-NEXT: mov w0, w19186; NOFP16-NEXT: bl __truncsfhf2187; NOFP16-NEXT: mov w19, w0188; NOFP16-NEXT: mov w0, w20189; NOFP16-NEXT: bl __truncsfhf2190; NOFP16-NEXT: mov w1, w19191; NOFP16-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload192; NOFP16-NEXT: mov w2, w21193; NOFP16-NEXT: ldp x30, x21, [sp], #32 // 16-byte Folded Reload194; NOFP16-NEXT: ret195 %fptrunc = call <3 x half> @llvm.experimental.constrained.fptrunc.v3f16.v3f32(<3 x float> %arg, metadata !"round.tonearest", metadata !"fpexcept.strict")196 ret <3 x half> %fptrunc197 }198 199 define <4 x half> @v4f16_return(<4 x float> %arg) #0 {200; NOFP16-LABEL: v4f16_return:201; NOFP16: // %bb.0:202; NOFP16-NEXT: str x30, [sp, #-48]! // 8-byte Folded Spill203; NOFP16-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill204; NOFP16-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill205; NOFP16-NEXT: .cfi_def_cfa_offset 48206; NOFP16-NEXT: .cfi_offset w19, -8207; NOFP16-NEXT: .cfi_offset w20, -16208; NOFP16-NEXT: .cfi_offset w21, -24209; NOFP16-NEXT: .cfi_offset w22, -32210; NOFP16-NEXT: .cfi_offset w30, -48211; NOFP16-NEXT: mov w21, w0212; NOFP16-NEXT: mov w0, w3213; NOFP16-NEXT: mov w19, w2214; NOFP16-NEXT: mov w20, w1215; NOFP16-NEXT: bl __truncsfhf2216; NOFP16-NEXT: mov w22, w0217; NOFP16-NEXT: mov w0, w19218; NOFP16-NEXT: bl __truncsfhf2219; NOFP16-NEXT: mov w19, w0220; NOFP16-NEXT: mov w0, w20221; NOFP16-NEXT: bl __truncsfhf2222; NOFP16-NEXT: mov w20, w0223; NOFP16-NEXT: mov w0, w21224; NOFP16-NEXT: bl __truncsfhf2225; NOFP16-NEXT: mov w1, w20226; NOFP16-NEXT: mov w2, w19227; NOFP16-NEXT: mov w3, w22228; NOFP16-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload229; NOFP16-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload230; NOFP16-NEXT: ldr x30, [sp], #48 // 8-byte Folded Reload231; NOFP16-NEXT: ret232 %fptrunc = call <4 x half> @llvm.experimental.constrained.fptrunc.v4f16.v4f32(<4 x float> %arg, metadata !"round.tonearest", metadata !"fpexcept.strict")233 ret <4 x half> %fptrunc234 }235 236; FIXME:237; define void @outgoing_f16_arg(ptr %ptr) #0 {238; %val = load half, ptr %ptr239; call void @f16_user(half %val)240; ret void241; }242 243; define void @outgoing_v2f16_arg(ptr %ptr) #0 {244; %val = load <2 x half>, ptr %ptr245; call void @v2f16_user(<2 x half> %val)246; ret void247; }248 249; define void @outgoing_f16_return(ptr %ptr) #0 {250; %val = call half @f16_result()251; store half %val, ptr %ptr252; ret void253; }254 255; define void @outgoing_v2f16_return(ptr %ptr) #0 {256; %val = call <2 x half> @v2f16_result()257; store <2 x half> %val, ptr %ptr258; ret void259; }260 261define void @outgoing_v4f16_return(ptr %ptr) #0 {262; NOFP16-LABEL: outgoing_v4f16_return:263; NOFP16: // %bb.0:264; NOFP16-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill265; NOFP16-NEXT: .cfi_def_cfa_offset 16266; NOFP16-NEXT: .cfi_offset w19, -8267; NOFP16-NEXT: .cfi_offset w30, -16268; NOFP16-NEXT: mov x19, x0269; NOFP16-NEXT: bl v4f16_result270; NOFP16-NEXT: strh w2, [x19, #4]271; NOFP16-NEXT: strh w3, [x19, #6]272; NOFP16-NEXT: strh w1, [x19, #2]273; NOFP16-NEXT: strh w0, [x19]274; NOFP16-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload275; NOFP16-NEXT: ret276 %val = call <4 x half> @v4f16_result() #0277 store <4 x half> %val, ptr %ptr278 ret void279}280 281define void @outgoing_v8f16_return(ptr %ptr) #0 {282; NOFP16-LABEL: outgoing_v8f16_return:283; NOFP16: // %bb.0:284; NOFP16-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill285; NOFP16-NEXT: .cfi_def_cfa_offset 16286; NOFP16-NEXT: .cfi_offset w19, -8287; NOFP16-NEXT: .cfi_offset w30, -16288; NOFP16-NEXT: mov x19, x0289; NOFP16-NEXT: bl v8f16_result290; NOFP16-NEXT: strh w5, [x19, #10]291; NOFP16-NEXT: strh w7, [x19, #14]292; NOFP16-NEXT: strh w6, [x19, #12]293; NOFP16-NEXT: strh w4, [x19, #8]294; NOFP16-NEXT: strh w3, [x19, #6]295; NOFP16-NEXT: strh w2, [x19, #4]296; NOFP16-NEXT: strh w1, [x19, #2]297; NOFP16-NEXT: strh w0, [x19]298; NOFP16-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload299; NOFP16-NEXT: ret300 %val = call <8 x half> @v8f16_result() #0301 store <8 x half> %val, ptr %ptr302 ret void303}304 305define half @call_split_type_used_outside_block_v8f16() #0 {306; NOFP16-LABEL: call_split_type_used_outside_block_v8f16:307; NOFP16: // %bb.0: // %bb0308; NOFP16-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill309; NOFP16-NEXT: .cfi_def_cfa_offset 16310; NOFP16-NEXT: .cfi_offset w30, -16311; NOFP16-NEXT: bl v8f16_result312; NOFP16-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload313; NOFP16-NEXT: ret314bb0:315 %split.ret.type = call <8 x half> @v8f16_result() #0316 br label %bb1317 318bb1:319 %extract = extractelement <8 x half> %split.ret.type, i32 0320 ret half %extract321}322 323declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata) #0324declare <2 x float> @llvm.experimental.constrained.fpext.v2f32.v2f16(<2 x half>, metadata) #0325declare <3 x float> @llvm.experimental.constrained.fpext.v3f32.v3f16(<3 x half>, metadata) #0326declare <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half>, metadata) #0327 328declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata) #0329declare <2 x half> @llvm.experimental.constrained.fptrunc.v2f16.v2f32(<2 x float>, metadata, metadata) #0330declare <3 x half> @llvm.experimental.constrained.fptrunc.v3f16.v3f32(<3 x float>, metadata, metadata) #0331declare <4 x half> @llvm.experimental.constrained.fptrunc.v4f16.v4f32(<4 x float>, metadata, metadata) #0332 333attributes #0 = { strictfp }334