Skip to content

Hexagon: sfmax/sfmin instructions are IEEE754-2019 #139056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 14, 2025
Merged
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
18 changes: 11 additions & 7 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,8 +1499,9 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
// - indexed loads and stores (pre-/post-incremented),
// - ANY_EXTEND_VECTOR_INREG, ATOMIC_CMP_SWAP_WITH_SUCCESS, CONCAT_VECTORS,
// ConstantFP, FCEIL, FCOPYSIGN, FEXP, FEXP2, FFLOOR, FGETSIGN,
// FLOG, FLOG2, FLOG10, FMAXNUM, FMINNUM, FNEARBYINT, FRINT, FROUND, TRAP,
// FTRUNC, PREFETCH, SIGN_EXTEND_VECTOR_INREG, ZERO_EXTEND_VECTOR_INREG,
// FLOG, FLOG2, FLOG10, FMAXIMUMNUM, FMINIMUMNUM, FNEARBYINT, FRINT, FROUND,
// TRAP, FTRUNC, PREFETCH, SIGN_EXTEND_VECTOR_INREG,
// ZERO_EXTEND_VECTOR_INREG,
// which default to "expand" for at least one type.

// Misc operations.
Expand Down Expand Up @@ -1638,6 +1639,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,

// Set the action for vector operations to "expand", then override it with
// either "custom" or "legal" for specific cases.
// clang-format off
static const unsigned VectExpOps[] = {
// Integer arithmetic:
ISD::ADD, ISD::SUB, ISD::MUL, ISD::SDIV, ISD::UDIV,
Expand All @@ -1652,7 +1654,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
ISD::FCOS, ISD::FPOW, ISD::FLOG, ISD::FLOG2,
ISD::FLOG10, ISD::FEXP, ISD::FEXP2, ISD::FCEIL, ISD::FTRUNC,
ISD::FRINT, ISD::FNEARBYINT, ISD::FROUND, ISD::FFLOOR,
ISD::FMINNUM, ISD::FMAXNUM, ISD::FSINCOS, ISD::FLDEXP,
ISD::FMINIMUMNUM, ISD::FMAXIMUMNUM,
ISD::FSINCOS, ISD::FLDEXP,
// Misc:
ISD::BR_CC, ISD::SELECT_CC, ISD::ConstantPool,
// Vector:
Expand All @@ -1662,6 +1665,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
ISD::CONCAT_VECTORS, ISD::VECTOR_SHUFFLE,
ISD::SPLAT_VECTOR,
};
// clang-format on

for (MVT VT : MVT::fixedlen_vector_valuetypes()) {
for (unsigned VectExpOp : VectExpOps)
Expand Down Expand Up @@ -1784,8 +1788,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FMUL, MVT::f64, Expand);
setOperationAction(ISD::FDIV, MVT::f32, Custom);

setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
setOperationAction(ISD::FMINIMUMNUM, MVT::f32, Legal);
setOperationAction(ISD::FMAXIMUMNUM, MVT::f32, Legal);

