Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
VT, Expand);
}
setOperationAction(ISD::CTPOP, GRLenVT, Legal);
setOperationAction(ISD::FCEIL, {MVT::f32, MVT::f64}, Legal);
setOperationAction(ISD::FFLOOR, {MVT::f32, MVT::f64}, Legal);
setOperationAction(ISD::FTRUNC, {MVT::f32, MVT::f64}, Legal);
setOperationAction(ISD::FROUNDEVEN, {MVT::f32, MVT::f64}, Legal);
}

// Set operations for 'LASX' feature.
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2259,6 +2259,32 @@ def : Pat<(loongarch_vfrsqrte v2f64:$src),
(VFRSQRTE_D v2f64:$src)>;
}

// Vector floating-point conversion
def : Pat<(f32 (fceil FPR32:$fj)),
(f32 (EXTRACT_SUBREG (VFRINTRP_S (VREPLVEI_W
(SUBREG_TO_REG (i64 0), FPR32:$fj, sub_32), 0)), sub_32))>;
def : Pat<(f64 (fceil FPR64:$fj)),
(f64 (EXTRACT_SUBREG (VFRINTRP_D (VREPLVEI_D
(SUBREG_TO_REG (i64 0), FPR64:$fj, sub_64), 0)), sub_64))>;
def : Pat<(f32 (ffloor FPR32:$fj)),
(f32 (EXTRACT_SUBREG (VFRINTRM_S (VREPLVEI_W
(SUBREG_TO_REG (i64 0), FPR32:$fj, sub_32), 0)), sub_32))>;
def : Pat<(f64 (ffloor FPR64:$fj)),
(f64 (EXTRACT_SUBREG (VFRINTRM_D (VREPLVEI_D
(SUBREG_TO_REG (i64 0), FPR64:$fj, sub_64), 0)), sub_64))>;
def : Pat<(f32 (ftrunc FPR32:$fj)),
(f32 (EXTRACT_SUBREG (VFRINTRZ_S (VREPLVEI_W
(SUBREG_TO_REG (i64 0), FPR32:$fj, sub_32), 0)), sub_32))>;
def : Pat<(f64 (ftrunc FPR64:$fj)),
(f64 (EXTRACT_SUBREG (VFRINTRZ_D (VREPLVEI_D
(SUBREG_TO_REG (i64 0), FPR64:$fj, sub_64), 0)), sub_64))>;
def : Pat<(f32 (froundeven FPR32:$fj)),
(f32 (EXTRACT_SUBREG (VFRINTRNE_S (VREPLVEI_W
(SUBREG_TO_REG (i64 0), FPR32:$fj, sub_32), 0)), sub_32))>;
def : Pat<(f64 (froundeven FPR64:$fj)),
(f64 (EXTRACT_SUBREG (VFRINTRNE_D (VREPLVEI_D
(SUBREG_TO_REG (i64 0), FPR64:$fj, sub_64), 0)), sub_64))>;

// load
def : Pat<(int_loongarch_lsx_vld GPR:$rj, timm:$imm),
(VLD GPR:$rj, (to_valid_timm timm:$imm))>;
Expand Down
156 changes: 156 additions & 0 deletions llvm/test/CodeGen/LoongArch/fp-conversion.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc --mtriple=loongarch64 --mattr=-lsx < %s | FileCheck %s --check-prefix=NOLSX
; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s --check-prefix=LSX

;; ceilf
define float @ceil_f32(float %i) nounwind {
; NOLSX-LABEL: ceil_f32:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(ceilf)
;
; LSX-LABEL: ceil_f32:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0 killed $f0 def $vr0
; LSX-NEXT: vreplvei.w $vr0, $vr0, 0
; LSX-NEXT: vfrintrp.s $vr0, $vr0
; LSX-NEXT: # kill: def $f0 killed $f0 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call float @llvm.ceil.f32(float %i)
ret float %0
}

;; ceil
define double @ceil_f64(double %i) nounwind {
; NOLSX-LABEL: ceil_f64:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(ceil)
;
; LSX-LABEL: ceil_f64:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0
; LSX-NEXT: vreplvei.d $vr0, $vr0, 0
; LSX-NEXT: vfrintrp.d $vr0, $vr0
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call double @llvm.ceil.f64(double %i)
ret double %0
}

;; floorf
define float @floor_f32(float %i) nounwind {
; NOLSX-LABEL: floor_f32:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(floorf)
;
; LSX-LABEL: floor_f32:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0 killed $f0 def $vr0
; LSX-NEXT: vreplvei.w $vr0, $vr0, 0
; LSX-NEXT: vfrintrm.s $vr0, $vr0
; LSX-NEXT: # kill: def $f0 killed $f0 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call float @llvm.floor.f32(float %i)
ret float %0
}

;; floor
define double @floor_f64(double %i) nounwind {
; NOLSX-LABEL: floor_f64:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(floor)
;
; LSX-LABEL: floor_f64:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0
; LSX-NEXT: vreplvei.d $vr0, $vr0, 0
; LSX-NEXT: vfrintrm.d $vr0, $vr0
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call double @llvm.floor.f64(double %i)
ret double %0
}

;; truncf
define float @trunc_f32(float %i) nounwind {
; NOLSX-LABEL: trunc_f32:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(truncf)
;
; LSX-LABEL: trunc_f32:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0 killed $f0 def $vr0
; LSX-NEXT: vreplvei.w $vr0, $vr0, 0
; LSX-NEXT: vfrintrz.s $vr0, $vr0
; LSX-NEXT: # kill: def $f0 killed $f0 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call float @llvm.trunc.f32(float %i)
ret float %0
}

;; trunc
define double @trunc_f64(double %i) nounwind {
; NOLSX-LABEL: trunc_f64:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(trunc)
;
; LSX-LABEL: trunc_f64:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0
; LSX-NEXT: vreplvei.d $vr0, $vr0, 0
; LSX-NEXT: vfrintrz.d $vr0, $vr0
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call double @llvm.trunc.f64(double %i)
ret double %0
}

;; roundevenf
define float @roundeven_f32(float %i) nounwind {
; NOLSX-LABEL: roundeven_f32:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(roundevenf)
;
; LSX-LABEL: roundeven_f32:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0 killed $f0 def $vr0
; LSX-NEXT: vreplvei.w $vr0, $vr0, 0
; LSX-NEXT: vfrintrne.s $vr0, $vr0
; LSX-NEXT: # kill: def $f0 killed $f0 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call float @llvm.roundeven.f32(float %i)
ret float %0
}

;; roundeven
define double @roundeven_f64(double %i) nounwind {
; NOLSX-LABEL: roundeven_f64:
; NOLSX: # %bb.0: # %entry
; NOLSX-NEXT: b %plt(roundeven)
;
; LSX-LABEL: roundeven_f64:
; LSX: # %bb.0: # %entry
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0
; LSX-NEXT: vreplvei.d $vr0, $vr0, 0
; LSX-NEXT: vfrintrne.d $vr0, $vr0
; LSX-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0
; LSX-NEXT: ret
entry:
%0 = call double @llvm.roundeven.f64(double %i)
ret double %0
}

declare float @llvm.ceil.f32(float)
declare double @llvm.ceil.f64(double)
declare float @llvm.floor.f32(float)
declare double @llvm.floor.f64(double)
declare float @llvm.trunc.f32(float)
declare double @llvm.trunc.f64(double)
declare float @llvm.roundeven.f32(float)
declare double @llvm.roundeven.f64(double)
Loading