Index: llvm/include/llvm/Target/TargetSelectionDAG.td =================================================================== --- llvm/include/llvm/Target/TargetSelectionDAG.td +++ llvm/include/llvm/Target/TargetSelectionDAG.td @@ -450,6 +450,9 @@ def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; def fround : SDNode<"ISD::FROUND" , SDTFPUnaryOp>; +def lround : SDNode<"ISD::LROUND" , SDTFPToIntOp>; +def llround : SDNode<"ISD::LLROUND" , SDTFPToIntOp>; + def fpround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; def fpextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -457,6 +457,8 @@ setOperationAction(ISD::FMAXNUM, Ty, Legal); setOperationAction(ISD::FMINIMUM, Ty, Legal); setOperationAction(ISD::FMAXIMUM, Ty, Legal); + setOperationAction(ISD::LROUND, Ty, Legal); + setOperationAction(ISD::LLROUND, Ty, Legal); } if (Subtarget->hasFullFP16()) { Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -3073,6 +3073,15 @@ defm : FPToIntegerPats; defm : FPToIntegerPats; +def : Pat<(i64 (lround f32:$Rn)), + (!cast(FCVTASUXSr) f32:$Rn)>; +def : Pat<(i64 (lround f64:$Rn)), + (!cast(FCVTASUXDr) f64:$Rn)>; +def : Pat<(i64 (llround f32:$Rn)), + (!cast(FCVTASUXSr) f32:$Rn)>; +def : Pat<(i64 (llround f64:$Rn)), + (!cast(FCVTASUXDr) f64:$Rn)>; + //===----------------------------------------------------------------------===// // Scaled integer to floating point conversion instructions. //===----------------------------------------------------------------------===// Index: llvm/test/CodeGen/AArch64/llround-conv.ll =================================================================== --- llvm/test/CodeGen/AArch64/llround-conv.ll +++ llvm/test/CodeGen/AArch64/llround-conv.ll @@ -1,7 +1,8 @@ ; RUN: llc < %s -mtriple=aarch64 -mattr=+neon | FileCheck %s ; CHECK-LABEL: testmsws: -; CHECK: bl llroundf +; CHECK: fcvtas x0, s0 +; CHECK: ret define i32 @testmsws(float %x) { entry: %0 = tail call i64 @llvm.llround.f32(float %x) @@ -10,7 +11,8 @@ } ; CHECK-LABEL: testmsxs: -; CHECK: b llroundf +; CHECK: fcvtas x0, s0 +; CHECK-NEXT: ret define i64 @testmsxs(float %x) { entry: %0 = tail call i64 @llvm.llround.f32(float %x) @@ -18,7 +20,8 @@ } ; CHECK-LABEL: testmswd: -; CHECK: bl llround +; CHECK: fcvtas x0, d0 +; CHECK: ret define i32 @testmswd(double %x) { entry: %0 = tail call i64 @llvm.llround.f64(double %x) @@ -27,7 +30,8 @@ } ; CHECK-LABEL: testmsxd: -; CHECK: b llround +; CHECK: fcvtas x0, d0 +; CHECK-NEXT: ret define i64 @testmsxd(double %x) { entry: %0 = tail call i64 @llvm.llround.f64(double %x) Index: llvm/test/CodeGen/AArch64/lround-conv.ll =================================================================== --- llvm/test/CodeGen/AArch64/lround-conv.ll +++ llvm/test/CodeGen/AArch64/lround-conv.ll @@ -1,7 +1,8 @@ ; RUN: llc < %s -mtriple=aarch64 -mattr=+neon | FileCheck %s ; CHECK-LABEL: testmsws: -; CHECK: bl lroundf +; CHECK: fcvtas x0, s0 +; CHECK: ret define i32 @testmsws(float %x) { entry: %0 = tail call i64 @llvm.lround.i64.f32(float %x) @@ -10,7 +11,8 @@ } ; CHECK-LABEL: testmsxs: -; CHECK: b lroundf +; CHECK: fcvtas x0, s0 +; CHECK-NEXT: ret define i64 @testmsxs(float %x) { entry: %0 = tail call i64 @llvm.lround.i64.f32(float %x) @@ -18,7 +20,8 @@ } ; CHECK-LABEL: testmswd: -; CHECK: bl lround +; CHECK: fcvtas x0, d0 +; CHECK: ret define i32 @testmswd(double %x) { entry: %0 = tail call i64 @llvm.lround.i64.f64(double %x) @@ -27,7 +30,8 @@ } ; CHECK-LABEL: testmsxd: -; CHECK: b lround +; CHECK: fcvtas x0, d0 +; CHECK-NEXT: ret define i64 @testmsxd(double %x) { entry: %0 = tail call i64 @llvm.lround.i64.f64(double %x)