Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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
//
Expand Down
28 changes: 28 additions & 0 deletions llvm/test/CodeGen/Hexagon/autohvx/fp-to-int_2.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; 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

; f16 -> s16
; No widening
define void @f16s16_0(ptr %a0, ptr %a1) #0 {
; CHECK-LABEL: f16s16_0:
; CHECK: {
; CHECK: [[DST:v[0-9]+]].h = [[SRC:v[0-9]+]].hf
; CHECK-NEXT: jumpr r31
; CHECK: vmem(r1+#0) = [[DST]].new
; CHECK-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
}

; Widen result #2
define void @f32s8_2(ptr %a0, ptr %a1) {
; CHECK-LABEL: f32s8_2:
; CHECK: v{{.*}}.w = v{{.*}}.sf
%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
}