setOperationAction(ISD::FP_TO_UINT, MVT::i1, Promote);
setOperationAction(ISD::FP_TO_UINT, MVT::i8, Promote);
Expand Down Expand Up @@ -1833,8 +1837,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FSUB, MVT::f64, Legal);
}
if (Subtarget.hasV67Ops()) {
setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
setOperationAction(ISD::FMINIMUMNUM, MVT::f64, Legal);
setOperationAction(ISD::FMAXIMUMNUM, MVT::f64, Legal);
setOperationAction(ISD::FMUL, MVT::f64, Legal);
}

Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ HexagonTargetLowering::initializeHVXLowering() {
setOperationAction(ISD::FADD, T, Legal);
setOperationAction(ISD::FSUB, T, Legal);
setOperationAction(ISD::FMUL, T, Legal);
setOperationAction(ISD::FMINNUM, T, Legal);
setOperationAction(ISD::FMAXNUM, T, Legal);
setOperationAction(ISD::FMINIMUMNUM, T, Legal);
setOperationAction(ISD::FMAXIMUMNUM, T, Legal);

setOperationAction(ISD::INSERT_SUBVECTOR, T, Custom);
setOperationAction(ISD::EXTRACT_SUBVECTOR, T, Custom);
Expand Down Expand Up @@ -164,8 +164,8 @@ HexagonTargetLowering::initializeHVXLowering() {
setOperationAction(ISD::FADD, P, Custom);
setOperationAction(ISD::FSUB, P, Custom);
setOperationAction(ISD::FMUL, P, Custom);
setOperationAction(ISD::FMINNUM, P, Custom);
setOperationAction(ISD::FMAXNUM, P, Custom);
setOperationAction(ISD::FMINIMUMNUM, P, Custom);
setOperationAction(ISD::FMAXIMUMNUM, P, Custom);
setOperationAction(ISD::SETCC, P, Custom);
setOperationAction(ISD::VSELECT, P, Custom);

Expand Down Expand Up @@ -3172,8 +3172,8 @@ HexagonTargetLowering::LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::FADD:
case ISD::FSUB:
case ISD::FMUL:
case ISD::FMINNUM:
case ISD::FMAXNUM:
case ISD::FMINIMUMNUM:
case ISD::FMAXIMUMNUM:
case ISD::MULHS:
case ISD::MULHU:
case ISD::AND:
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/Hexagon/HexagonPatterns.td
Original file line number Diff line number Diff line change
Expand Up @@ -1579,8 +1579,8 @@ def: OpR_RR_pat<C2_and, Mul, v8i1, V8I1>;
def: OpR_RR_pat<F2_sfadd, pf2<fadd>, f32, F32>;
def: OpR_RR_pat<F2_sfsub, pf2<fsub>, f32, F32>;
def: OpR_RR_pat<F2_sfmpy, pf2<fmul>, f32, F32>;
def: OpR_RR_pat<F2_sfmin, pf2<fminnum>, f32, F32>;
def: OpR_RR_pat<F2_sfmax, pf2<fmaxnum>, f32, F32>;
def: OpR_RR_pat<F2_sfmin, pf2<fminimumnum>, f32, F32>;
def: OpR_RR_pat<F2_sfmax, pf2<fmaximumnum>, f32, F32>;

let Predicates = [HasV66] in {
def: OpR_RR_pat<F2_dfadd, pf2<fadd>, f64, F64>;
Expand All @@ -1600,8 +1600,8 @@ let Predicates = [HasV67,UseUnsafeMath], AddedComplexity = 50 in {
def: Pat<(fmul F64:$Rs, F64:$Rt), (DfMpy $Rs, $Rt)>;
}
let Predicates = [HasV67] in {
def: OpR_RR_pat<F2_dfmin, pf2<fminnum>, f64, F64>;
def: OpR_RR_pat<F2_dfmax, pf2<fmaxnum>, f64, F64>;
def: OpR_RR_pat<F2_dfmin, pf2<fminimumnum>, f64, F64>;
def: OpR_RR_pat<F2_dfmax, pf2<fmaximumnum>, f64, F64>;

def: Pat<(fmul F64:$Rs, F64:$Rt), (DfMpy (F2_dfmpyfix $Rs, $Rt),
(F2_dfmpyfix $Rt, $Rs))>;
Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
Original file line number Diff line number Diff line change
Expand Up @@ -508,10 +508,10 @@ let Predicates = [UseHVXV68, UseHVX128B, UseHVXQFloat] in {
defm: MinMax_pats<V6_vmin_sf, V6_vmax_sf, vselect, setgt, VecQ32, HVF32>;
defm: MinMax_pats<V6_vmin_sf, V6_vmax_sf, vselect, setogt, VecQ32, HVF32>;
}
def: OpR_RR_pat<V6_vmin_hf, pf2<fminnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vmax_hf, pf2<fmaxnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vmin_sf, pf2<fminnum>, VecF32, HVF32>;
def: OpR_RR_pat<V6_vmax_sf, pf2<fmaxnum>, VecF32, HVF32>;
def: OpR_RR_pat<V6_vmin_hf, pf2<fminimumnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vmax_hf, pf2<fmaximumnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vmin_sf, pf2<fminimumnum>, VecF32, HVF32>;
def: OpR_RR_pat<V6_vmax_sf, pf2<fmaximumnum>, VecF32, HVF32>;
}

let Predicates = [UseHVXV68, UseHVX128B, UseHVXIEEEFP] in {
Expand All @@ -521,10 +521,10 @@ let Predicates = [UseHVXV68, UseHVX128B, UseHVXIEEEFP] in {
defm: MinMax_pats<V6_vfmin_sf, V6_vfmax_sf, vselect, setgt, VecQ32, HVF32>;
defm: MinMax_pats<V6_vfmin_sf, V6_vfmax_sf, vselect, setogt, VecQ32, HVF32>;
}
def: OpR_RR_pat<V6_vfmin_hf, pf2<fminnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vfmax_hf, pf2<fmaxnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vfmin_sf, pf2<fminnum>, VecF32, HVF32>;
def: OpR_RR_pat<V6_vfmax_sf, pf2<fmaxnum>, VecF32, HVF32>;
def: OpR_RR_pat<V6_vfmin_hf, pf2<fminimumnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vfmax_hf, pf2<fmaximumnum>, VecF16, HVF16>;
def: OpR_RR_pat<V6_vfmin_sf, pf2<fminimumnum>, VecF32, HVF32>;
def: OpR_RR_pat<V6_vfmax_sf, pf2<fmaximumnum>, VecF32, HVF32>;
}

let Predicates = [UseHVX] in {
Expand Down
45 changes: 41 additions & 4 deletions llvm/test/CodeGen/Hexagon/fminmax-v67.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


; CHECK-LABEL: t1
; CHECK: dfmax
; CHECK: call fmax

define dso_local double @t1(double %a, double %b) local_unnamed_addr {
entry:
Expand All @@ -11,7 +11,7 @@ entry:
}

; CHECK-LABEL: t2
; CHECK: dfmin
; CHECK: call fmin

define dso_local double @t2(double %a, double %b) local_unnamed_addr {
entry:
Expand All @@ -20,7 +20,7 @@ entry:
}

; CHECK-LABEL: t3
; CHECK: sfmax
; CHECK: call fmaxf

define dso_local float @t3(float %a, float %b) local_unnamed_addr {
entry:
Expand All @@ -29,14 +29,51 @@ entry:
}

; CHECK-LABEL: t4
; CHECK: sfmin
; CHECK: call fminf

define dso_local float @t4(float %a, float %b) local_unnamed_addr {
entry:
%0 = tail call float @llvm.minnum.f32(float %a, float %b)
ret float %0
}

; CHECK-LABEL: t1num
; CHECK: dfmax

define dso_local double @t1num(double %a, double %b) local_unnamed_addr {
entry:
%0 = tail call double @llvm.maximumnum.f64(double %a, double %b)
ret double %0
}

; CHECK-LABEL: t2num
; CHECK: dfmin

define dso_local double @t2num(double %a, double %b) local_unnamed_addr {
entry:
%0 = tail call double @llvm.minimumnum.f64(double %a, double %b)
ret double %0
}

; CHECK-LABEL: t3num
; CHECK: sfmax

define dso_local float @t3num(float %a, float %b) local_unnamed_addr {
entry:
%0 = tail call float @llvm.maximumnum.f32(float %a, float %b)
ret float %0
}

; CHECK-LABEL: t4num
; CHECK: sfmin

define dso_local float @t4num(float %a, float %b) local_unnamed_addr {
entry:
%0 = tail call float @llvm.minimumnum.f32(float %a, float %b)
ret float %0
}


declare double @llvm.minnum.f64(double, double) #1
declare double @llvm.maxnum.f64(double, double) #1
declare float @llvm.maxnum.f32(float, float) #1
Expand Down
45 changes: 39 additions & 6 deletions llvm/test/CodeGen/Hexagon/fminmax.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,55 @@
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
target triple = "hexagon"

; CHECK-LABEL: minimum
; CHECK: sfmin
define float @minimum(float %x, float %y) #0 {
; CHECK-LABEL: cfminf
; CHECK: call fminf
define float @cfminf(float %x, float %y) #0 {
entry:
%call = tail call float @fminf(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: maximum
; CHECK: sfmax
define float @maximum(float %x, float %y) #0 {
; CHECK-LABEL: cfmaxf
; CHECK: call fmaxf
define float @cfmaxf(float %x, float %y) #0 {
entry:
%call = tail call float @fmaxf(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: minnum
; CHECK: call fminf
define float @minnum(float %x, float %y) #0 {
entry:
%call = tail call float @llvm.minnum.f32(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: maxnum
; CHECK: call fmaxf
define float @maxnum(float %x, float %y) #0 {
entry:
%call = tail call float @llvm.maxnum.f32(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: minimumnum
; CHECK: sfmin
define float @minimumnum(float %x, float %y) #0 {
entry:
%call = tail call float @llvm.minimumnum.f32(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: maximumnum
; CHECK: sfmax
define float @maximumnum(float %x, float %y) #0 {
entry:
%call = tail call float @llvm.maximumnum.f32(float %x, float %y) #1
ret float %call
}


declare float @fminf(float, float) #0
declare float @fmaxf(float, float) #0

Expand Down