diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 6bee00d1ce382..fde1a6acc0fde 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -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. diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td index 525d2802daa23..25e70b4e6b35a 100644 --- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td @@ -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))>; diff --git a/llvm/test/CodeGen/LoongArch/fp-rounding.ll b/llvm/test/CodeGen/LoongArch/fp-rounding.ll index 19c4e3fb573da..2f4d4eafafe0b 100644 --- a/llvm/test/CodeGen/LoongArch/fp-rounding.ll +++ b/llvm/test/CodeGen/LoongArch/fp-rounding.ll @@ -10,7 +10,11 @@ define float @ceil_f32(float %i) nounwind { ; ; LSX-LABEL: ceil_f32: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(ceilf) +; 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 @@ -24,7 +28,11 @@ define double @ceil_f64(double %i) nounwind { ; ; LSX-LABEL: ceil_f64: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(ceil) +; 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 @@ -38,7 +46,11 @@ define float @floor_f32(float %i) nounwind { ; ; LSX-LABEL: floor_f32: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(floorf) +; 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 @@ -52,7 +64,11 @@ define double @floor_f64(double %i) nounwind { ; ; LSX-LABEL: floor_f64: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(floor) +; 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 @@ -66,7 +82,11 @@ define float @trunc_f32(float %i) nounwind { ; ; LSX-LABEL: trunc_f32: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(truncf) +; 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 @@ -80,7 +100,11 @@ define double @trunc_f64(double %i) nounwind { ; ; LSX-LABEL: trunc_f64: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(trunc) +; 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 @@ -94,7 +118,11 @@ define float @roundeven_f32(float %i) nounwind { ; ; LSX-LABEL: roundeven_f32: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(roundevenf) +; 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 @@ -108,7 +136,11 @@ define double @roundeven_f64(double %i) nounwind { ; ; LSX-LABEL: roundeven_f64: ; LSX: # %bb.0: # %entry -; LSX-NEXT: b %plt(roundeven) +; 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