https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/142559
This marks ffloor as legal providing that armv8 and neon is present (or fullfp16 for the fp16 instructions). The existing arm_neon_vrintm intrinsics are auto-upgraded to llvm.floor. If this is OK I will update the other vrint intrinsics. >From f32daa597fec9253c673629282ac3a6b53868b1e Mon Sep 17 00:00:00 2001 From: David Green <david.gr...@arm.com> Date: Tue, 3 Jun 2025 09:11:06 +0100 Subject: [PATCH] [ARM] Add neon vector support for floor This marks ffloor as legal providing that armv8 and neon is present (or fullfp16 for the fp16 instructions). The existing arm_neon_vrintm intrinsics are auto-upgraded to llvm.floor. --- clang/lib/CodeGen/TargetBuiltins/ARM.cpp | 4 +- .../test/CodeGen/arm-neon-directed-rounding.c | 4 +- .../test/CodeGen/arm-v8.2a-neon-intrinsics.c | 4 +- llvm/include/llvm/IR/IntrinsicsARM.td | 1 - llvm/lib/IR/AutoUpgrade.cpp | 1 + llvm/lib/Target/ARM/ARMISelLowering.cpp | 8 +++ llvm/lib/Target/ARM/ARMInstrNEON.td | 2 +- llvm/test/CodeGen/ARM/vrint.ll | 56 ++----------------- 8 files changed, 20 insertions(+), 60 deletions(-) diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp index 1cf8f6819b75a..e0bc2fb144e04 100644 --- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp @@ -843,8 +843,8 @@ static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType), NEONMAP0(vrndi_v), NEONMAP0(vrndiq_v), - NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType), - NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType), + NEONMAP1(vrndm_v, floor, Add1ArgType), + NEONMAP1(vrndmq_v, floor, Add1ArgType), NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType), NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType), NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType), diff --git a/clang/test/CodeGen/arm-neon-directed-rounding.c b/clang/test/CodeGen/arm-neon-directed-rounding.c index be587ea8e697a..6ef05544667b2 100644 --- a/clang/test/CodeGen/arm-neon-directed-rounding.c +++ b/clang/test/CodeGen/arm-neon-directed-rounding.c @@ -66,7 +66,7 @@ float32x4_t test_vrndaq_f32(float32x4_t a) { // CHECK-A32-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[A]] to <2 x i32> // CHECK-A32-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[TMP0]] to <8 x i8> // CHECK-A32-NEXT: [[VRNDM_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <2 x float> -// CHECK-A32-NEXT: [[VRNDM_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrintm.v2f32(<2 x float> [[VRNDM_V_I]]) +// CHECK-A32-NEXT: [[VRNDM_V1_I:%.*]] = call <2 x float> @llvm.floor.v2f32(<2 x float> [[VRNDM_V_I]]) // CHECK-A32-NEXT: [[VRNDM_V2_I:%.*]] = bitcast <2 x float> [[VRNDM_V1_I]] to <8 x i8> // CHECK-A32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[VRNDM_V2_I]] to <2 x i32> // CHECK-A32-NEXT: [[TMP3:%.*]] = bitcast <2 x i32> [[TMP2]] to <2 x float> @@ -91,7 +91,7 @@ float32x2_t test_vrndm_f32(float32x2_t a) { // CHECK-A32-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to <4 x i32> // CHECK-A32-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> // CHECK-A32-NEXT: [[VRNDMQ_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <4 x float> -// CHECK-A32-NEXT: [[VRNDMQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrintm.v4f32(<4 x float> [[VRNDMQ_V_I]]) +// CHECK-A32-NEXT: [[VRNDMQ_V1_I:%.*]] = call <4 x float> @llvm.floor.v4f32(<4 x float> [[VRNDMQ_V_I]]) // CHECK-A32-NEXT: [[VRNDMQ_V2_I:%.*]] = bitcast <4 x float> [[VRNDMQ_V1_I]] to <16 x i8> // CHECK-A32-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[VRNDMQ_V2_I]] to <4 x i32> // CHECK-A32-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to <4 x float> diff --git a/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c b/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c index f85deeeca757f..2ea80d5b8389b 100644 --- a/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c +++ b/clang/test/CodeGen/arm-v8.2a-neon-intrinsics.c @@ -586,7 +586,7 @@ float16x8_t test_vrndaq_f16(float16x8_t a) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[A]] to <4 x i16> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i16> [[TMP0]] to <8 x i8> // CHECK-NEXT: [[VRNDM_V_I:%.*]] = bitcast <8 x i8> [[TMP1]] to <4 x half> -// CHECK-NEXT: [[VRNDM_V1_I:%.*]] = call <4 x half> @llvm.arm.neon.vrintm.v4f16(<4 x half> [[VRNDM_V_I]]) +// CHECK-NEXT: [[VRNDM_V1_I:%.*]] = call <4 x half> @llvm.floor.v4f16(<4 x half> [[VRNDM_V_I]]) // CHECK-NEXT: [[VRNDM_V2_I:%.*]] = bitcast <4 x half> [[VRNDM_V1_I]] to <8 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[VRNDM_V2_I]] to <4 x i16> // CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i16> [[TMP2]] to <4 x half> @@ -602,7 +602,7 @@ float16x4_t test_vrndm_f16(float16x4_t a) { // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[A]] to <8 x i16> // CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[TMP0]] to <16 x i8> // CHECK-NEXT: [[VRNDMQ_V_I:%.*]] = bitcast <16 x i8> [[TMP1]] to <8 x half> -// CHECK-NEXT: [[VRNDMQ_V1_I:%.*]] = call <8 x half> @llvm.arm.neon.vrintm.v8f16(<8 x half> [[VRNDMQ_V_I]]) +// CHECK-NEXT: [[VRNDMQ_V1_I:%.*]] = call <8 x half> @llvm.floor.v8f16(<8 x half> [[VRNDMQ_V_I]]) // CHECK-NEXT: [[VRNDMQ_V2_I:%.*]] = bitcast <8 x half> [[VRNDMQ_V1_I]] to <16 x i8> // CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[VRNDMQ_V2_I]] to <8 x i16> // CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to <8 x half> diff --git a/llvm/include/llvm/IR/IntrinsicsARM.td b/llvm/include/llvm/IR/IntrinsicsARM.td index 9b7dd8099368d..a38d201cb623c 100644 --- a/llvm/include/llvm/IR/IntrinsicsARM.td +++ b/llvm/include/llvm/IR/IntrinsicsARM.td @@ -682,7 +682,6 @@ def int_arm_neon_vrintn : Neon_1FloatArg_Intrinsic; def int_arm_neon_vrintx : Neon_1Arg_Intrinsic; def int_arm_neon_vrinta : Neon_1Arg_Intrinsic; def int_arm_neon_vrintz : Neon_1Arg_Intrinsic; -def int_arm_neon_vrintm : Neon_1Arg_Intrinsic; def int_arm_neon_vrintp : Neon_1Arg_Intrinsic; // De-interleaving vector loads from N-element structures. diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 7ba6d411bc7b5..b96de6410cb13 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -719,6 +719,7 @@ static bool upgradeArmOrAarch64IntrinsicFunction(bool IsArm, Function *F, .StartsWith("vqaddu.", Intrinsic::uadd_sat) .StartsWith("vqsubs.", Intrinsic::ssub_sat) .StartsWith("vqsubu.", Intrinsic::usub_sat) + .StartsWith("vrintm.", Intrinsic::floor) .Default(Intrinsic::not_intrinsic); if (ID != Intrinsic::not_intrinsic) { NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID, diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index be4876d0667ab..d4f874e647869 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -1598,6 +1598,11 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::FMINIMUM, MVT::v4f32, Legal); setOperationAction(ISD::FMAXIMUM, MVT::v4f32, Legal); + if (Subtarget->hasV8Ops()) { + setOperationAction(ISD::FFLOOR, MVT::v2f32, Legal); + setOperationAction(ISD::FFLOOR, MVT::v4f32, Legal); + } + if (Subtarget->hasFullFP16()) { setOperationAction(ISD::FMINNUM, MVT::v4f16, Legal); setOperationAction(ISD::FMAXNUM, MVT::v4f16, Legal); @@ -1608,6 +1613,9 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::FMAXIMUM, MVT::v4f16, Legal); setOperationAction(ISD::FMINIMUM, MVT::v8f16, Legal); setOperationAction(ISD::FMAXIMUM, MVT::v8f16, Legal); + + setOperationAction(ISD::FFLOOR, MVT::v4f16, Legal); + setOperationAction(ISD::FFLOOR, MVT::v8f16, Legal); } } diff --git a/llvm/lib/Target/ARM/ARMInstrNEON.td b/llvm/lib/Target/ARM/ARMInstrNEON.td index 3335f52f15555..7e6b71501fff9 100644 --- a/llvm/lib/Target/ARM/ARMInstrNEON.td +++ b/llvm/lib/Target/ARM/ARMInstrNEON.td @@ -7316,7 +7316,7 @@ defm VRINTNN : VRINT_FPI<"n", 0b000, int_arm_neon_vrintn>; defm VRINTXN : VRINT_FPI<"x", 0b001, int_arm_neon_vrintx>; defm VRINTAN : VRINT_FPI<"a", 0b010, int_arm_neon_vrinta>; defm VRINTZN : VRINT_FPI<"z", 0b011, int_arm_neon_vrintz>; -defm VRINTMN : VRINT_FPI<"m", 0b101, int_arm_neon_vrintm>; +defm VRINTMN : VRINT_FPI<"m", 0b101, ffloor>; defm VRINTPN : VRINT_FPI<"p", 0b111, int_arm_neon_vrintp>; // Cryptography instructions diff --git a/llvm/test/CodeGen/ARM/vrint.ll b/llvm/test/CodeGen/ARM/vrint.ll index 2391e9499479b..6675900f4f448 100644 --- a/llvm/test/CodeGen/ARM/vrint.ll +++ b/llvm/test/CodeGen/ARM/vrint.ll @@ -813,21 +813,7 @@ define <4 x half> @frintm_4h(<4 x half> %A) nounwind { ; ; CHECK-FP16-LABEL: frintm_4h: ; CHECK-FP16: @ %bb.0: -; CHECK-FP16-NEXT: vmovx.f16 s2, s0 -; CHECK-FP16-NEXT: vrintm.f16 s2, s2 -; CHECK-FP16-NEXT: vmov r0, s2 -; CHECK-FP16-NEXT: vrintm.f16 s2, s0 -; CHECK-FP16-NEXT: vmov r1, s2 -; CHECK-FP16-NEXT: vrintm.f16 s2, s1 -; CHECK-FP16-NEXT: vmovx.f16 s0, s1 -; CHECK-FP16-NEXT: vrintm.f16 s0, s0 -; CHECK-FP16-NEXT: vmov.16 d16[0], r1 -; CHECK-FP16-NEXT: vmov.16 d16[1], r0 -; CHECK-FP16-NEXT: vmov r0, s2 -; CHECK-FP16-NEXT: vmov.16 d16[2], r0 -; CHECK-FP16-NEXT: vmov r0, s0 -; CHECK-FP16-NEXT: vmov.16 d16[3], r0 -; CHECK-FP16-NEXT: vorr d0, d16, d16 +; CHECK-FP16-NEXT: vrintm.f16 d0, d0 ; CHECK-FP16-NEXT: bx lr %tmp3 = call <4 x half> @llvm.floor.v4f16(<4 x half> %A) ret <4 x half> %tmp3 @@ -977,35 +963,7 @@ define <8 x half> @frintm_8h(<8 x half> %A) nounwind { ; ; CHECK-FP16-LABEL: frintm_8h: ; CHECK-FP16: @ %bb.0: -; CHECK-FP16-NEXT: vmovx.f16 s4, s2 -; CHECK-FP16-NEXT: vrintm.f16 s4, s4 -; CHECK-FP16-NEXT: vmov r0, s4 -; CHECK-FP16-NEXT: vrintm.f16 s4, s2 -; CHECK-FP16-NEXT: vmov r1, s4 -; CHECK-FP16-NEXT: vrintm.f16 s4, s3 -; CHECK-FP16-NEXT: vmov.16 d17[0], r1 -; CHECK-FP16-NEXT: vmov.16 d17[1], r0 -; CHECK-FP16-NEXT: vmov r0, s4 -; CHECK-FP16-NEXT: vmovx.f16 s4, s3 -; CHECK-FP16-NEXT: vrintm.f16 s4, s4 -; CHECK-FP16-NEXT: vmov.16 d17[2], r0 -; CHECK-FP16-NEXT: vmov r0, s4 -; CHECK-FP16-NEXT: vmovx.f16 s4, s0 -; CHECK-FP16-NEXT: vrintm.f16 s4, s4 -; CHECK-FP16-NEXT: vmov.16 d17[3], r0 -; CHECK-FP16-NEXT: vmov r0, s4 -; CHECK-FP16-NEXT: vrintm.f16 s4, s0 -; CHECK-FP16-NEXT: vmovx.f16 s0, s1 -; CHECK-FP16-NEXT: vmov r1, s4 -; CHECK-FP16-NEXT: vrintm.f16 s4, s1 -; CHECK-FP16-NEXT: vrintm.f16 s0, s0 -; CHECK-FP16-NEXT: vmov.16 d16[0], r1 -; CHECK-FP16-NEXT: vmov.16 d16[1], r0 -; CHECK-FP16-NEXT: vmov r0, s4 -; CHECK-FP16-NEXT: vmov.16 d16[2], r0 -; CHECK-FP16-NEXT: vmov r0, s0 -; CHECK-FP16-NEXT: vmov.16 d16[3], r0 -; CHECK-FP16-NEXT: vorr q0, q8, q8 +; CHECK-FP16-NEXT: vrintm.f16 q0, q0 ; CHECK-FP16-NEXT: bx lr %tmp3 = call <8 x half> @llvm.floor.v8f16(<8 x half> %A) ret <8 x half> %tmp3 @@ -1031,9 +989,7 @@ define <2 x float> @frintm_2s(<2 x float> %A) nounwind { ; ; CHECK-LABEL: frintm_2s: ; CHECK: @ %bb.0: -; CHECK-NEXT: vrintm.f32 s3, s1 -; CHECK-NEXT: vrintm.f32 s2, s0 -; CHECK-NEXT: vmov.f64 d0, d1 +; CHECK-NEXT: vrintm.f32 d0, d0 ; CHECK-NEXT: bx lr %tmp3 = call <2 x float> @llvm.floor.v2f32(<2 x float> %A) ret <2 x float> %tmp3 @@ -1065,11 +1021,7 @@ define <4 x float> @frintm_4s(<4 x float> %A) nounwind { ; ; CHECK-LABEL: frintm_4s: ; CHECK: @ %bb.0: -; CHECK-NEXT: vrintm.f32 s7, s3 -; CHECK-NEXT: vrintm.f32 s6, s2 -; CHECK-NEXT: vrintm.f32 s5, s1 -; CHECK-NEXT: vrintm.f32 s4, s0 -; CHECK-NEXT: vorr q0, q1, q1 +; CHECK-NEXT: vrintm.f32 q0, q0 ; CHECK-NEXT: bx lr %tmp3 = call <4 x float> @llvm.floor.v4f32(<4 x float> %A) ret <4 x float> %tmp3 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits