[llvm] 4715e52 - [Hexagon] Add an option to use fast FP to int convert for some HVX cases (#169562)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 3 12:05:12 PST 2025
Author: Fateme Hosseini
Date: 2025-12-03T14:05:07-06:00
New Revision: 4715e525648dde9abc50dfc93fa2cd3a67708cc7
URL: https://github.com/llvm/llvm-project/commit/4715e525648dde9abc50dfc93fa2cd3a67708cc7
DIFF: https://github.com/llvm/llvm-project/commit/4715e525648dde9abc50dfc93fa2cd3a67708cc7.diff
LOG: [Hexagon] Add an option to use fast FP to int convert for some HVX cases (#169562)
Lowering several flavors of fptosi for HVX can be done faster, but
violates c/c++ convention on some arch tags. Nevertheless customers are
using direct intrinsics with "incorrect" rounding mode and want compiler
to do the same.
Default behavior is not changed.
Patch By: Fateme Hosseini
Co-authored-by: Sergei Larin <slarin at codeaurora.org>
Co-authored-by: Sergei Larin <slarin at qti.qualcomm.com>
Added:
llvm/test/CodeGen/Hexagon/autohvx/fp-to-int_2.ll
Modified:
llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
index 212a57bc7cde5..0b782d79237da 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
@@ -31,6 +31,10 @@ static cl::opt<unsigned> HvxWidenThreshold("hexagon-hvx-widen",
cl::Hidden, cl::init(16),
cl::desc("Lower threshold (in bytes) for widening to HVX vectors"));
+static cl::opt<bool>
+ EnableFpFastConvert("hexagon-fp-fast-convert", cl::Hidden, cl::init(false),
+ cl::desc("Enable FP fast conversion routine."));
+
static const MVT LegalV64[] = { MVT::v64i8, MVT::v32i16, MVT::v16i32 };
static const MVT LegalW64[] = { MVT::v128i8, MVT::v64i16, MVT::v32i32 };
static const MVT LegalV128[] = { MVT::v128i8, MVT::v64i16, MVT::v32i32 };
@@ -2970,6 +2974,32 @@ HexagonTargetLowering::ExpandHvxFpToInt(SDValue Op, SelectionDAG &DAG) const {
MVT ResTy = ty(Op);
assert(InpTy.changeTypeToInteger() == ResTy);
+ // At this point this is an experiment under a flag.
+ // In arch before V81 the rounding mode is towards nearest value.
+ // The C/C++ standard requires rounding towards zero:
+ // C (C99 and later): ISO/IEC 9899:2018 (C18), section 6.3.1.4 — "When a
+ // finite value of real floating type is converted to an integer type, the
+ // fractional part is discarded (i.e., the value is truncated toward zero)."
+ // C++: ISO/IEC 14882:2020 (C++20), section 7.3.7 — "A prvalue of a
+ // floating-point type can be converted to a prvalue of an integer type. The
+ // conversion truncates; that is, the fractional part is discarded."
+ if (InpTy == MVT::v64f16) {
+ if (Subtarget.useHVXV81Ops()) {
+ // This is c/c++ compliant
+ SDValue ConvVec =
+ getInstr(Hexagon::V6_vconv_h_hf_rnd, dl, ResTy, {Op0}, DAG);
+ return ConvVec;
+ } else if (EnableFpFastConvert) {
+ // Vd32.h=Vu32.hf same as Q6_Vh_equals_Vhf
+ SDValue ConvVec = getInstr(Hexagon::V6_vconv_h_hf, dl, ResTy, {Op0}, DAG);
+ return ConvVec;
+ }
+ } else if (EnableFpFastConvert && InpTy == MVT::v32f32) {
+ // Vd32.w=Vu32.sf same as Q6_Vw_equals_Vsf
+ SDValue ConvVec = getInstr(Hexagon::V6_vconv_w_sf, dl, ResTy, {Op0}, DAG);
+ return ConvVec;
+ }
+
// int32_t conv_f32_to_i32(uint32_t inp) {
// // s | exp8 | frac23
//
diff --git a/llvm/test/CodeGen/Hexagon/autohvx/fp-to-int_2.ll b/llvm/test/CodeGen/Hexagon/autohvx/fp-to-int_2.ll
new file mode 100644
index 0000000000000..03e484a6721a7
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/autohvx/fp-to-int_2.ll
@@ -0,0 +1,75 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=hexagon -hexagon-hvx-widen=32 -hexagon-fp-fast-convert=true -mattr=+hvxv68,+hvx-length128b,+hvx-qfloat < %s | FileCheck %s --check-prefix=CHECK-V68
+; RUN: llc -mtriple=hexagon -hexagon-hvx-widen=32 -hexagon-fp-fast-convert=true -mattr=+hvxv81,+hvx-length128b,+hvx-qfloat < %s | FileCheck %s --check-prefix=CHECK-V81
+
+; ----------------------------
+; V68 Tests
+; ----------------------------
+
+; f16 -> s16 (No widening)
+define void @f16s16_0(ptr %a0, ptr %a1) #0 {
+; CHECK-V68-LABEL: f16s16_0:
+; CHECK-V68: {
+; CHECK-V68: [[DST:v[0-9]+]].h = [[SRC:v[0-9]+]].hf
+; CHECK-V68-NEXT: jumpr r31
+; CHECK-V68: vmem(r1+#0) = [[DST]].new
+; CHECK-V68-NEXT: }
+ %v0 = load <64 x half>, ptr %a0, align 128
+ %v1 = fptosi <64 x half> %v0 to <64 x i16>
+ store <64 x i16> %v1, ptr %a1, align 128
+ ret void
+}
+
+; f32 -> s8 (Triggers V6_vconv_w_sf)
+define void @f32s8_2(ptr %a0, ptr %a1) {
+; CHECK-V68-LABEL: f32s8_2:
+; CHECK-V68: {
+; CHECK-V68: [[SRC:v[0-9]+]] = vmem(r0+#0)
+; CHECK-V68: [[SRC]].w = [[SRC]].sf
+; CHECK-V68: vpack
+; CHECK-V68: vpack
+; CHECK-V68: vpack
+; CHECK-V68: jumpr r31
+; CHECK-V68: vmem(r1+#0) = [[DST:v[0-9]+]]
+; CHECK-V68-NEXT: }
+ %v0 = load <32 x float>, ptr %a0, align 128
+ %v1 = fptosi <32 x float> %v0 to <32 x i8>
+ store <32 x i8> %v1, ptr %a1, align 128
+ ret void
+}
+
+; ----------------------------
+; V81 Tests
+; ----------------------------
+
+; f16 -> s16 with rounding (V6_vconv_h_hf_rnd)
+define void @f16s16_v81(ptr %a0, ptr %a1) {
+; CHECK-V81-LABEL: f16s16_v81:
+; CHECK-V81: {
+; CHECK-V81: [[DST:v[0-9]+]].h = [[SRC:v[0-9]+]].hf:rnd
+; CHECK-V81-NEXT: jumpr r31
+; CHECK-V81: vmem(r1+#0) = [[DST]].new
+; CHECK-V81-NEXT: }
+ %v0 = load <64 x half>, ptr %a0, align 128
+ %v1 = fptosi <64 x half> %v0 to <64 x i16>
+ store <64 x i16> %v1, ptr %a1, align 128
+ ret void
+}
+
+; f32 -> s8 with V81 (still uses V6_vconv_w_sf)
+define void @f32s8_v81(ptr %a0, ptr %a1) {
+; CHECK-V81-LABEL: f32s8_v81:
+; CHECK-V81: {
+; CHECK-V81: [[SRC:v[0-9]+]] = vmem(r0+#0)
+; CHECK-V81: [[SRC]].w = [[SRC]].sf
+; CHECK-V81: vpack
+; CHECK-V81: vpack
+; CHECK-V81: vpack
+; CHECK-V81: jumpr r31
+; CHECK-V81: vmem(r1+#0) = [[DST:v[0-9]+]]
+; CHECK-V81-NEXT: }
+ %v0 = load <32 x float>, ptr %a0, align 128
+ %v1 = fptosi <32 x float> %v0 to <32 x i8>
+ store <32 x i8> %v1, ptr %a1, align 128
+ ret void
+}
More information about the llvm-commits
mailing list