brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.0 KiB · 3ea1a01 Raw
461 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc -mattr=+neon,+fullfp16,+fprcvt -verify-machineinstrs %s -o - | FileCheck %s3; RUN: llc -mattr=+neon -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK-NO-FPRCVT4 5target triple = "aarch64-unknown-linux-gnu"6 7 8; To demonstrate what we have implemented, we'll want a scalar integer value in a SIMD/FP register.9; A common case for this setup is when using the result of an integer reduction intrinsic.10 11; SCVTF12 13define half @scvtf_f16i32(<4 x i32> %x) {14; CHECK-LABEL: scvtf_f16i32:15; CHECK:       // %bb.0:16; CHECK-NEXT:    scvtf h0, s017; CHECK-NEXT:    ret18;19; CHECK-NO-FPRCVT-LABEL: scvtf_f16i32:20; CHECK-NO-FPRCVT:       // %bb.0:21; CHECK-NO-FPRCVT-NEXT:    scvtf s0, s022; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s023; CHECK-NO-FPRCVT-NEXT:    ret24 %extract = extractelement <4 x i32> %x, i64 025 %conv = sitofp i32 %extract to half26 ret half %conv27}28 29define half @scvtf_f16i32_neg(<4 x i32> %x) {30; CHECK-LABEL: scvtf_f16i32_neg:31; CHECK:       // %bb.0:32; CHECK-NEXT:    mov w8, v0.s[1]33; CHECK-NEXT:    scvtf h0, w834; CHECK-NEXT:    ret35;36; CHECK-NO-FPRCVT-LABEL: scvtf_f16i32_neg:37; CHECK-NO-FPRCVT:       // %bb.0:38; CHECK-NO-FPRCVT-NEXT:    mov w8, v0.s[1]39; CHECK-NO-FPRCVT-NEXT:    scvtf s0, w840; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s041; CHECK-NO-FPRCVT-NEXT:    ret42 %extract = extractelement <4 x i32> %x, i64 143 %conv = sitofp i32 %extract to half44 ret half %conv45}46 47define <1 x half> @scvtf_f16i32_simple(<1 x i32> %x) {48; CHECK-LABEL: scvtf_f16i32_simple:49; CHECK:       // %bb.0:50; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q051; CHECK-NEXT:    scvtf h0, s052; CHECK-NEXT:    ret53;54; CHECK-NO-FPRCVT-LABEL: scvtf_f16i32_simple:55; CHECK-NO-FPRCVT:       // %bb.0:56; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 def $q057; CHECK-NO-FPRCVT-NEXT:    scvtf s0, s058; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s059; CHECK-NO-FPRCVT-NEXT:    ret60 %conv = sitofp <1 x i32> %x to <1 x half>61 ret <1 x half> %conv62}63 64define double @scvtf_f64i32(<4 x i32> %x) {65; CHECK-LABEL: scvtf_f64i32:66; CHECK:       // %bb.0:67; CHECK-NEXT:    scvtf d0, s068; CHECK-NEXT:    ret69;70; CHECK-NO-FPRCVT-LABEL: scvtf_f64i32:71; CHECK-NO-FPRCVT:       // %bb.0:72; CHECK-NO-FPRCVT-NEXT:    fmov w8, s073; CHECK-NO-FPRCVT-NEXT:    scvtf d0, w874; CHECK-NO-FPRCVT-NEXT:    ret75 %extract = extractelement <4 x i32> %x, i64 076 %conv = sitofp i32 %extract to double77 ret double %conv78}79 80define double @scvtf_f64i32_neg(<4 x i32> %x) {81; CHECK-LABEL: scvtf_f64i32_neg:82; CHECK:       // %bb.0:83; CHECK-NEXT:    mov w8, v0.s[1]84; CHECK-NEXT:    scvtf d0, w885; CHECK-NEXT:    ret86;87; CHECK-NO-FPRCVT-LABEL: scvtf_f64i32_neg:88; CHECK-NO-FPRCVT:       // %bb.0:89; CHECK-NO-FPRCVT-NEXT:    mov w8, v0.s[1]90; CHECK-NO-FPRCVT-NEXT:    scvtf d0, w891; CHECK-NO-FPRCVT-NEXT:    ret92 %extract = extractelement <4 x i32> %x, i64 193 %conv = sitofp i32 %extract to double94 ret double %conv95}96 97define <1 x double> @scvtf_f64i32_simple(<1 x i32> %x) {98; CHECK-LABEL: scvtf_f64i32_simple:99; CHECK:       // %bb.0:100; CHECK-NEXT:    scvtf d0, s0101; CHECK-NEXT:    ret102;103; CHECK-NO-FPRCVT-LABEL: scvtf_f64i32_simple:104; CHECK-NO-FPRCVT:       // %bb.0:105; CHECK-NO-FPRCVT-NEXT:    sshll v0.2d, v0.2s, #0106; CHECK-NO-FPRCVT-NEXT:    scvtf v0.2d, v0.2d107; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 killed $q0108; CHECK-NO-FPRCVT-NEXT:    ret109 %conv = sitofp <1 x i32> %x to <1 x double>110 ret <1 x double> %conv111}112 113define half @scvtf_f16i64(<2 x i64> %x) {114; CHECK-LABEL: scvtf_f16i64:115; CHECK:       // %bb.0:116; CHECK-NEXT:    scvtf h0, d0117; CHECK-NEXT:    ret118;119; CHECK-NO-FPRCVT-LABEL: scvtf_f16i64:120; CHECK-NO-FPRCVT:       // %bb.0:121; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0122; CHECK-NO-FPRCVT-NEXT:    scvtf s0, x8123; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0124; CHECK-NO-FPRCVT-NEXT:    ret125 %extract = extractelement <2 x i64> %x, i64 0126 %conv = sitofp i64 %extract to half127 ret half %conv128}129 130define half @scvtf_f16i64_neg(<2 x i64> %x) {131; CHECK-LABEL: scvtf_f16i64_neg:132; CHECK:       // %bb.0:133; CHECK-NEXT:    mov x8, v0.d[1]134; CHECK-NEXT:    scvtf h0, x8135; CHECK-NEXT:    ret136;137; CHECK-NO-FPRCVT-LABEL: scvtf_f16i64_neg:138; CHECK-NO-FPRCVT:       // %bb.0:139; CHECK-NO-FPRCVT-NEXT:    mov x8, v0.d[1]140; CHECK-NO-FPRCVT-NEXT:    scvtf s0, x8141; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0142; CHECK-NO-FPRCVT-NEXT:    ret143 %extract = extractelement <2 x i64> %x, i64 1144 %conv = sitofp i64 %extract to half145 ret half %conv146}147 148define <1 x half> @scvtf_f16i64_simple(<1 x i64> %x) {149; CHECK-LABEL: scvtf_f16i64_simple:150; CHECK:       // %bb.0:151; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0152; CHECK-NEXT:    scvtf h0, d0153; CHECK-NEXT:    ret154;155; CHECK-NO-FPRCVT-LABEL: scvtf_f16i64_simple:156; CHECK-NO-FPRCVT:       // %bb.0:157; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 def $q0158; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0159; CHECK-NO-FPRCVT-NEXT:    scvtf s0, x8160; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0161; CHECK-NO-FPRCVT-NEXT:    ret162 %conv = sitofp <1 x i64> %x to <1 x half>163 ret <1 x half> %conv164}165 166define float @scvtf_f32i64(<2 x i64> %x) {167; CHECK-LABEL: scvtf_f32i64:168; CHECK:       // %bb.0:169; CHECK-NEXT:    scvtf s0, d0170; CHECK-NEXT:    ret171;172; CHECK-NO-FPRCVT-LABEL: scvtf_f32i64:173; CHECK-NO-FPRCVT:       // %bb.0:174; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0175; CHECK-NO-FPRCVT-NEXT:    scvtf s0, x8176; CHECK-NO-FPRCVT-NEXT:    ret177 %extract = extractelement <2 x i64> %x, i64 0178 %conv = sitofp i64 %extract to float179 ret float %conv180}181 182define float @scvtf_f32i64_neg(<2 x i64> %x) {183; CHECK-LABEL: scvtf_f32i64_neg:184; CHECK:       // %bb.0:185; CHECK-NEXT:    mov x8, v0.d[1]186; CHECK-NEXT:    scvtf s0, x8187; CHECK-NEXT:    ret188;189; CHECK-NO-FPRCVT-LABEL: scvtf_f32i64_neg:190; CHECK-NO-FPRCVT:       // %bb.0:191; CHECK-NO-FPRCVT-NEXT:    mov x8, v0.d[1]192; CHECK-NO-FPRCVT-NEXT:    scvtf s0, x8193; CHECK-NO-FPRCVT-NEXT:    ret194 %extract = extractelement <2 x i64> %x, i64 1195 %conv = sitofp i64 %extract to float196 ret float %conv197}198 199; This test does not give the indended result of scvtf s0, d0200; This is due to the input being loaded as a 2 item vector and201; therefore using vector inputs that do not match the pattern202; This test will be fixed in a future revision203define <1 x float> @scvtf_f32i64_simple(<1 x i64> %x) {204; CHECK-LABEL: scvtf_f32i64_simple:205; CHECK:       // %bb.0:206; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0207; CHECK-NEXT:    movi d1, #0000000000000000208; CHECK-NEXT:    scvtf s0, d0209; CHECK-NEXT:    mov v1.s[0], v0.s[0]210; CHECK-NEXT:    fmov d0, d1211; CHECK-NEXT:    ret212;213; CHECK-NO-FPRCVT-LABEL: scvtf_f32i64_simple:214; CHECK-NO-FPRCVT:       // %bb.0:215; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 def $q0216; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0217; CHECK-NO-FPRCVT-NEXT:    movi d1, #0000000000000000218; CHECK-NO-FPRCVT-NEXT:    scvtf s0, x8219; CHECK-NO-FPRCVT-NEXT:    mov v1.s[0], v0.s[0]220; CHECK-NO-FPRCVT-NEXT:    fmov d0, d1221; CHECK-NO-FPRCVT-NEXT:    ret222 %conv = sitofp <1 x i64> %x to <1 x float>223 ret <1 x float> %conv224}225 226; UCVTF227 228define half @ucvtf_f16i32(<4 x i32> %x) {229; CHECK-LABEL: ucvtf_f16i32:230; CHECK:       // %bb.0:231; CHECK-NEXT:    ucvtf h0, s0232; CHECK-NEXT:    ret233;234; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i32:235; CHECK-NO-FPRCVT:       // %bb.0:236; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, s0237; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0238; CHECK-NO-FPRCVT-NEXT:    ret239 %extract = extractelement <4 x i32> %x, i64 0240 %conv = uitofp i32 %extract to half241 ret half %conv242}243 244define half @ucvtf_f16i32_neg(<4 x i32> %x) {245; CHECK-LABEL: ucvtf_f16i32_neg:246; CHECK:       // %bb.0:247; CHECK-NEXT:    mov w8, v0.s[1]248; CHECK-NEXT:    ucvtf h0, w8249; CHECK-NEXT:    ret250;251; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i32_neg:252; CHECK-NO-FPRCVT:       // %bb.0:253; CHECK-NO-FPRCVT-NEXT:    mov w8, v0.s[1]254; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, w8255; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0256; CHECK-NO-FPRCVT-NEXT:    ret257 %extract = extractelement <4 x i32> %x, i64 1258 %conv = uitofp i32 %extract to half259 ret half %conv260}261 262define <1 x half> @ucvtf_f16i32_simple(<1 x i32> %x) {263; CHECK-LABEL: ucvtf_f16i32_simple:264; CHECK:       // %bb.0:265; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0266; CHECK-NEXT:    ucvtf h0, s0267; CHECK-NEXT:    ret268;269; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i32_simple:270; CHECK-NO-FPRCVT:       // %bb.0:271; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 def $q0272; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, s0273; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0274; CHECK-NO-FPRCVT-NEXT:    ret275 %conv = uitofp <1 x i32> %x to <1 x half>276 ret <1 x half> %conv277}278 279define double @ucvtf_f64i32(<4 x i32> %x) {280; CHECK-LABEL: ucvtf_f64i32:281; CHECK:       // %bb.0:282; CHECK-NEXT:    ucvtf d0, s0283; CHECK-NEXT:    ret284;285; CHECK-NO-FPRCVT-LABEL: ucvtf_f64i32:286; CHECK-NO-FPRCVT:       // %bb.0:287; CHECK-NO-FPRCVT-NEXT:    fmov w8, s0288; CHECK-NO-FPRCVT-NEXT:    ucvtf d0, w8289; CHECK-NO-FPRCVT-NEXT:    ret290 %extract = extractelement <4 x i32> %x, i64 0291 %conv = uitofp i32 %extract to double292 ret double %conv293}294 295define double @ucvtf_f64i32_neg(<4 x i32> %x) {296; CHECK-LABEL: ucvtf_f64i32_neg:297; CHECK:       // %bb.0:298; CHECK-NEXT:    mov w8, v0.s[1]299; CHECK-NEXT:    ucvtf d0, w8300; CHECK-NEXT:    ret301;302; CHECK-NO-FPRCVT-LABEL: ucvtf_f64i32_neg:303; CHECK-NO-FPRCVT:       // %bb.0:304; CHECK-NO-FPRCVT-NEXT:    mov w8, v0.s[1]305; CHECK-NO-FPRCVT-NEXT:    ucvtf d0, w8306; CHECK-NO-FPRCVT-NEXT:    ret307 %extract = extractelement <4 x i32> %x, i64 1308 %conv = uitofp i32 %extract to double309 ret double %conv310}311 312define <1 x double> @ucvtf_f64i32_simple(<1 x i32> %x) {313; CHECK-LABEL: ucvtf_f64i32_simple:314; CHECK:       // %bb.0:315; CHECK-NEXT:    ucvtf d0, s0316; CHECK-NEXT:    ret317;318; CHECK-NO-FPRCVT-LABEL: ucvtf_f64i32_simple:319; CHECK-NO-FPRCVT:       // %bb.0:320; CHECK-NO-FPRCVT-NEXT:    ushll v0.2d, v0.2s, #0321; CHECK-NO-FPRCVT-NEXT:    ucvtf v0.2d, v0.2d322; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 killed $q0323; CHECK-NO-FPRCVT-NEXT:    ret324 %conv = uitofp <1 x i32> %x to <1 x double>325 ret <1 x double> %conv326}327 328define half @ucvtf_f16i64(<2 x i64> %x) {329; CHECK-LABEL: ucvtf_f16i64:330; CHECK:       // %bb.0:331; CHECK-NEXT:    ucvtf h0, d0332; CHECK-NEXT:    ret333;334; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i64:335; CHECK-NO-FPRCVT:       // %bb.0:336; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0337; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, x8338; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0339; CHECK-NO-FPRCVT-NEXT:    ret340 %extract = extractelement <2 x i64> %x, i64 0341 %conv = uitofp i64 %extract to half342 ret half %conv343}344 345define half @ucvtf_f16i64_neg(<2 x i64> %x) {346; CHECK-LABEL: ucvtf_f16i64_neg:347; CHECK:       // %bb.0:348; CHECK-NEXT:    mov x8, v0.d[1]349; CHECK-NEXT:    ucvtf h0, x8350; CHECK-NEXT:    ret351;352; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i64_neg:353; CHECK-NO-FPRCVT:       // %bb.0:354; CHECK-NO-FPRCVT-NEXT:    mov x8, v0.d[1]355; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, x8356; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0357; CHECK-NO-FPRCVT-NEXT:    ret358 %extract = extractelement <2 x i64> %x, i64 1359 %conv = uitofp i64 %extract to half360 ret half %conv361}362 363define <1 x half> @ucvtf_f16i64_simple(<1 x i64> %x) {364; CHECK-LABEL: ucvtf_f16i64_simple:365; CHECK:       // %bb.0:366; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0367; CHECK-NEXT:    ucvtf h0, d0368; CHECK-NEXT:    ret369;370; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i64_simple:371; CHECK-NO-FPRCVT:       // %bb.0:372; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 def $q0373; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0374; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, x8375; CHECK-NO-FPRCVT-NEXT:    fcvt h0, s0376; CHECK-NO-FPRCVT-NEXT:    ret377 %conv = uitofp <1 x i64> %x to <1 x half>378 ret <1 x half> %conv379}380 381define float @ucvtf_f32i64(<2 x i64> %x) {382; CHECK-LABEL: ucvtf_f32i64:383; CHECK:       // %bb.0:384; CHECK-NEXT:    ucvtf s0, d0385; CHECK-NEXT:    ret386;387; CHECK-NO-FPRCVT-LABEL: ucvtf_f32i64:388; CHECK-NO-FPRCVT:       // %bb.0:389; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0390; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, x8391; CHECK-NO-FPRCVT-NEXT:    ret392 %extract = extractelement <2 x i64> %x, i64 0393 %conv = uitofp i64 %extract to float394 ret float %conv395}396 397define float @ucvtf_f32i64_neg(<2 x i64> %x) {398; CHECK-LABEL: ucvtf_f32i64_neg:399; CHECK:       // %bb.0:400; CHECK-NEXT:    mov x8, v0.d[1]401; CHECK-NEXT:    ucvtf s0, x8402; CHECK-NEXT:    ret403;404; CHECK-NO-FPRCVT-LABEL: ucvtf_f32i64_neg:405; CHECK-NO-FPRCVT:       // %bb.0:406; CHECK-NO-FPRCVT-NEXT:    mov x8, v0.d[1]407; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, x8408; CHECK-NO-FPRCVT-NEXT:    ret409 %extract = extractelement <2 x i64> %x, i64 1410 %conv = uitofp i64 %extract to float411 ret float %conv412}413 414; This test does not give the indended result of ucvtf s0, d0415; This is due to the input being loaded as a 2 item vector and416; therefore using vector inputs that do not match the pattern417; This test will be fixed in a future revision418define <1 x float> @ucvtf_f32i64_simple(<1 x i64> %x) {419; CHECK-LABEL: ucvtf_f32i64_simple:420; CHECK:       // %bb.0:421; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0422; CHECK-NEXT:    movi d1, #0000000000000000423; CHECK-NEXT:    ucvtf s0, d0424; CHECK-NEXT:    mov v1.s[0], v0.s[0]425; CHECK-NEXT:    fmov d0, d1426; CHECK-NEXT:    ret427;428; CHECK-NO-FPRCVT-LABEL: ucvtf_f32i64_simple:429; CHECK-NO-FPRCVT:       // %bb.0:430; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 def $q0431; CHECK-NO-FPRCVT-NEXT:    fmov x8, d0432; CHECK-NO-FPRCVT-NEXT:    movi d1, #0000000000000000433; CHECK-NO-FPRCVT-NEXT:    ucvtf s0, x8434; CHECK-NO-FPRCVT-NEXT:    mov v1.s[0], v0.s[0]435; CHECK-NO-FPRCVT-NEXT:    fmov d0, d1436; CHECK-NO-FPRCVT-NEXT:    ret437 %conv = uitofp <1 x i64> %x to <1 x float>438 ret <1 x float> %conv439}440 441define <1 x double> @uitofp_sext_v2i32_extract_lane0(<2 x i32> %x) {442; CHECK-LABEL: uitofp_sext_v2i32_extract_lane0:443; CHECK:       // %bb.0:444; CHECK-NEXT:    sshll v0.2d, v0.2s, #0445; CHECK-NEXT:    ucvtf v0.2d, v0.2d446; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0447; CHECK-NEXT:    ret448;449; CHECK-NO-FPRCVT-LABEL: uitofp_sext_v2i32_extract_lane0:450; CHECK-NO-FPRCVT:       // %bb.0:451; CHECK-NO-FPRCVT-NEXT:    sshll v0.2d, v0.2s, #0452; CHECK-NO-FPRCVT-NEXT:    ucvtf v0.2d, v0.2d453; CHECK-NO-FPRCVT-NEXT:    // kill: def $d0 killed $d0 killed $q0454; CHECK-NO-FPRCVT-NEXT:    ret455  %wide  = sext <2 x i32> %x to <2 x i64>456  %fpv2  = uitofp <2 x i64> %wide to <2 x double>457  %lane0 = shufflevector <2 x double> %fpv2, <2 x double> poison, <1 x i32> zeroinitializer458  ret <1 x double> %lane0459}460 461