From 2e22177214df9d7e4181a49ef10d5a24bb050afd Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Thu, 13 Aug 2015 01:13:56 +0000 Subject: [PATCH] [AArch64] Also custom-lowering mismatched vector/f16 FCOPYSIGN. We can lower them using our cool tricks if we fpext/fptrunc the second input, like we do for f32/f64. Follow-up to r243924, r243926, and r244858. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244860 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelLowering.cpp | 16 +++----- test/CodeGen/AArch64/f16-instructions.ll | 12 ++---- test/CodeGen/AArch64/vector-fcopysign.ll | 47 ++++++---------------- 3 files changed, 21 insertions(+), 54 deletions(-) diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index df8de64090c..91a2db163f2 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3651,17 +3651,11 @@ SDValue AArch64TargetLowering::LowerFCOPYSIGN(SDValue Op, SDValue In1 = Op.getOperand(0); SDValue In2 = Op.getOperand(1); EVT SrcVT = In2.getValueType(); - if (SrcVT != VT) { - if (SrcVT == MVT::f32 && VT == MVT::f64) - In2 = DAG.getNode(ISD::FP_EXTEND, DL, VT, In2); - else if (SrcVT == MVT::f64 && VT == MVT::f32) - In2 = DAG.getNode(ISD::FP_ROUND, DL, VT, In2, - DAG.getIntPtrConstant(0, DL)); - else - // FIXME: Src type is different, bail out for now. Can VT really be a - // vector type? - return SDValue(); - } + + if (SrcVT.bitsLT(VT)) + In2 = DAG.getNode(ISD::FP_EXTEND, DL, VT, In2); + else if (SrcVT.bitsGT(VT)) + In2 = DAG.getNode(ISD::FP_ROUND, DL, VT, In2, DAG.getIntPtrConstant(0, DL)); EVT VecVT; EVT EltVT; diff --git a/test/CodeGen/AArch64/f16-instructions.ll b/test/CodeGen/AArch64/f16-instructions.ll index 26fc3a9ae24..99dc8e33014 100644 --- a/test/CodeGen/AArch64/f16-instructions.ll +++ b/test/CodeGen/AArch64/f16-instructions.ll @@ -666,17 +666,11 @@ define half @test_maxnum(half %a, half %b) #0 { } ; CHECK-LABEL: test_copysign: -; CHECK-NEXT: sub sp, sp, #16 -; CHECK-NEXT: str h1, [sp, #8] -; CHECK-NEXT: ldr x8, [sp, #8] +; CHECK-NEXT: fcvt s1, h1 ; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: fabs s0, s0 -; CHECK-NEXT: fneg s1, s0 -; CHECK-NEXT: lsl x8, x8, #48 -; CHECK-NEXT: cmp x8, #0 -; CHECK-NEXT: fcsel s0, s1, s0, lt +; CHECK-NEXT: movi.4s v2, #0x80, lsl #24 +; CHECK-NEXT: bit.16b v0, v1, v2 ; CHECK-NEXT: fcvt h0, s0 -; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: ret define half @test_copysign(half %a, half %b) #0 { %r = call half @llvm.copysign.f16(half %a, half %b) diff --git a/test/CodeGen/AArch64/vector-fcopysign.ll b/test/CodeGen/AArch64/vector-fcopysign.ll index f3e2827ce65..cf6e6017eaa 100644 --- a/test/CodeGen/AArch64/vector-fcopysign.ll +++ b/test/CodeGen/AArch64/vector-fcopysign.ll @@ -74,14 +74,9 @@ define <2 x float> @test_copysign_v2f32_v2f32(<2 x float> %a, <2 x float> %b) #0 define <2 x float> @test_copysign_v2f32_v2f64(<2 x float> %a, <2 x double> %b) #0 { ; CHECK-LABEL: test_copysign_v2f32_v2f64: ; CHECK: ; BB#0: -; CHECK-NEXT: mov d2, v1[1] -; CHECK-NEXT: mov s3, v0[1] -; CHECK-NEXT: movi.4s v4, #0x80, lsl #24 -; CHECK-NEXT: fcvt s1, d1 -; CHECK-NEXT: fcvt s2, d2 -; CHECK-NEXT: bit.16b v3, v2, v4 -; CHECK-NEXT: bit.16b v0, v1, v4 -; CHECK-NEXT: ins.s v0[1], v3[0] +; CHECK-NEXT: fcvtn v1.2s, v1.2d +; CHECK-NEXT: movi.2s v2, #0x80, lsl #24 +; CHECK-NEXT: bit.8b v0, v1, v2 ; CHECK-NEXT: ret %tmp0 = fptrunc <2 x double> %b to <2 x float> %r = call <2 x float> @llvm.copysign.v2f32(<2 x float> %a, <2 x float> %tmp0) @@ -136,15 +131,10 @@ declare <4 x float> @llvm.copysign.v4f32(<4 x float> %a, <4 x float> %b) #0 define <2 x double> @test_copysign_v2f64_v232(<2 x double> %a, <2 x float> %b) #0 { ; CHECK-LABEL: test_copysign_v2f64_v232: ; CHECK: ; BB#0: -; CHECK-NEXT: mov d2, v0[1] -; CHECK-NEXT: mov s3, v1[1] -; CHECK-NEXT: movi.2d v4, #0000000000000000 -; CHECK-NEXT: fcvt d1, s1 -; CHECK-NEXT: fcvt d3, s3 -; CHECK-NEXT: fneg.2d v4, v4 -; CHECK-NEXT: bit.16b v2, v3, v4 -; CHECK-NEXT: bit.16b v0, v1, v4 -; CHECK-NEXT: ins.d v0[1], v2[0] +; CHECK-NEXT: movi.2d v2, #0000000000000000 +; CHECK-NEXT: fneg.2d v2, v2 +; CHECK-NEXT: fcvtl v1.2d, v1.2s +; CHECK-NEXT: bit.16b v0, v1, v2 ; CHECK-NEXT: ret %tmp0 = fpext <2 x float> %b to <2 x double> %r = call <2 x double> @llvm.copysign.v2f64(<2 x double> %a, <2 x double> %tmp0) @@ -170,23 +160,12 @@ declare <2 x double> @llvm.copysign.v2f64(<2 x double> %a, <2 x double> %b) #0 define <4 x double> @test_copysign_v4f64_v4f32(<4 x double> %a, <4 x float> %b) #0 { ; CHECK-LABEL: test_copysign_v4f64_v4f32: ; CHECK: ; BB#0: -; CHECK-NEXT: ext.16b v3, v2, v2, #8 -; CHECK-NEXT: mov d4, v0[1] -; CHECK-NEXT: mov s5, v2[1] -; CHECK-NEXT: movi.2d v6, #0000000000000000 -; CHECK-NEXT: fcvt d2, s2 -; CHECK-NEXT: fcvt d5, s5 -; CHECK-NEXT: fneg.2d v6, v6 -; CHECK-NEXT: bit.16b v4, v5, v6 -; CHECK-NEXT: mov d5, v1[1] -; CHECK-NEXT: bit.16b v0, v2, v6 -; CHECK-NEXT: mov s2, v3[1] -; CHECK-NEXT: fcvt d3, s3 -; CHECK-NEXT: fcvt d2, s2 -; CHECK-NEXT: ins.d v0[1], v4[0] -; CHECK-NEXT: bit.16b v5, v2, v6 -; CHECK-NEXT: bit.16b v1, v3, v6 -; CHECK-NEXT: ins.d v1[1], v5[0] +; CHECK-NEXT: movi.2d v3, #0000000000000000 +; CHECK-NEXT: fcvtl2 v4.2d, v2.4s +; CHECK-NEXT: fcvtl v2.2d, v2.2s +; CHECK-NEXT: fneg.2d v3, v3 +; CHECK-NEXT: bit.16b v1, v4, v3 +; CHECK-NEXT: bit.16b v0, v2, v3 ; CHECK-NEXT: ret %tmp0 = fpext <4 x float> %b to <4 x double> %r = call <4 x double> @llvm.copysign.v4f64(<4 x double> %a, <4 x double> %tmp0) -- 2.34.1