From 63779461f28cda3de9161308f89ee1f409a5434d Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Wed, 29 Oct 2025 11:48:30 +0000 Subject: [PATCH 1/7] [AArch64][GlobalISel] SIMD fpcvt codegen for rounding nodes --- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 73 +++ .../AArch64/GISel/AArch64RegisterBankInfo.cpp | 18 +- .../AArch64/GlobalISel/regbank-llround.mir | 4 +- .../AArch64/GlobalISel/regbank-lround.mir | 4 +- .../AArch64/arm64-cvt-simd-round-rint.ll | 428 ++++++++++++++++++ llvm/test/CodeGen/AArch64/vector-lrint.ll | 18 +- 6 files changed, 522 insertions(+), 23 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index b9e299ef37454..f765c6e037176 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -6799,6 +6799,79 @@ defm : FPToIntegerPats; defm : FPToIntegerPats; +// For global-isel we can use register classes to determine +// which FCVT instruction to use. +let Predicates = [HasFPRCVT] in { +def : Pat<(i64 (any_lround f32:$Rn)), + (FCVTASDSr f32:$Rn)>; +def : Pat<(i64 (any_llround f32:$Rn)), + (FCVTASDSr f32:$Rn)>; +} +def : Pat<(i64 (any_lround f64:$Rn)), + (FCVTASv1i64 f64:$Rn)>; +def : Pat<(i64 (any_llround f64:$Rn)), + (FCVTASv1i64 f64:$Rn)>; + +let Predicates = [HasFPRCVT] in { + def : Pat<(f32 (bitconvert (i32 (any_lround f16:$Rn)))), + (FCVTASSHr f16:$Rn)>; + def : Pat<(f64 (bitconvert (i64 (any_lround f16:$Rn)))), + (FCVTASDHr f16:$Rn)>; + def : Pat<(f64 (bitconvert (i64 (any_llround f16:$Rn)))), + (FCVTASDHr f16:$Rn)>; + def : Pat<(f64 (bitconvert (i64 (any_lround f32:$Rn)))), + (FCVTASDSr f32:$Rn)>; + def : Pat<(f32 (bitconvert (i32 (any_lround f64:$Rn)))), + (FCVTASSDr f64:$Rn)>; + def : Pat<(f64 (bitconvert (i64 (any_llround f32:$Rn)))), + (FCVTASDSr f32:$Rn)>; +} +def : Pat<(f32 (bitconvert (i32 (any_lround f32:$Rn)))), + (FCVTASv1i32 f32:$Rn)>; +def : Pat<(f64 (bitconvert (i64 (any_lround f64:$Rn)))), + (FCVTASv1i64 f64:$Rn)>; +def : Pat<(f64 (bitconvert (i64 (any_llround f64:$Rn)))), + (FCVTASv1i64 f64:$Rn)>; + +// For global-isel we can use register classes to determine +// which FCVT instruction to use. +let Predicates = [HasFPRCVT] in { +def : Pat<(i64 (any_lrint f16:$Rn)), + (FCVTZSDHr (FRINTXHr f16:$Rn))>; +def : Pat<(i64 (any_llrint f16:$Rn)), + (FCVTZSDHr (FRINTXHr f16:$Rn))>; +def : Pat<(i64 (any_lrint f32:$Rn)), + (FCVTZSDSr (FRINTXSr f32:$Rn))>; +def : Pat<(i64 (any_llrint f32:$Rn)), + (FCVTZSDSr (FRINTXSr f32:$Rn))>; +} +def : Pat<(i64 (any_lrint f64:$Rn)), + (FCVTZSv1i64 (FRINTXDr f64:$Rn))>; +def : Pat<(i64 (any_llrint f64:$Rn)), + (FCVTZSv1i64 (FRINTXDr f64:$Rn))>; + +let Predicates = [HasFPRCVT] in { + def : Pat<(f32 (bitconvert (i32 (any_lrint f16:$Rn)))), + (FCVTZSSHr (FRINTXHr f16:$Rn))>; + def : Pat<(f64 (bitconvert (i64 (any_lrint f16:$Rn)))), + (FCVTZSDHr (FRINTXHr f16:$Rn))>; + def : Pat<(f64 (bitconvert (i64 (any_llrint f16:$Rn)))), + (FCVTZSDHr (FRINTXHr f16:$Rn))>; + def : Pat<(f64 (bitconvert (i64 (any_lrint f32:$Rn)))), + (FCVTZSDSr (FRINTXSr f32:$Rn))>; + def : Pat<(f32 (bitconvert (i32 (any_lrint f64:$Rn)))), + (FCVTZSSDr (FRINTXDr f64:$Rn))>; + def : Pat<(f64 (bitconvert (i64 (any_llrint f32:$Rn)))), + (FCVTZSDSr (FRINTXSr f32:$Rn))>; +} +def : Pat<(f32 (bitconvert (i32 (any_lrint f32:$Rn)))), + (FCVTZSv1i32 (FRINTXSr f32:$Rn))>; +def : Pat<(f64 (bitconvert (i64 (any_lrint f64:$Rn)))), + (FCVTZSv1i64 (FRINTXDr f64:$Rn))>; +def : Pat<(f64 (bitconvert (i64 (any_llrint f64:$Rn)))), + (FCVTZSv1i64 (FRINTXDr f64:$Rn))>; + + // f16 -> s16 conversions let Predicates = [HasFullFP16] in { def : Pat<(i16(fp_to_sint_sat_gi f16:$Rn)), (FCVTZSv1f16 f16:$Rn)>; diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp index 6d2d70511e894..8bd982898b8d6 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp @@ -858,7 +858,11 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case TargetOpcode::G_FPTOSI_SAT: case TargetOpcode::G_FPTOUI_SAT: case TargetOpcode::G_FPTOSI: - case TargetOpcode::G_FPTOUI: { + case TargetOpcode::G_FPTOUI: + case TargetOpcode::G_INTRINSIC_LRINT: + case TargetOpcode::G_INTRINSIC_LLRINT: + case TargetOpcode::G_LROUND: + case TargetOpcode::G_LLROUND: { LLT DstType = MRI.getType(MI.getOperand(0).getReg()); if (DstType.isVector()) break; @@ -879,12 +883,6 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR}; break; } - case TargetOpcode::G_INTRINSIC_LRINT: - case TargetOpcode::G_INTRINSIC_LLRINT: - if (MRI.getType(MI.getOperand(0).getReg()).isVector()) - break; - OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR}; - break; case TargetOpcode::G_FCMP: { // If the result is a vector, it must use a FPR. AArch64GenRegisterBankInfo::PartialMappingIdx Idx0 = @@ -1224,12 +1222,6 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { } break; } - case TargetOpcode::G_LROUND: - case TargetOpcode::G_LLROUND: { - // Source is always floating point and destination is always integer. - OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR}; - break; - } } // Finally construct the computed mapping. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir index 420c7cfb07b74..16100f01017a6 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir @@ -14,7 +14,7 @@ body: | ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %fpr:fpr(s64) = COPY $d0 - ; CHECK-NEXT: %llround:gpr(s64) = G_LLROUND %fpr(s64) + ; CHECK-NEXT: %llround:fpr(s64) = G_LLROUND %fpr(s64) ; CHECK-NEXT: $d0 = COPY %llround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %fpr:_(s64) = COPY $d0 @@ -35,7 +35,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %gpr:gpr(s64) = COPY $x0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr(s64) = COPY %gpr(s64) - ; CHECK-NEXT: %llround:gpr(s64) = G_LLROUND [[COPY]](s64) + ; CHECK-NEXT: %llround:fpr(s64) = G_LLROUND [[COPY]](s64) ; CHECK-NEXT: $d0 = COPY %llround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %gpr:_(s64) = COPY $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir index 775c6ca773c68..5cb93f7c4646d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir @@ -14,7 +14,7 @@ body: | ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %fpr:fpr(s64) = COPY $d0 - ; CHECK-NEXT: %lround:gpr(s64) = G_LROUND %fpr(s64) + ; CHECK-NEXT: %lround:fpr(s64) = G_LROUND %fpr(s64) ; CHECK-NEXT: $d0 = COPY %lround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %fpr:_(s64) = COPY $d0 @@ -35,7 +35,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %gpr:gpr(s64) = COPY $x0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr(s64) = COPY %gpr(s64) - ; CHECK-NEXT: %lround:gpr(s64) = G_LROUND [[COPY]](s64) + ; CHECK-NEXT: %lround:fpr(s64) = G_LROUND [[COPY]](s64) ; CHECK-NEXT: $d0 = COPY %lround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %gpr:_(s64) = COPY $x0 diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll new file mode 100644 index 0000000000000..000ff64131ccf --- /dev/null +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll @@ -0,0 +1,428 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SD +; RUN: llc < %s -mtriple aarch64-unknown-unknown -global-isel -global-isel-abort=2 -mattr=+fprcvt,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI + +; CHECK-GI: warning: Instruction selection used fallback path for lround_i32_f16_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f16_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f64_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f32_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f16_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f16_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f16_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f32_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f64_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f32_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f64_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f16_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f32_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f64_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f16_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f64_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f32_simd +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f16_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i64_f16_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i64_f32_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f64_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f32_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i64_f64_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llrint_i64_f16_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llrint_i64_f32_simd_exp +; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llrint_i64_f64_simd_exp + +; +; (L/LL)Round +; + +define float @lround_i32_f16_simd(half %x) { +; CHECK-LABEL: lround_i32_f16_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, h0 +; CHECK-NEXT: ret + %val = call i32 @llvm.lround.i32.f16(half %x) + %sum = bitcast i32 %val to float + ret float %sum +} + +define double @lround_i64_f16_simd(half %x) { +; CHECK-LABEL: lround_i64_f16_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.lround.i64.f16(half %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lround_i64_f32_simd(float %x) { +; CHECK-LABEL: lround_i64_f32_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.lround.i64.f32(float %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define float @lround_i32_f64_simd(double %x) { +; CHECK-LABEL: lround_i32_f64_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, d0 +; CHECK-NEXT: ret + %val = call i32 @llvm.lround.i32.f64(double %x) + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lround_i32_f32_simd(float %x) { +; CHECK-LABEL: lround_i32_f32_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, s0 +; CHECK-NEXT: ret + %val = call i32 @llvm.lround.i32.f32(float %x) + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lround_i64_f64_simd(double %x) { +; CHECK-LABEL: lround_i64_f64_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.lround.i64.f64(double %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llround_i64_f16_simd(half %x) { +; CHECK-LABEL: llround_i64_f16_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.llround.i64.f16(half %x) + %sum = bitcast i64 %val to double + ret double %sum +} + +define double @llround_i64_f32_simd(float %x) { +; CHECK-LABEL: llround_i64_f32_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.llround.i64.f32(float %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llround_i64_f64_simd(double %x) { +; CHECK-LABEL: llround_i64_f64_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.llround.i64.f64(double %x) + %bc = bitcast i64 %val to double + ret double %bc +} + + +; +; (L/LL)Round experimental +; + +define float @lround_i32_f16_simd_exp(half %x) { +; CHECK-LABEL: lround_i32_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, h0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f16(half %x, metadata !"fpexcept.strict") + %sum = bitcast i32 %val to float + ret float %sum +} + +define double @lround_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: lround_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lround.i64.f16(half %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lround_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: lround_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lround.i64.f32(float %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define float @lround_i32_f64_simd_exp(double %x) { +; CHECK-LABEL: lround_i32_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, d0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x, metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lround_i32_f32_simd_exp(float %x) { +; CHECK-LABEL: lround_i32_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, s0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x, metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lround_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: lround_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lround.i64.f64(double %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llround_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: llround_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llround.i64.f16(half %x, metadata !"fpexcept.strict") + %sum = bitcast i64 %val to double + ret double %sum +} + +define double @llround_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: llround_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llround.i64.f32(float %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llround_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: llround_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llround.i64.f64(double %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +; +; (L/LL)Rint +; + +define float @lrint_i32_f16_simd(half %x) { +; CHECK-LABEL: lrint_i32_f16_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs s0, h0 +; CHECK-NEXT: ret + %val = call i32 @llvm.lrint.i32.f16(half %x) + %sum = bitcast i32 %val to float + ret float %sum +} + +define double @lrint_i64_f16_simd(half %x) { +; CHECK-LABEL: lrint_i64_f16_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.lrint.i53.f16(half %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lrint_i64_f32_simd(float %x) { +; CHECK-LABEL: lrint_i64_f32_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.lrint.i64.f32(float %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define float @lrint_i32_f64_simd(double %x) { +; CHECK-LABEL: lrint_i32_f64_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs s0, d0 +; CHECK-NEXT: ret + %val = call i32 @llvm.lrint.i32.f64(double %x) + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lrint_i32_f32_simd(float %x) { +; CHECK-LABEL: lrint_i32_f32_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs s0, s0 +; CHECK-NEXT: ret + %val = call i32 @llvm.lrint.i32.f32(float %x) + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lrint_i64_f64_simd(double %x) { +; CHECK-LABEL: lrint_i64_f64_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.lrint.i64.f64(double %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llrint_i64_f16_simd(half %x) { +; CHECK-LABEL: llrint_i64_f16_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.llrint.i64.f16(half %x) + %sum = bitcast i64 %val to double + ret double %sum +} + +define double @llrint_i64_f32_simd(float %x) { +; CHECK-LABEL: llrint_i64_f32_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.llrint.i64.f32(float %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llrint_i64_f64_simd(double %x) { +; CHECK-LABEL: llrint_i64_f64_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.llrint.i64.f64(double %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +; +; (L/LL)Rint experimental +; + +define float @lrint_i32_f16_simd_exp(half %x) { +; CHECK-LABEL: lrint_i32_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs s0, h0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lrint.i32.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %sum = bitcast i32 %val to float + ret float %sum +} + +define double @lrint_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: lrint_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i53.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lrint_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: lrint_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define float @lrint_i32_f64_simd_exp(double %x) { +; CHECK-LABEL: lrint_i32_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs s0, d0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lrint.i32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lrint_i32_f32_simd_exp(float %x) { +; CHECK-LABEL: lrint_i32_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs s0, s0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lrint_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: lrint_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i64.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llrint_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: llrint_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llrint.i64.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %sum = bitcast i64 %val to double + ret double %sum +} + +define double @llrint_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: llrint_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llrint_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: llrint_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llrint.i64.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK-GI: {{.*}} +; CHECK-SD: {{.*}} diff --git a/llvm/test/CodeGen/AArch64/vector-lrint.ll b/llvm/test/CodeGen/AArch64/vector-lrint.ll index 65839b21b5356..05ff166a3ec90 100644 --- a/llvm/test/CodeGen/AArch64/vector-lrint.ll +++ b/llvm/test/CodeGen/AArch64/vector-lrint.ll @@ -1005,12 +1005,18 @@ define <1 x iXLen> @lrint_v1f64(<1 x double> %x) nounwind { ; CHECK-i32-NEXT: fmov s0, w8 ; CHECK-i32-NEXT: ret ; -; CHECK-i64-LABEL: lrint_v1f64: -; CHECK-i64: // %bb.0: -; CHECK-i64-NEXT: frintx d0, d0 -; CHECK-i64-NEXT: fcvtzs x8, d0 -; CHECK-i64-NEXT: fmov d0, x8 -; CHECK-i64-NEXT: ret +; CHECK-i64-SD-LABEL: lrint_v1f64: +; CHECK-i64-SD: // %bb.0: +; CHECK-i64-SD-NEXT: frintx d0, d0 +; CHECK-i64-SD-NEXT: fcvtzs x8, d0 +; CHECK-i64-SD-NEXT: fmov d0, x8 +; CHECK-i64-SD-NEXT: ret +; +; CHECK-i64-GI-LABEL: lrint_v1f64: +; CHECK-i64-GI: // %bb.0: +; CHECK-i64-GI-NEXT: frintx d0, d0 +; CHECK-i64-GI-NEXT: fcvtzs d0, d0 +; CHECK-i64-GI-NEXT: ret %a = call <1 x iXLen> @llvm.lrint.v1iXLen.v1f64(<1 x double> %x) ret <1 x iXLen> %a } From 38217973c66464577a09b74da0d524a18deb9f93 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Thu, 20 Nov 2025 10:37:10 +0000 Subject: [PATCH 2/7] Added patterns for legalized rounding nodes --- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 4 ++ .../AArch64/arm64-cvt-simd-round-rint.ll | 52 +++++++++++-------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 05b0351823b2d..dac796c7bbe09 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -6808,6 +6808,10 @@ defm : FPToIntegerPats; +def : Pat<(i64 (any_llround f16:$Rn)), + (FCVTASDHr f16:$Rn)>; def : Pat<(i64 (any_lround f32:$Rn)), (FCVTASDSr f32:$Rn)>; def : Pat<(i64 (any_llround f32:$Rn)), diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll index 000ff64131ccf..16fd91c0dd0ab 100644 --- a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll @@ -2,12 +2,7 @@ ; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SD ; RUN: llc < %s -mtriple aarch64-unknown-unknown -global-isel -global-isel-abort=2 -mattr=+fprcvt,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI -; CHECK-GI: warning: Instruction selection used fallback path for lround_i32_f16_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f16_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f64_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f32_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f16_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f16_simd_exp +; CHECK-GI: warning: Instruction selection used fallback path for lround_i32_f16_simd_exp ; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f16_simd_exp ; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f32_simd_exp ; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f64_simd_exp @@ -34,10 +29,16 @@ ; define float @lround_i32_f16_simd(half %x) { -; CHECK-LABEL: lround_i32_f16_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, h0 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: lround_i32_f16_simd: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: fcvtas s0, h0 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: lround_i32_f16_simd: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: fcvtas x8, h0 +; CHECK-GI-NEXT: fmov s0, w8 +; CHECK-GI-NEXT: ret %val = call i32 @llvm.lround.i32.f16(half %x) %sum = bitcast i32 %val to float ret float %sum @@ -64,20 +65,32 @@ define double @lround_i64_f32_simd(float %x) { } define float @lround_i32_f64_simd(double %x) { -; CHECK-LABEL: lround_i32_f64_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, d0 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: lround_i32_f64_simd: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: fcvtas s0, d0 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: lround_i32_f64_simd: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: fcvtas x8, d0 +; CHECK-GI-NEXT: fmov s0, w8 +; CHECK-GI-NEXT: ret %val = call i32 @llvm.lround.i32.f64(double %x) %bc = bitcast i32 %val to float ret float %bc } define float @lround_i32_f32_simd(float %x) { -; CHECK-LABEL: lround_i32_f32_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, s0 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: lround_i32_f32_simd: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: fcvtas s0, s0 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: lround_i32_f32_simd: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: fcvtas x8, s0 +; CHECK-GI-NEXT: fmov s0, w8 +; CHECK-GI-NEXT: ret %val = call i32 @llvm.lround.i32.f32(float %x) %bc = bitcast i32 %val to float ret float %bc @@ -423,6 +436,3 @@ define double @llrint_i64_f64_simd_exp(double %x) { %bc = bitcast i64 %val to double ret double %bc } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK-GI: {{.*}} -; CHECK-SD: {{.*}} From 0f90db6145b1d7f83c809509dd6967ade447f770 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Mon, 1 Dec 2025 12:26:20 +0000 Subject: [PATCH 3/7] split tests --- .../AArch64/arm64-cvt-simd-round-rint.s | 456 ++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s new file mode 100644 index 0000000000000..8e2e8a39b86d6 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s @@ -0,0 +1,456 @@ + .file "arm64-cvt-simd-round-rint.ll" + .text + .globl lround_i32_f16_simd // -- Begin function lround_i32_f16_simd + .p2align 2 + .type lround_i32_f16_simd,@function +lround_i32_f16_simd: // @lround_i32_f16_simd + .cfi_startproc +// %bb.0: + fcvtas x8, h0 + fmov s0, w8 + ret +.Lfunc_end0: + .size lround_i32_f16_simd, .Lfunc_end0-lround_i32_f16_simd + .cfi_endproc + // -- End function + .globl lround_i64_f16_simd // -- Begin function lround_i64_f16_simd + .p2align 2 + .type lround_i64_f16_simd,@function +lround_i64_f16_simd: // @lround_i64_f16_simd + .cfi_startproc +// %bb.0: + fcvtas d0, h0 + ret +.Lfunc_end1: + .size lround_i64_f16_simd, .Lfunc_end1-lround_i64_f16_simd + .cfi_endproc + // -- End function + .globl lround_i64_f32_simd // -- Begin function lround_i64_f32_simd + .p2align 2 + .type lround_i64_f32_simd,@function +lround_i64_f32_simd: // @lround_i64_f32_simd + .cfi_startproc +// %bb.0: + fcvtas d0, s0 + ret +.Lfunc_end2: + .size lround_i64_f32_simd, .Lfunc_end2-lround_i64_f32_simd + .cfi_endproc + // -- End function + .globl lround_i32_f64_simd // -- Begin function lround_i32_f64_simd + .p2align 2 + .type lround_i32_f64_simd,@function +lround_i32_f64_simd: // @lround_i32_f64_simd + .cfi_startproc +// %bb.0: + fcvtas x8, d0 + fmov s0, w8 + ret +.Lfunc_end3: + .size lround_i32_f64_simd, .Lfunc_end3-lround_i32_f64_simd + .cfi_endproc + // -- End function + .globl lround_i32_f32_simd // -- Begin function lround_i32_f32_simd + .p2align 2 + .type lround_i32_f32_simd,@function +lround_i32_f32_simd: // @lround_i32_f32_simd + .cfi_startproc +// %bb.0: + fcvtas x8, s0 + fmov s0, w8 + ret +.Lfunc_end4: + .size lround_i32_f32_simd, .Lfunc_end4-lround_i32_f32_simd + .cfi_endproc + // -- End function + .globl lround_i64_f64_simd // -- Begin function lround_i64_f64_simd + .p2align 2 + .type lround_i64_f64_simd,@function +lround_i64_f64_simd: // @lround_i64_f64_simd + .cfi_startproc +// %bb.0: + fcvtas d0, d0 + ret +.Lfunc_end5: + .size lround_i64_f64_simd, .Lfunc_end5-lround_i64_f64_simd + .cfi_endproc + // -- End function + .globl llround_i64_f16_simd // -- Begin function llround_i64_f16_simd + .p2align 2 + .type llround_i64_f16_simd,@function +llround_i64_f16_simd: // @llround_i64_f16_simd + .cfi_startproc +// %bb.0: + fcvtas d0, h0 + ret +.Lfunc_end6: + .size llround_i64_f16_simd, .Lfunc_end6-llround_i64_f16_simd + .cfi_endproc + // -- End function + .globl llround_i64_f32_simd // -- Begin function llround_i64_f32_simd + .p2align 2 + .type llround_i64_f32_simd,@function +llround_i64_f32_simd: // @llround_i64_f32_simd + .cfi_startproc +// %bb.0: + fcvtas d0, s0 + ret +.Lfunc_end7: + .size llround_i64_f32_simd, .Lfunc_end7-llround_i64_f32_simd + .cfi_endproc + // -- End function + .globl llround_i64_f64_simd // -- Begin function llround_i64_f64_simd + .p2align 2 + .type llround_i64_f64_simd,@function +llround_i64_f64_simd: // @llround_i64_f64_simd + .cfi_startproc +// %bb.0: + fcvtas d0, d0 + ret +.Lfunc_end8: + .size llround_i64_f64_simd, .Lfunc_end8-llround_i64_f64_simd + .cfi_endproc + // -- End function + .globl lround_i32_f16_simd_exp // -- Begin function lround_i32_f16_simd_exp + .p2align 2 + .type lround_i32_f16_simd_exp,@function +lround_i32_f16_simd_exp: // @lround_i32_f16_simd_exp + .cfi_startproc +// %bb.0: + fcvtas s0, h0 + ret +.Lfunc_end9: + .size lround_i32_f16_simd_exp, .Lfunc_end9-lround_i32_f16_simd_exp + .cfi_endproc + // -- End function + .globl lround_i64_f16_simd_exp // -- Begin function lround_i64_f16_simd_exp + .p2align 2 + .type lround_i64_f16_simd_exp,@function +lround_i64_f16_simd_exp: // @lround_i64_f16_simd_exp + .cfi_startproc +// %bb.0: + fcvtas d0, h0 + ret +.Lfunc_end10: + .size lround_i64_f16_simd_exp, .Lfunc_end10-lround_i64_f16_simd_exp + .cfi_endproc + // -- End function + .globl lround_i64_f32_simd_exp // -- Begin function lround_i64_f32_simd_exp + .p2align 2 + .type lround_i64_f32_simd_exp,@function +lround_i64_f32_simd_exp: // @lround_i64_f32_simd_exp + .cfi_startproc +// %bb.0: + fcvtas d0, s0 + ret +.Lfunc_end11: + .size lround_i64_f32_simd_exp, .Lfunc_end11-lround_i64_f32_simd_exp + .cfi_endproc + // -- End function + .globl lround_i32_f64_simd_exp // -- Begin function lround_i32_f64_simd_exp + .p2align 2 + .type lround_i32_f64_simd_exp,@function +lround_i32_f64_simd_exp: // @lround_i32_f64_simd_exp + .cfi_startproc +// %bb.0: + fcvtas s0, d0 + ret +.Lfunc_end12: + .size lround_i32_f64_simd_exp, .Lfunc_end12-lround_i32_f64_simd_exp + .cfi_endproc + // -- End function + .globl lround_i32_f32_simd_exp // -- Begin function lround_i32_f32_simd_exp + .p2align 2 + .type lround_i32_f32_simd_exp,@function +lround_i32_f32_simd_exp: // @lround_i32_f32_simd_exp + .cfi_startproc +// %bb.0: + fcvtas s0, s0 + ret +.Lfunc_end13: + .size lround_i32_f32_simd_exp, .Lfunc_end13-lround_i32_f32_simd_exp + .cfi_endproc + // -- End function + .globl lround_i64_f64_simd_exp // -- Begin function lround_i64_f64_simd_exp + .p2align 2 + .type lround_i64_f64_simd_exp,@function +lround_i64_f64_simd_exp: // @lround_i64_f64_simd_exp + .cfi_startproc +// %bb.0: + fcvtas d0, d0 + ret +.Lfunc_end14: + .size lround_i64_f64_simd_exp, .Lfunc_end14-lround_i64_f64_simd_exp + .cfi_endproc + // -- End function + .globl llround_i64_f16_simd_exp // -- Begin function llround_i64_f16_simd_exp + .p2align 2 + .type llround_i64_f16_simd_exp,@function +llround_i64_f16_simd_exp: // @llround_i64_f16_simd_exp + .cfi_startproc +// %bb.0: + fcvtas d0, h0 + ret +.Lfunc_end15: + .size llround_i64_f16_simd_exp, .Lfunc_end15-llround_i64_f16_simd_exp + .cfi_endproc + // -- End function + .globl llround_i64_f32_simd_exp // -- Begin function llround_i64_f32_simd_exp + .p2align 2 + .type llround_i64_f32_simd_exp,@function +llround_i64_f32_simd_exp: // @llround_i64_f32_simd_exp + .cfi_startproc +// %bb.0: + fcvtas d0, s0 + ret +.Lfunc_end16: + .size llround_i64_f32_simd_exp, .Lfunc_end16-llround_i64_f32_simd_exp + .cfi_endproc + // -- End function + .globl llround_i64_f64_simd_exp // -- Begin function llround_i64_f64_simd_exp + .p2align 2 + .type llround_i64_f64_simd_exp,@function +llround_i64_f64_simd_exp: // @llround_i64_f64_simd_exp + .cfi_startproc +// %bb.0: + fcvtas d0, d0 + ret +.Lfunc_end17: + .size llround_i64_f64_simd_exp, .Lfunc_end17-llround_i64_f64_simd_exp + .cfi_endproc + // -- End function + .globl lrint_i32_f16_simd // -- Begin function lrint_i32_f16_simd + .p2align 2 + .type lrint_i32_f16_simd,@function +lrint_i32_f16_simd: // @lrint_i32_f16_simd + .cfi_startproc +// %bb.0: + frintx h0, h0 + fcvtzs s0, h0 + ret +.Lfunc_end18: + .size lrint_i32_f16_simd, .Lfunc_end18-lrint_i32_f16_simd + .cfi_endproc + // -- End function + .globl lrint_i64_f16_simd // -- Begin function lrint_i64_f16_simd + .p2align 2 + .type lrint_i64_f16_simd,@function +lrint_i64_f16_simd: // @lrint_i64_f16_simd + .cfi_startproc +// %bb.0: + frintx h0, h0 + fcvtzs d0, h0 + ret +.Lfunc_end19: + .size lrint_i64_f16_simd, .Lfunc_end19-lrint_i64_f16_simd + .cfi_endproc + // -- End function + .globl lrint_i64_f32_simd // -- Begin function lrint_i64_f32_simd + .p2align 2 + .type lrint_i64_f32_simd,@function +lrint_i64_f32_simd: // @lrint_i64_f32_simd + .cfi_startproc +// %bb.0: + frintx s0, s0 + fcvtzs d0, s0 + ret +.Lfunc_end20: + .size lrint_i64_f32_simd, .Lfunc_end20-lrint_i64_f32_simd + .cfi_endproc + // -- End function + .globl lrint_i32_f64_simd // -- Begin function lrint_i32_f64_simd + .p2align 2 + .type lrint_i32_f64_simd,@function +lrint_i32_f64_simd: // @lrint_i32_f64_simd + .cfi_startproc +// %bb.0: + frintx d0, d0 + fcvtzs s0, d0 + ret +.Lfunc_end21: + .size lrint_i32_f64_simd, .Lfunc_end21-lrint_i32_f64_simd + .cfi_endproc + // -- End function + .globl lrint_i32_f32_simd // -- Begin function lrint_i32_f32_simd + .p2align 2 + .type lrint_i32_f32_simd,@function +lrint_i32_f32_simd: // @lrint_i32_f32_simd + .cfi_startproc +// %bb.0: + frintx s0, s0 + fcvtzs s0, s0 + ret +.Lfunc_end22: + .size lrint_i32_f32_simd, .Lfunc_end22-lrint_i32_f32_simd + .cfi_endproc + // -- End function + .globl lrint_i64_f64_simd // -- Begin function lrint_i64_f64_simd + .p2align 2 + .type lrint_i64_f64_simd,@function +lrint_i64_f64_simd: // @lrint_i64_f64_simd + .cfi_startproc +// %bb.0: + frintx d0, d0 + fcvtzs d0, d0 + ret +.Lfunc_end23: + .size lrint_i64_f64_simd, .Lfunc_end23-lrint_i64_f64_simd + .cfi_endproc + // -- End function + .globl llrint_i64_f16_simd // -- Begin function llrint_i64_f16_simd + .p2align 2 + .type llrint_i64_f16_simd,@function +llrint_i64_f16_simd: // @llrint_i64_f16_simd + .cfi_startproc +// %bb.0: + frintx h0, h0 + fcvtzs d0, h0 + ret +.Lfunc_end24: + .size llrint_i64_f16_simd, .Lfunc_end24-llrint_i64_f16_simd + .cfi_endproc + // -- End function + .globl llrint_i64_f32_simd // -- Begin function llrint_i64_f32_simd + .p2align 2 + .type llrint_i64_f32_simd,@function +llrint_i64_f32_simd: // @llrint_i64_f32_simd + .cfi_startproc +// %bb.0: + frintx s0, s0 + fcvtzs d0, s0 + ret +.Lfunc_end25: + .size llrint_i64_f32_simd, .Lfunc_end25-llrint_i64_f32_simd + .cfi_endproc + // -- End function + .globl llrint_i64_f64_simd // -- Begin function llrint_i64_f64_simd + .p2align 2 + .type llrint_i64_f64_simd,@function +llrint_i64_f64_simd: // @llrint_i64_f64_simd + .cfi_startproc +// %bb.0: + frintx d0, d0 + fcvtzs d0, d0 + ret +.Lfunc_end26: + .size llrint_i64_f64_simd, .Lfunc_end26-llrint_i64_f64_simd + .cfi_endproc + // -- End function + .globl lrint_i32_f16_simd_exp // -- Begin function lrint_i32_f16_simd_exp + .p2align 2 + .type lrint_i32_f16_simd_exp,@function +lrint_i32_f16_simd_exp: // @lrint_i32_f16_simd_exp + .cfi_startproc +// %bb.0: + frintx h0, h0 + fcvtzs s0, h0 + ret +.Lfunc_end27: + .size lrint_i32_f16_simd_exp, .Lfunc_end27-lrint_i32_f16_simd_exp + .cfi_endproc + // -- End function + .globl lrint_i64_f16_simd_exp // -- Begin function lrint_i64_f16_simd_exp + .p2align 2 + .type lrint_i64_f16_simd_exp,@function +lrint_i64_f16_simd_exp: // @lrint_i64_f16_simd_exp + .cfi_startproc +// %bb.0: + frintx h0, h0 + fcvtzs d0, h0 + ret +.Lfunc_end28: + .size lrint_i64_f16_simd_exp, .Lfunc_end28-lrint_i64_f16_simd_exp + .cfi_endproc + // -- End function + .globl lrint_i64_f32_simd_exp // -- Begin function lrint_i64_f32_simd_exp + .p2align 2 + .type lrint_i64_f32_simd_exp,@function +lrint_i64_f32_simd_exp: // @lrint_i64_f32_simd_exp + .cfi_startproc +// %bb.0: + frintx s0, s0 + fcvtzs d0, s0 + ret +.Lfunc_end29: + .size lrint_i64_f32_simd_exp, .Lfunc_end29-lrint_i64_f32_simd_exp + .cfi_endproc + // -- End function + .globl lrint_i32_f64_simd_exp // -- Begin function lrint_i32_f64_simd_exp + .p2align 2 + .type lrint_i32_f64_simd_exp,@function +lrint_i32_f64_simd_exp: // @lrint_i32_f64_simd_exp + .cfi_startproc +// %bb.0: + frintx d0, d0 + fcvtzs s0, d0 + ret +.Lfunc_end30: + .size lrint_i32_f64_simd_exp, .Lfunc_end30-lrint_i32_f64_simd_exp + .cfi_endproc + // -- End function + .globl lrint_i32_f32_simd_exp // -- Begin function lrint_i32_f32_simd_exp + .p2align 2 + .type lrint_i32_f32_simd_exp,@function +lrint_i32_f32_simd_exp: // @lrint_i32_f32_simd_exp + .cfi_startproc +// %bb.0: + frintx s0, s0 + fcvtzs s0, s0 + ret +.Lfunc_end31: + .size lrint_i32_f32_simd_exp, .Lfunc_end31-lrint_i32_f32_simd_exp + .cfi_endproc + // -- End function + .globl lrint_i64_f64_simd_exp // -- Begin function lrint_i64_f64_simd_exp + .p2align 2 + .type lrint_i64_f64_simd_exp,@function +lrint_i64_f64_simd_exp: // @lrint_i64_f64_simd_exp + .cfi_startproc +// %bb.0: + frintx d0, d0 + fcvtzs d0, d0 + ret +.Lfunc_end32: + .size lrint_i64_f64_simd_exp, .Lfunc_end32-lrint_i64_f64_simd_exp + .cfi_endproc + // -- End function + .globl llrint_i64_f16_simd_exp // -- Begin function llrint_i64_f16_simd_exp + .p2align 2 + .type llrint_i64_f16_simd_exp,@function +llrint_i64_f16_simd_exp: // @llrint_i64_f16_simd_exp + .cfi_startproc +// %bb.0: + frintx h0, h0 + fcvtzs d0, h0 + ret +.Lfunc_end33: + .size llrint_i64_f16_simd_exp, .Lfunc_end33-llrint_i64_f16_simd_exp + .cfi_endproc + // -- End function + .globl llrint_i64_f32_simd_exp // -- Begin function llrint_i64_f32_simd_exp + .p2align 2 + .type llrint_i64_f32_simd_exp,@function +llrint_i64_f32_simd_exp: // @llrint_i64_f32_simd_exp + .cfi_startproc +// %bb.0: + frintx s0, s0 + fcvtzs d0, s0 + ret +.Lfunc_end34: + .size llrint_i64_f32_simd_exp, .Lfunc_end34-llrint_i64_f32_simd_exp + .cfi_endproc + // -- End function + .globl llrint_i64_f64_simd_exp // -- Begin function llrint_i64_f64_simd_exp + .p2align 2 + .type llrint_i64_f64_simd_exp,@function +llrint_i64_f64_simd_exp: // @llrint_i64_f64_simd_exp + .cfi_startproc +// %bb.0: + frintx d0, d0 + fcvtzs d0, d0 + ret +.Lfunc_end35: + .size llrint_i64_f64_simd_exp, .Lfunc_end35-llrint_i64_f64_simd_exp + .cfi_endproc + // -- End function + .section ".note.GNU-stack","",@progbits From ed50a6a69239db282a15393ce4fa5af157375063 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Mon, 1 Dec 2025 12:29:34 +0000 Subject: [PATCH 4/7] test fix --- .../arm64-cvt-simd-round-rint-strictfp.ll | 199 ++++++++++++++++ .../AArch64/arm64-cvt-simd-round-rint.ll | 220 +----------------- 2 files changed, 201 insertions(+), 218 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll new file mode 100644 index 0000000000000..2c8a2ad4aeb04 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll @@ -0,0 +1,199 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK + +; +; (L/LL)Round experimental +; + +define float @lround_i32_f16_simd_exp(half %x) { +; CHECK-LABEL: lround_i32_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, h0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f16(half %x, metadata !"fpexcept.strict") + %sum = bitcast i32 %val to float + ret float %sum +} + +define double @lround_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: lround_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lround.i64.f16(half %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lround_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: lround_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lround.i64.f32(float %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define float @lround_i32_f64_simd_exp(double %x) { +; CHECK-LABEL: lround_i32_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, d0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x, metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lround_i32_f32_simd_exp(float %x) { +; CHECK-LABEL: lround_i32_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, s0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x, metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lround_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: lround_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lround.i64.f64(double %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llround_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: llround_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llround.i64.f16(half %x, metadata !"fpexcept.strict") + %sum = bitcast i64 %val to double + ret double %sum +} + +define double @llround_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: llround_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llround.i64.f32(float %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llround_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: llround_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llround.i64.f64(double %x, metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +; +; (L/LL)Rint experimental +; + +define float @lrint_i32_f16_simd_exp(half %x) { +; CHECK-LABEL: lrint_i32_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs s0, h0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lrint.i32.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %sum = bitcast i32 %val to float + ret float %sum +} + +define double @lrint_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: lrint_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i53.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lrint_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: lrint_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define float @lrint_i32_f64_simd_exp(double %x) { +; CHECK-LABEL: lrint_i32_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs s0, d0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lrint.i32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lrint_i32_f32_simd_exp(float %x) { +; CHECK-LABEL: lrint_i32_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs s0, s0 +; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lrint_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: lrint_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i64.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llrint_i64_f16_simd_exp(half %x) { +; CHECK-LABEL: llrint_i64_f16_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx h0, h0 +; CHECK-NEXT: fcvtzs d0, h0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llrint.i64.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %sum = bitcast i64 %val to double + ret double %sum +} + +define double @llrint_i64_f32_simd_exp(float %x) { +; CHECK-LABEL: llrint_i64_f32_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx s0, s0 +; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @llrint_i64_f64_simd_exp(double %x) { +; CHECK-LABEL: llrint_i64_f64_simd_exp: +; CHECK: // %bb.0: +; CHECK-NEXT: frintx d0, d0 +; CHECK-NEXT: fcvtzs d0, d0 +; CHECK-NEXT: ret + %val = call i64 @llvm.experimental.constrained.llrint.i64.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll index 16fd91c0dd0ab..295c763145719 100644 --- a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll @@ -2,27 +2,9 @@ ; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SD ; RUN: llc < %s -mtriple aarch64-unknown-unknown -global-isel -global-isel-abort=2 -mattr=+fprcvt,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI -; CHECK-GI: warning: Instruction selection used fallback path for lround_i32_f16_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f16_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f32_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f64_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i32_f32_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lround_i64_f64_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f16_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f32_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llround_i64_f64_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f16_simd +; CHECK-GI: warning: Instruction selection used fallback path for lrint_i32_f16_simd ; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f64_simd ; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f32_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f16_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i64_f16_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i64_f32_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f64_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f32_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i64_f64_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llrint_i64_f16_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llrint_i64_f32_simd_exp -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for llrint_i64_f64_simd_exp ; ; (L/LL)Round @@ -136,101 +118,6 @@ define double @llround_i64_f64_simd(double %x) { ret double %bc } - -; -; (L/LL)Round experimental -; - -define float @lround_i32_f16_simd_exp(half %x) { -; CHECK-LABEL: lround_i32_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, h0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lround.i32.f16(half %x, metadata !"fpexcept.strict") - %sum = bitcast i32 %val to float - ret float %sum -} - -define double @lround_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: lround_i64_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, h0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lround.i64.f16(half %x, metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @lround_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: lround_i64_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, s0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lround.i64.f32(float %x, metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define float @lround_i32_f64_simd_exp(double %x) { -; CHECK-LABEL: lround_i32_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, d0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x, metadata !"fpexcept.strict") - %bc = bitcast i32 %val to float - ret float %bc -} - -define float @lround_i32_f32_simd_exp(float %x) { -; CHECK-LABEL: lround_i32_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, s0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x, metadata !"fpexcept.strict") - %bc = bitcast i32 %val to float - ret float %bc -} - -define double @lround_i64_f64_simd_exp(double %x) { -; CHECK-LABEL: lround_i64_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, d0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lround.i64.f64(double %x, metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @llround_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: llround_i64_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, h0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.llround.i64.f16(half %x, metadata !"fpexcept.strict") - %sum = bitcast i64 %val to double - ret double %sum -} - -define double @llround_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: llround_i64_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, s0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.llround.i64.f32(float %x, metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @llround_i64_f64_simd_exp(double %x) { -; CHECK-LABEL: llround_i64_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, d0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.llround.i64.f64(double %x, metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - ; ; (L/LL)Rint ; @@ -332,107 +219,4 @@ define double @llrint_i64_f64_simd(double %x) { %val = call i64 @llvm.llrint.i64.f64(double %x) %bc = bitcast i64 %val to double ret double %bc -} - -; -; (L/LL)Rint experimental -; - -define float @lrint_i32_f16_simd_exp(half %x) { -; CHECK-LABEL: lrint_i32_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs s0, h0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lrint.i32.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %sum = bitcast i32 %val to float - ret float %sum -} - -define double @lrint_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: lrint_i64_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs d0, h0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lrint.i53.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @lrint_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: lrint_i64_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs d0, s0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define float @lrint_i32_f64_simd_exp(double %x) { -; CHECK-LABEL: lrint_i32_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx d0, d0 -; CHECK-NEXT: fcvtzs s0, d0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lrint.i32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i32 %val to float - ret float %bc -} - -define float @lrint_i32_f32_simd_exp(float %x) { -; CHECK-LABEL: lrint_i32_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs s0, s0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i32 %val to float - ret float %bc -} - -define double @lrint_i64_f64_simd_exp(double %x) { -; CHECK-LABEL: lrint_i64_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx d0, d0 -; CHECK-NEXT: fcvtzs d0, d0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lrint.i64.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @llrint_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: llrint_i64_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs d0, h0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.llrint.i64.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %sum = bitcast i64 %val to double - ret double %sum -} - -define double @llrint_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: llrint_i64_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs d0, s0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.llrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @llrint_i64_f64_simd_exp(double %x) { -; CHECK-LABEL: llrint_i64_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx d0, d0 -; CHECK-NEXT: fcvtzs d0, d0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.llrint.i64.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} +} \ No newline at end of file From 10877d2e2c5af3289c34e28042cf140ac5b5f463 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Mon, 1 Dec 2025 12:43:12 +0000 Subject: [PATCH 5/7] delete s file --- .../AArch64/arm64-cvt-simd-round-rint.s | 456 ------------------ 1 file changed, 456 deletions(-) delete mode 100644 llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s deleted file mode 100644 index 8e2e8a39b86d6..0000000000000 --- a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.s +++ /dev/null @@ -1,456 +0,0 @@ - .file "arm64-cvt-simd-round-rint.ll" - .text - .globl lround_i32_f16_simd // -- Begin function lround_i32_f16_simd - .p2align 2 - .type lround_i32_f16_simd,@function -lround_i32_f16_simd: // @lround_i32_f16_simd - .cfi_startproc -// %bb.0: - fcvtas x8, h0 - fmov s0, w8 - ret -.Lfunc_end0: - .size lround_i32_f16_simd, .Lfunc_end0-lround_i32_f16_simd - .cfi_endproc - // -- End function - .globl lround_i64_f16_simd // -- Begin function lround_i64_f16_simd - .p2align 2 - .type lround_i64_f16_simd,@function -lround_i64_f16_simd: // @lround_i64_f16_simd - .cfi_startproc -// %bb.0: - fcvtas d0, h0 - ret -.Lfunc_end1: - .size lround_i64_f16_simd, .Lfunc_end1-lround_i64_f16_simd - .cfi_endproc - // -- End function - .globl lround_i64_f32_simd // -- Begin function lround_i64_f32_simd - .p2align 2 - .type lround_i64_f32_simd,@function -lround_i64_f32_simd: // @lround_i64_f32_simd - .cfi_startproc -// %bb.0: - fcvtas d0, s0 - ret -.Lfunc_end2: - .size lround_i64_f32_simd, .Lfunc_end2-lround_i64_f32_simd - .cfi_endproc - // -- End function - .globl lround_i32_f64_simd // -- Begin function lround_i32_f64_simd - .p2align 2 - .type lround_i32_f64_simd,@function -lround_i32_f64_simd: // @lround_i32_f64_simd - .cfi_startproc -// %bb.0: - fcvtas x8, d0 - fmov s0, w8 - ret -.Lfunc_end3: - .size lround_i32_f64_simd, .Lfunc_end3-lround_i32_f64_simd - .cfi_endproc - // -- End function - .globl lround_i32_f32_simd // -- Begin function lround_i32_f32_simd - .p2align 2 - .type lround_i32_f32_simd,@function -lround_i32_f32_simd: // @lround_i32_f32_simd - .cfi_startproc -// %bb.0: - fcvtas x8, s0 - fmov s0, w8 - ret -.Lfunc_end4: - .size lround_i32_f32_simd, .Lfunc_end4-lround_i32_f32_simd - .cfi_endproc - // -- End function - .globl lround_i64_f64_simd // -- Begin function lround_i64_f64_simd - .p2align 2 - .type lround_i64_f64_simd,@function -lround_i64_f64_simd: // @lround_i64_f64_simd - .cfi_startproc -// %bb.0: - fcvtas d0, d0 - ret -.Lfunc_end5: - .size lround_i64_f64_simd, .Lfunc_end5-lround_i64_f64_simd - .cfi_endproc - // -- End function - .globl llround_i64_f16_simd // -- Begin function llround_i64_f16_simd - .p2align 2 - .type llround_i64_f16_simd,@function -llround_i64_f16_simd: // @llround_i64_f16_simd - .cfi_startproc -// %bb.0: - fcvtas d0, h0 - ret -.Lfunc_end6: - .size llround_i64_f16_simd, .Lfunc_end6-llround_i64_f16_simd - .cfi_endproc - // -- End function - .globl llround_i64_f32_simd // -- Begin function llround_i64_f32_simd - .p2align 2 - .type llround_i64_f32_simd,@function -llround_i64_f32_simd: // @llround_i64_f32_simd - .cfi_startproc -// %bb.0: - fcvtas d0, s0 - ret -.Lfunc_end7: - .size llround_i64_f32_simd, .Lfunc_end7-llround_i64_f32_simd - .cfi_endproc - // -- End function - .globl llround_i64_f64_simd // -- Begin function llround_i64_f64_simd - .p2align 2 - .type llround_i64_f64_simd,@function -llround_i64_f64_simd: // @llround_i64_f64_simd - .cfi_startproc -// %bb.0: - fcvtas d0, d0 - ret -.Lfunc_end8: - .size llround_i64_f64_simd, .Lfunc_end8-llround_i64_f64_simd - .cfi_endproc - // -- End function - .globl lround_i32_f16_simd_exp // -- Begin function lround_i32_f16_simd_exp - .p2align 2 - .type lround_i32_f16_simd_exp,@function -lround_i32_f16_simd_exp: // @lround_i32_f16_simd_exp - .cfi_startproc -// %bb.0: - fcvtas s0, h0 - ret -.Lfunc_end9: - .size lround_i32_f16_simd_exp, .Lfunc_end9-lround_i32_f16_simd_exp - .cfi_endproc - // -- End function - .globl lround_i64_f16_simd_exp // -- Begin function lround_i64_f16_simd_exp - .p2align 2 - .type lround_i64_f16_simd_exp,@function -lround_i64_f16_simd_exp: // @lround_i64_f16_simd_exp - .cfi_startproc -// %bb.0: - fcvtas d0, h0 - ret -.Lfunc_end10: - .size lround_i64_f16_simd_exp, .Lfunc_end10-lround_i64_f16_simd_exp - .cfi_endproc - // -- End function - .globl lround_i64_f32_simd_exp // -- Begin function lround_i64_f32_simd_exp - .p2align 2 - .type lround_i64_f32_simd_exp,@function -lround_i64_f32_simd_exp: // @lround_i64_f32_simd_exp - .cfi_startproc -// %bb.0: - fcvtas d0, s0 - ret -.Lfunc_end11: - .size lround_i64_f32_simd_exp, .Lfunc_end11-lround_i64_f32_simd_exp - .cfi_endproc - // -- End function - .globl lround_i32_f64_simd_exp // -- Begin function lround_i32_f64_simd_exp - .p2align 2 - .type lround_i32_f64_simd_exp,@function -lround_i32_f64_simd_exp: // @lround_i32_f64_simd_exp - .cfi_startproc -// %bb.0: - fcvtas s0, d0 - ret -.Lfunc_end12: - .size lround_i32_f64_simd_exp, .Lfunc_end12-lround_i32_f64_simd_exp - .cfi_endproc - // -- End function - .globl lround_i32_f32_simd_exp // -- Begin function lround_i32_f32_simd_exp - .p2align 2 - .type lround_i32_f32_simd_exp,@function -lround_i32_f32_simd_exp: // @lround_i32_f32_simd_exp - .cfi_startproc -// %bb.0: - fcvtas s0, s0 - ret -.Lfunc_end13: - .size lround_i32_f32_simd_exp, .Lfunc_end13-lround_i32_f32_simd_exp - .cfi_endproc - // -- End function - .globl lround_i64_f64_simd_exp // -- Begin function lround_i64_f64_simd_exp - .p2align 2 - .type lround_i64_f64_simd_exp,@function -lround_i64_f64_simd_exp: // @lround_i64_f64_simd_exp - .cfi_startproc -// %bb.0: - fcvtas d0, d0 - ret -.Lfunc_end14: - .size lround_i64_f64_simd_exp, .Lfunc_end14-lround_i64_f64_simd_exp - .cfi_endproc - // -- End function - .globl llround_i64_f16_simd_exp // -- Begin function llround_i64_f16_simd_exp - .p2align 2 - .type llround_i64_f16_simd_exp,@function -llround_i64_f16_simd_exp: // @llround_i64_f16_simd_exp - .cfi_startproc -// %bb.0: - fcvtas d0, h0 - ret -.Lfunc_end15: - .size llround_i64_f16_simd_exp, .Lfunc_end15-llround_i64_f16_simd_exp - .cfi_endproc - // -- End function - .globl llround_i64_f32_simd_exp // -- Begin function llround_i64_f32_simd_exp - .p2align 2 - .type llround_i64_f32_simd_exp,@function -llround_i64_f32_simd_exp: // @llround_i64_f32_simd_exp - .cfi_startproc -// %bb.0: - fcvtas d0, s0 - ret -.Lfunc_end16: - .size llround_i64_f32_simd_exp, .Lfunc_end16-llround_i64_f32_simd_exp - .cfi_endproc - // -- End function - .globl llround_i64_f64_simd_exp // -- Begin function llround_i64_f64_simd_exp - .p2align 2 - .type llround_i64_f64_simd_exp,@function -llround_i64_f64_simd_exp: // @llround_i64_f64_simd_exp - .cfi_startproc -// %bb.0: - fcvtas d0, d0 - ret -.Lfunc_end17: - .size llround_i64_f64_simd_exp, .Lfunc_end17-llround_i64_f64_simd_exp - .cfi_endproc - // -- End function - .globl lrint_i32_f16_simd // -- Begin function lrint_i32_f16_simd - .p2align 2 - .type lrint_i32_f16_simd,@function -lrint_i32_f16_simd: // @lrint_i32_f16_simd - .cfi_startproc -// %bb.0: - frintx h0, h0 - fcvtzs s0, h0 - ret -.Lfunc_end18: - .size lrint_i32_f16_simd, .Lfunc_end18-lrint_i32_f16_simd - .cfi_endproc - // -- End function - .globl lrint_i64_f16_simd // -- Begin function lrint_i64_f16_simd - .p2align 2 - .type lrint_i64_f16_simd,@function -lrint_i64_f16_simd: // @lrint_i64_f16_simd - .cfi_startproc -// %bb.0: - frintx h0, h0 - fcvtzs d0, h0 - ret -.Lfunc_end19: - .size lrint_i64_f16_simd, .Lfunc_end19-lrint_i64_f16_simd - .cfi_endproc - // -- End function - .globl lrint_i64_f32_simd // -- Begin function lrint_i64_f32_simd - .p2align 2 - .type lrint_i64_f32_simd,@function -lrint_i64_f32_simd: // @lrint_i64_f32_simd - .cfi_startproc -// %bb.0: - frintx s0, s0 - fcvtzs d0, s0 - ret -.Lfunc_end20: - .size lrint_i64_f32_simd, .Lfunc_end20-lrint_i64_f32_simd - .cfi_endproc - // -- End function - .globl lrint_i32_f64_simd // -- Begin function lrint_i32_f64_simd - .p2align 2 - .type lrint_i32_f64_simd,@function -lrint_i32_f64_simd: // @lrint_i32_f64_simd - .cfi_startproc -// %bb.0: - frintx d0, d0 - fcvtzs s0, d0 - ret -.Lfunc_end21: - .size lrint_i32_f64_simd, .Lfunc_end21-lrint_i32_f64_simd - .cfi_endproc - // -- End function - .globl lrint_i32_f32_simd // -- Begin function lrint_i32_f32_simd - .p2align 2 - .type lrint_i32_f32_simd,@function -lrint_i32_f32_simd: // @lrint_i32_f32_simd - .cfi_startproc -// %bb.0: - frintx s0, s0 - fcvtzs s0, s0 - ret -.Lfunc_end22: - .size lrint_i32_f32_simd, .Lfunc_end22-lrint_i32_f32_simd - .cfi_endproc - // -- End function - .globl lrint_i64_f64_simd // -- Begin function lrint_i64_f64_simd - .p2align 2 - .type lrint_i64_f64_simd,@function -lrint_i64_f64_simd: // @lrint_i64_f64_simd - .cfi_startproc -// %bb.0: - frintx d0, d0 - fcvtzs d0, d0 - ret -.Lfunc_end23: - .size lrint_i64_f64_simd, .Lfunc_end23-lrint_i64_f64_simd - .cfi_endproc - // -- End function - .globl llrint_i64_f16_simd // -- Begin function llrint_i64_f16_simd - .p2align 2 - .type llrint_i64_f16_simd,@function -llrint_i64_f16_simd: // @llrint_i64_f16_simd - .cfi_startproc -// %bb.0: - frintx h0, h0 - fcvtzs d0, h0 - ret -.Lfunc_end24: - .size llrint_i64_f16_simd, .Lfunc_end24-llrint_i64_f16_simd - .cfi_endproc - // -- End function - .globl llrint_i64_f32_simd // -- Begin function llrint_i64_f32_simd - .p2align 2 - .type llrint_i64_f32_simd,@function -llrint_i64_f32_simd: // @llrint_i64_f32_simd - .cfi_startproc -// %bb.0: - frintx s0, s0 - fcvtzs d0, s0 - ret -.Lfunc_end25: - .size llrint_i64_f32_simd, .Lfunc_end25-llrint_i64_f32_simd - .cfi_endproc - // -- End function - .globl llrint_i64_f64_simd // -- Begin function llrint_i64_f64_simd - .p2align 2 - .type llrint_i64_f64_simd,@function -llrint_i64_f64_simd: // @llrint_i64_f64_simd - .cfi_startproc -// %bb.0: - frintx d0, d0 - fcvtzs d0, d0 - ret -.Lfunc_end26: - .size llrint_i64_f64_simd, .Lfunc_end26-llrint_i64_f64_simd - .cfi_endproc - // -- End function - .globl lrint_i32_f16_simd_exp // -- Begin function lrint_i32_f16_simd_exp - .p2align 2 - .type lrint_i32_f16_simd_exp,@function -lrint_i32_f16_simd_exp: // @lrint_i32_f16_simd_exp - .cfi_startproc -// %bb.0: - frintx h0, h0 - fcvtzs s0, h0 - ret -.Lfunc_end27: - .size lrint_i32_f16_simd_exp, .Lfunc_end27-lrint_i32_f16_simd_exp - .cfi_endproc - // -- End function - .globl lrint_i64_f16_simd_exp // -- Begin function lrint_i64_f16_simd_exp - .p2align 2 - .type lrint_i64_f16_simd_exp,@function -lrint_i64_f16_simd_exp: // @lrint_i64_f16_simd_exp - .cfi_startproc -// %bb.0: - frintx h0, h0 - fcvtzs d0, h0 - ret -.Lfunc_end28: - .size lrint_i64_f16_simd_exp, .Lfunc_end28-lrint_i64_f16_simd_exp - .cfi_endproc - // -- End function - .globl lrint_i64_f32_simd_exp // -- Begin function lrint_i64_f32_simd_exp - .p2align 2 - .type lrint_i64_f32_simd_exp,@function -lrint_i64_f32_simd_exp: // @lrint_i64_f32_simd_exp - .cfi_startproc -// %bb.0: - frintx s0, s0 - fcvtzs d0, s0 - ret -.Lfunc_end29: - .size lrint_i64_f32_simd_exp, .Lfunc_end29-lrint_i64_f32_simd_exp - .cfi_endproc - // -- End function - .globl lrint_i32_f64_simd_exp // -- Begin function lrint_i32_f64_simd_exp - .p2align 2 - .type lrint_i32_f64_simd_exp,@function -lrint_i32_f64_simd_exp: // @lrint_i32_f64_simd_exp - .cfi_startproc -// %bb.0: - frintx d0, d0 - fcvtzs s0, d0 - ret -.Lfunc_end30: - .size lrint_i32_f64_simd_exp, .Lfunc_end30-lrint_i32_f64_simd_exp - .cfi_endproc - // -- End function - .globl lrint_i32_f32_simd_exp // -- Begin function lrint_i32_f32_simd_exp - .p2align 2 - .type lrint_i32_f32_simd_exp,@function -lrint_i32_f32_simd_exp: // @lrint_i32_f32_simd_exp - .cfi_startproc -// %bb.0: - frintx s0, s0 - fcvtzs s0, s0 - ret -.Lfunc_end31: - .size lrint_i32_f32_simd_exp, .Lfunc_end31-lrint_i32_f32_simd_exp - .cfi_endproc - // -- End function - .globl lrint_i64_f64_simd_exp // -- Begin function lrint_i64_f64_simd_exp - .p2align 2 - .type lrint_i64_f64_simd_exp,@function -lrint_i64_f64_simd_exp: // @lrint_i64_f64_simd_exp - .cfi_startproc -// %bb.0: - frintx d0, d0 - fcvtzs d0, d0 - ret -.Lfunc_end32: - .size lrint_i64_f64_simd_exp, .Lfunc_end32-lrint_i64_f64_simd_exp - .cfi_endproc - // -- End function - .globl llrint_i64_f16_simd_exp // -- Begin function llrint_i64_f16_simd_exp - .p2align 2 - .type llrint_i64_f16_simd_exp,@function -llrint_i64_f16_simd_exp: // @llrint_i64_f16_simd_exp - .cfi_startproc -// %bb.0: - frintx h0, h0 - fcvtzs d0, h0 - ret -.Lfunc_end33: - .size llrint_i64_f16_simd_exp, .Lfunc_end33-llrint_i64_f16_simd_exp - .cfi_endproc - // -- End function - .globl llrint_i64_f32_simd_exp // -- Begin function llrint_i64_f32_simd_exp - .p2align 2 - .type llrint_i64_f32_simd_exp,@function -llrint_i64_f32_simd_exp: // @llrint_i64_f32_simd_exp - .cfi_startproc -// %bb.0: - frintx s0, s0 - fcvtzs d0, s0 - ret -.Lfunc_end34: - .size llrint_i64_f32_simd_exp, .Lfunc_end34-llrint_i64_f32_simd_exp - .cfi_endproc - // -- End function - .globl llrint_i64_f64_simd_exp // -- Begin function llrint_i64_f64_simd_exp - .p2align 2 - .type llrint_i64_f64_simd_exp,@function -llrint_i64_f64_simd_exp: // @llrint_i64_f64_simd_exp - .cfi_startproc -// %bb.0: - frintx d0, d0 - fcvtzs d0, d0 - ret -.Lfunc_end35: - .size llrint_i64_f64_simd_exp, .Lfunc_end35-llrint_i64_f64_simd_exp - .cfi_endproc - // -- End function - .section ".note.GNU-stack","",@progbits From 21a0c8d69f9c9a52f466e8552bef3abb1ec8c4e4 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Wed, 3 Dec 2025 15:12:10 +0000 Subject: [PATCH 6/7] Remove globalISel work --- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 34 ------------- .../AArch64/GISel/AArch64RegisterBankInfo.cpp | 18 +++++-- .../AArch64/GlobalISel/regbank-llround.mir | 4 +- .../AArch64/GlobalISel/regbank-lround.mir | 4 +- .../AArch64/arm64-cvt-simd-round-rint.ll | 51 +++++-------------- llvm/test/CodeGen/AArch64/vector-lrint.ll | 18 +++---- 6 files changed, 37 insertions(+), 92 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index dac796c7bbe09..ace5d1b1c0cf5 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -6805,23 +6805,6 @@ defm : FPToIntegerPats; defm : FPToIntegerPats; -// For global-isel we can use register classes to determine -// which FCVT instruction to use. -let Predicates = [HasFPRCVT] in { -def : Pat<(i64 (any_lround f16:$Rn)), - (FCVTASDHr f16:$Rn)>; -def : Pat<(i64 (any_llround f16:$Rn)), - (FCVTASDHr f16:$Rn)>; -def : Pat<(i64 (any_lround f32:$Rn)), - (FCVTASDSr f32:$Rn)>; -def : Pat<(i64 (any_llround f32:$Rn)), - (FCVTASDSr f32:$Rn)>; -} -def : Pat<(i64 (any_lround f64:$Rn)), - (FCVTASv1i64 f64:$Rn)>; -def : Pat<(i64 (any_llround f64:$Rn)), - (FCVTASv1i64 f64:$Rn)>; - let Predicates = [HasFPRCVT] in { def : Pat<(f32 (bitconvert (i32 (any_lround f16:$Rn)))), (FCVTASSHr f16:$Rn)>; @@ -6843,23 +6826,6 @@ def : Pat<(f64 (bitconvert (i64 (any_lround f64:$Rn)))), def : Pat<(f64 (bitconvert (i64 (any_llround f64:$Rn)))), (FCVTASv1i64 f64:$Rn)>; -// For global-isel we can use register classes to determine -// which FCVT instruction to use. -let Predicates = [HasFPRCVT] in { -def : Pat<(i64 (any_lrint f16:$Rn)), - (FCVTZSDHr (FRINTXHr f16:$Rn))>; -def : Pat<(i64 (any_llrint f16:$Rn)), - (FCVTZSDHr (FRINTXHr f16:$Rn))>; -def : Pat<(i64 (any_lrint f32:$Rn)), - (FCVTZSDSr (FRINTXSr f32:$Rn))>; -def : Pat<(i64 (any_llrint f32:$Rn)), - (FCVTZSDSr (FRINTXSr f32:$Rn))>; -} -def : Pat<(i64 (any_lrint f64:$Rn)), - (FCVTZSv1i64 (FRINTXDr f64:$Rn))>; -def : Pat<(i64 (any_llrint f64:$Rn)), - (FCVTZSv1i64 (FRINTXDr f64:$Rn))>; - let Predicates = [HasFPRCVT] in { def : Pat<(f32 (bitconvert (i32 (any_lrint f16:$Rn)))), (FCVTZSSHr (FRINTXHr f16:$Rn))>; diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp index ed5cc83e1ff37..6b920f05227ad 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp @@ -859,11 +859,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case TargetOpcode::G_FPTOSI_SAT: case TargetOpcode::G_FPTOUI_SAT: case TargetOpcode::G_FPTOSI: - case TargetOpcode::G_FPTOUI: - case TargetOpcode::G_INTRINSIC_LRINT: - case TargetOpcode::G_INTRINSIC_LLRINT: - case TargetOpcode::G_LROUND: - case TargetOpcode::G_LLROUND: { + case TargetOpcode::G_FPTOUI: { LLT DstType = MRI.getType(MI.getOperand(0).getReg()); if (DstType.isVector()) break; @@ -884,6 +880,12 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR}; break; } + case TargetOpcode::G_INTRINSIC_LRINT: + case TargetOpcode::G_INTRINSIC_LLRINT: + if (MRI.getType(MI.getOperand(0).getReg()).isVector()) + break; + OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR}; + break; case TargetOpcode::G_FCMP: { // If the result is a vector, it must use a FPR. AArch64GenRegisterBankInfo::PartialMappingIdx Idx0 = @@ -1223,6 +1225,12 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { } break; } + case TargetOpcode::G_LROUND: + case TargetOpcode::G_LLROUND: { + // Source is always floating point and destination is always integer. + OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR}; + break; + } } // Finally construct the computed mapping. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir index 16100f01017a6..420c7cfb07b74 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-llround.mir @@ -14,7 +14,7 @@ body: | ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %fpr:fpr(s64) = COPY $d0 - ; CHECK-NEXT: %llround:fpr(s64) = G_LLROUND %fpr(s64) + ; CHECK-NEXT: %llround:gpr(s64) = G_LLROUND %fpr(s64) ; CHECK-NEXT: $d0 = COPY %llround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %fpr:_(s64) = COPY $d0 @@ -35,7 +35,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %gpr:gpr(s64) = COPY $x0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr(s64) = COPY %gpr(s64) - ; CHECK-NEXT: %llround:fpr(s64) = G_LLROUND [[COPY]](s64) + ; CHECK-NEXT: %llround:gpr(s64) = G_LLROUND [[COPY]](s64) ; CHECK-NEXT: $d0 = COPY %llround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %gpr:_(s64) = COPY $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir index 5cb93f7c4646d..775c6ca773c68 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-lround.mir @@ -14,7 +14,7 @@ body: | ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %fpr:fpr(s64) = COPY $d0 - ; CHECK-NEXT: %lround:fpr(s64) = G_LROUND %fpr(s64) + ; CHECK-NEXT: %lround:gpr(s64) = G_LROUND %fpr(s64) ; CHECK-NEXT: $d0 = COPY %lround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %fpr:_(s64) = COPY $d0 @@ -35,7 +35,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %gpr:gpr(s64) = COPY $x0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr(s64) = COPY %gpr(s64) - ; CHECK-NEXT: %lround:fpr(s64) = G_LROUND [[COPY]](s64) + ; CHECK-NEXT: %lround:gpr(s64) = G_LROUND [[COPY]](s64) ; CHECK-NEXT: $d0 = COPY %lround(s64) ; CHECK-NEXT: RET_ReallyLR implicit $s0 %gpr:_(s64) = COPY $x0 diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll index 295c763145719..6f74c31858be0 100644 --- a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll @@ -1,26 +1,15 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 -; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SD -; RUN: llc < %s -mtriple aarch64-unknown-unknown -global-isel -global-isel-abort=2 -mattr=+fprcvt,+fullfp16 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI - -; CHECK-GI: warning: Instruction selection used fallback path for lrint_i32_f16_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f64_simd -; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_i32_f32_simd +; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK ; ; (L/LL)Round ; define float @lround_i32_f16_simd(half %x) { -; CHECK-SD-LABEL: lround_i32_f16_simd: -; CHECK-SD: // %bb.0: -; CHECK-SD-NEXT: fcvtas s0, h0 -; CHECK-SD-NEXT: ret -; -; CHECK-GI-LABEL: lround_i32_f16_simd: -; CHECK-GI: // %bb.0: -; CHECK-GI-NEXT: fcvtas x8, h0 -; CHECK-GI-NEXT: fmov s0, w8 -; CHECK-GI-NEXT: ret +; CHECK-LABEL: lround_i32_f16_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, h0 +; CHECK-NEXT: ret %val = call i32 @llvm.lround.i32.f16(half %x) %sum = bitcast i32 %val to float ret float %sum @@ -47,32 +36,20 @@ define double @lround_i64_f32_simd(float %x) { } define float @lround_i32_f64_simd(double %x) { -; CHECK-SD-LABEL: lround_i32_f64_simd: -; CHECK-SD: // %bb.0: -; CHECK-SD-NEXT: fcvtas s0, d0 -; CHECK-SD-NEXT: ret -; -; CHECK-GI-LABEL: lround_i32_f64_simd: -; CHECK-GI: // %bb.0: -; CHECK-GI-NEXT: fcvtas x8, d0 -; CHECK-GI-NEXT: fmov s0, w8 -; CHECK-GI-NEXT: ret +; CHECK-LABEL: lround_i32_f64_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, d0 +; CHECK-NEXT: ret %val = call i32 @llvm.lround.i32.f64(double %x) %bc = bitcast i32 %val to float ret float %bc } define float @lround_i32_f32_simd(float %x) { -; CHECK-SD-LABEL: lround_i32_f32_simd: -; CHECK-SD: // %bb.0: -; CHECK-SD-NEXT: fcvtas s0, s0 -; CHECK-SD-NEXT: ret -; -; CHECK-GI-LABEL: lround_i32_f32_simd: -; CHECK-GI: // %bb.0: -; CHECK-GI-NEXT: fcvtas x8, s0 -; CHECK-GI-NEXT: fmov s0, w8 -; CHECK-GI-NEXT: ret +; CHECK-LABEL: lround_i32_f32_simd: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvtas s0, s0 +; CHECK-NEXT: ret %val = call i32 @llvm.lround.i32.f32(float %x) %bc = bitcast i32 %val to float ret float %bc @@ -219,4 +196,4 @@ define double @llrint_i64_f64_simd(double %x) { %val = call i64 @llvm.llrint.i64.f64(double %x) %bc = bitcast i64 %val to double ret double %bc -} \ No newline at end of file +} diff --git a/llvm/test/CodeGen/AArch64/vector-lrint.ll b/llvm/test/CodeGen/AArch64/vector-lrint.ll index 3e827bf437c7b..c226ec3c3e25c 100644 --- a/llvm/test/CodeGen/AArch64/vector-lrint.ll +++ b/llvm/test/CodeGen/AArch64/vector-lrint.ll @@ -1005,18 +1005,12 @@ define <1 x iXLen> @lrint_v1f64(<1 x double> %x) nounwind { ; CHECK-i32-NEXT: fmov s0, w8 ; CHECK-i32-NEXT: ret ; -; CHECK-i64-SD-LABEL: lrint_v1f64: -; CHECK-i64-SD: // %bb.0: -; CHECK-i64-SD-NEXT: frintx d0, d0 -; CHECK-i64-SD-NEXT: fcvtzs x8, d0 -; CHECK-i64-SD-NEXT: fmov d0, x8 -; CHECK-i64-SD-NEXT: ret -; -; CHECK-i64-GI-LABEL: lrint_v1f64: -; CHECK-i64-GI: // %bb.0: -; CHECK-i64-GI-NEXT: frintx d0, d0 -; CHECK-i64-GI-NEXT: fcvtzs d0, d0 -; CHECK-i64-GI-NEXT: ret +; CHECK-i64-LABEL: lrint_v1f64: +; CHECK-i64: // %bb.0: +; CHECK-i64-NEXT: frintx d0, d0 +; CHECK-i64-NEXT: fcvtzs x8, d0 +; CHECK-i64-NEXT: fmov d0, x8 +; CHECK-i64-NEXT: ret %a = call <1 x iXLen> @llvm.lrint.v1iXLen.v1f64(<1 x double> %x) ret <1 x iXLen> %a } From 7e1c2843bddc90566a6b67346368109c8a1a125a Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Fri, 5 Dec 2025 15:24:16 +0000 Subject: [PATCH 7/7] Adjust tests for clarity --- .../arm64-cvt-simd-round-rint-strictfp.ll | 263 ++++++++++++------ .../AArch64/arm64-cvt-simd-round-rint.ll | 263 ++++++++++++------ 2 files changed, 350 insertions(+), 176 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll index 2c8a2ad4aeb04..7633a9b3fff24 100644 --- a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint-strictfp.ll @@ -1,60 +1,85 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 -; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK +; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FPRCVT +; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-NOFPRCVT ; -; (L/LL)Round experimental +; Lround strictfp ; define float @lround_i32_f16_simd_exp(half %x) { -; CHECK-LABEL: lround_i32_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lround_i32_f16_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas s0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i32_f16_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas w8, h0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i32 @llvm.experimental.constrained.lround.i32.f16(half %x, metadata !"fpexcept.strict") %sum = bitcast i32 %val to float ret float %sum } -define double @lround_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: lround_i64_f16_simd_exp: +define float @lround_i32_f32_simd_exp(float %x) { +; CHECK-LABEL: lround_i32_f32_simd_exp: ; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: fcvtas s0, s0 ; CHECK-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x, metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lround_i32_f64_simd_exp(double %x) { +; CHECK-FPRCVT-LABEL: lround_i32_f64_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas s0, d0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i32_f64_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas w8, d0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret + %val = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x, metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lround_i64_f16_simd_exp(half %x) { +; CHECK-FPRCVT-LABEL: lround_i64_f16_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i64_f16_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.experimental.constrained.lround.i64.f16(half %x, metadata !"fpexcept.strict") %bc = bitcast i64 %val to double ret double %bc } define double @lround_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: lround_i64_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, s0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lround_i64_f32_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i64_f32_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.experimental.constrained.lround.i64.f32(float %x, metadata !"fpexcept.strict") %bc = bitcast i64 %val to double ret double %bc } -define float @lround_i32_f64_simd_exp(double %x) { -; CHECK-LABEL: lround_i32_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, d0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x, metadata !"fpexcept.strict") - %bc = bitcast i32 %val to float - ret float %bc -} - -define float @lround_i32_f32_simd_exp(float %x) { -; CHECK-LABEL: lround_i32_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, s0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x, metadata !"fpexcept.strict") - %bc = bitcast i32 %val to float - ret float %bc -} - define double @lround_i64_f64_simd_exp(double %x) { ; CHECK-LABEL: lround_i64_f64_simd_exp: ; CHECK: // %bb.0: @@ -65,21 +90,37 @@ define double @lround_i64_f64_simd_exp(double %x) { ret double %bc } +; +; Llround strictfp +; + define double @llround_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: llround_i64_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llround_i64_f16_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llround_i64_f16_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.experimental.constrained.llround.i64.f16(half %x, metadata !"fpexcept.strict") %sum = bitcast i64 %val to double ret double %sum } define double @llround_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: llround_i64_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, s0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llround_i64_f32_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llround_i64_f32_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.experimental.constrained.llround.i64.f32(float %x, metadata !"fpexcept.strict") %bc = bitcast i64 %val to double ret double %bc @@ -96,62 +137,90 @@ define double @llround_i64_f64_simd_exp(double %x) { } ; -; (L/LL)Rint experimental +; Lrint strictfp ; define float @lrint_i32_f16_simd_exp(half %x) { -; CHECK-LABEL: lrint_i32_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs s0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lrint_i32_f16_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx h0, h0 +; CHECK-FPRCVT-NEXT: fcvtzs s0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i32_f16_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx h0, h0 +; CHECK-NOFPRCVT-NEXT: fcvtzs w8, h0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i32 @llvm.experimental.constrained.lrint.i32.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") %sum = bitcast i32 %val to float ret float %sum } -define double @lrint_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: lrint_i64_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs d0, h0 -; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lrint.i53.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @lrint_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: lrint_i64_f32_simd_exp: +define float @lrint_i32_f32_simd_exp(float %x) { +; CHECK-LABEL: lrint_i32_f32_simd_exp: ; CHECK: // %bb.0: ; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: fcvtzs s0, s0 ; CHECK-NEXT: ret - %val = call i64 @llvm.experimental.constrained.lrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i64 %val to double - ret double %bc + %val = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i32 %val to float + ret float %bc } define float @lrint_i32_f64_simd_exp(double %x) { -; CHECK-LABEL: lrint_i32_f64_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx d0, d0 -; CHECK-NEXT: fcvtzs s0, d0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lrint_i32_f64_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx d0, d0 +; CHECK-FPRCVT-NEXT: fcvtzs s0, d0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i32_f64_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx d0, d0 +; CHECK-NOFPRCVT-NEXT: fcvtzs w8, d0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i32 @llvm.experimental.constrained.lrint.i32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") %bc = bitcast i32 %val to float ret float %bc } -define float @lrint_i32_f32_simd_exp(float %x) { -; CHECK-LABEL: lrint_i32_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs s0, s0 -; CHECK-NEXT: ret - %val = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") - %bc = bitcast i32 %val to float - ret float %bc +define double @lrint_i64_f16_simd_exp(half %x) { +; CHECK-FPRCVT-LABEL: lrint_i64_f16_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx h0, h0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i64_f16_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx h0, h0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i53.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lrint_i64_f32_simd_exp(float %x) { +; CHECK-FPRCVT-LABEL: lrint_i64_f32_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx s0, s0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i64_f32_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx s0, s0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret + %val = call i64 @llvm.experimental.constrained.lrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") + %bc = bitcast i64 %val to double + ret double %bc } define double @lrint_i64_f64_simd_exp(double %x) { @@ -165,23 +234,41 @@ define double @lrint_i64_f64_simd_exp(double %x) { ret double %bc } +; +; Llrint strictfp +; + define double @llrint_i64_f16_simd_exp(half %x) { -; CHECK-LABEL: llrint_i64_f16_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs d0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llrint_i64_f16_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx h0, h0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llrint_i64_f16_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx h0, h0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.experimental.constrained.llrint.i64.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") %sum = bitcast i64 %val to double ret double %sum } define double @llrint_i64_f32_simd_exp(float %x) { -; CHECK-LABEL: llrint_i64_f32_simd_exp: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs d0, s0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llrint_i64_f32_simd_exp: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx s0, s0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llrint_i64_f32_simd_exp: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx s0, s0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.experimental.constrained.llrint.i64.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") %bc = bitcast i64 %val to double ret double %bc diff --git a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll index 6f74c31858be0..8717952ea944a 100644 --- a/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll +++ b/llvm/test/CodeGen/AArch64/arm64-cvt-simd-round-rint.ll @@ -1,60 +1,85 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 -; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK +; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fprcvt,+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FPRCVT +; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-NOFPRCVT ; -; (L/LL)Round +; Lround ; define float @lround_i32_f16_simd(half %x) { -; CHECK-LABEL: lround_i32_f16_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lround_i32_f16_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas s0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i32_f16_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas w8, h0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i32 @llvm.lround.i32.f16(half %x) %sum = bitcast i32 %val to float ret float %sum } -define double @lround_i64_f16_simd(half %x) { -; CHECK-LABEL: lround_i64_f16_simd: +define float @lround_i32_f32_simd(float %x) { +; CHECK-LABEL: lround_i32_f32_simd: ; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, h0 +; CHECK-NEXT: fcvtas s0, s0 ; CHECK-NEXT: ret + %val = call i32 @llvm.lround.i32.f32(float %x) + %bc = bitcast i32 %val to float + ret float %bc +} + +define float @lround_i32_f64_simd(double %x) { +; CHECK-FPRCVT-LABEL: lround_i32_f64_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas s0, d0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i32_f64_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas w8, d0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret + %val = call i32 @llvm.lround.i32.f64(double %x) + %bc = bitcast i32 %val to float + ret float %bc +} + +define double @lround_i64_f16_simd(half %x) { +; CHECK-FPRCVT-LABEL: lround_i64_f16_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i64_f16_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.lround.i64.f16(half %x) %bc = bitcast i64 %val to double ret double %bc } define double @lround_i64_f32_simd(float %x) { -; CHECK-LABEL: lround_i64_f32_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, s0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lround_i64_f32_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lround_i64_f32_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.lround.i64.f32(float %x) %bc = bitcast i64 %val to double ret double %bc } -define float @lround_i32_f64_simd(double %x) { -; CHECK-LABEL: lround_i32_f64_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, d0 -; CHECK-NEXT: ret - %val = call i32 @llvm.lround.i32.f64(double %x) - %bc = bitcast i32 %val to float - ret float %bc -} - -define float @lround_i32_f32_simd(float %x) { -; CHECK-LABEL: lround_i32_f32_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas s0, s0 -; CHECK-NEXT: ret - %val = call i32 @llvm.lround.i32.f32(float %x) - %bc = bitcast i32 %val to float - ret float %bc -} - define double @lround_i64_f64_simd(double %x) { ; CHECK-LABEL: lround_i64_f64_simd: ; CHECK: // %bb.0: @@ -65,21 +90,37 @@ define double @lround_i64_f64_simd(double %x) { ret double %bc } +; +; Llround +; + define double @llround_i64_f16_simd(half %x) { -; CHECK-LABEL: llround_i64_f16_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llround_i64_f16_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llround_i64_f16_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.llround.i64.f16(half %x) %sum = bitcast i64 %val to double ret double %sum } define double @llround_i64_f32_simd(float %x) { -; CHECK-LABEL: llround_i64_f32_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvtas d0, s0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llround_i64_f32_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: fcvtas d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llround_i64_f32_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: fcvtas x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.llround.i64.f32(float %x) %bc = bitcast i64 %val to double ret double %bc @@ -96,62 +137,90 @@ define double @llround_i64_f64_simd(double %x) { } ; -; (L/LL)Rint +; Lrint ; define float @lrint_i32_f16_simd(half %x) { -; CHECK-LABEL: lrint_i32_f16_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs s0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lrint_i32_f16_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx h0, h0 +; CHECK-FPRCVT-NEXT: fcvtzs s0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i32_f16_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx h0, h0 +; CHECK-NOFPRCVT-NEXT: fcvtzs w8, h0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i32 @llvm.lrint.i32.f16(half %x) %sum = bitcast i32 %val to float ret float %sum } -define double @lrint_i64_f16_simd(half %x) { -; CHECK-LABEL: lrint_i64_f16_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs d0, h0 -; CHECK-NEXT: ret - %val = call i64 @llvm.lrint.i53.f16(half %x) - %bc = bitcast i64 %val to double - ret double %bc -} - -define double @lrint_i64_f32_simd(float %x) { -; CHECK-LABEL: lrint_i64_f32_simd: +define float @lrint_i32_f32_simd(float %x) { +; CHECK-LABEL: lrint_i32_f32_simd: ; CHECK: // %bb.0: ; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs d0, s0 +; CHECK-NEXT: fcvtzs s0, s0 ; CHECK-NEXT: ret - %val = call i64 @llvm.lrint.i64.f32(float %x) - %bc = bitcast i64 %val to double - ret double %bc + %val = call i32 @llvm.lrint.i32.f32(float %x) + %bc = bitcast i32 %val to float + ret float %bc } define float @lrint_i32_f64_simd(double %x) { -; CHECK-LABEL: lrint_i32_f64_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx d0, d0 -; CHECK-NEXT: fcvtzs s0, d0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: lrint_i32_f64_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx d0, d0 +; CHECK-FPRCVT-NEXT: fcvtzs s0, d0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i32_f64_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx d0, d0 +; CHECK-NOFPRCVT-NEXT: fcvtzs w8, d0 +; CHECK-NOFPRCVT-NEXT: fmov s0, w8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i32 @llvm.lrint.i32.f64(double %x) %bc = bitcast i32 %val to float ret float %bc } -define float @lrint_i32_f32_simd(float %x) { -; CHECK-LABEL: lrint_i32_f32_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs s0, s0 -; CHECK-NEXT: ret - %val = call i32 @llvm.lrint.i32.f32(float %x) - %bc = bitcast i32 %val to float - ret float %bc +define double @lrint_i64_f16_simd(half %x) { +; CHECK-FPRCVT-LABEL: lrint_i64_f16_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx h0, h0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i64_f16_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx h0, h0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret + %val = call i64 @llvm.lrint.i64.f16(half %x) + %bc = bitcast i64 %val to double + ret double %bc +} + +define double @lrint_i64_f32_simd(float %x) { +; CHECK-FPRCVT-LABEL: lrint_i64_f32_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx s0, s0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: lrint_i64_f32_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx s0, s0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret + %val = call i64 @llvm.lrint.i64.f32(float %x) + %bc = bitcast i64 %val to double + ret double %bc } define double @lrint_i64_f64_simd(double %x) { @@ -165,23 +234,41 @@ define double @lrint_i64_f64_simd(double %x) { ret double %bc } +; +; Llrint +; + define double @llrint_i64_f16_simd(half %x) { -; CHECK-LABEL: llrint_i64_f16_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx h0, h0 -; CHECK-NEXT: fcvtzs d0, h0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llrint_i64_f16_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx h0, h0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, h0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llrint_i64_f16_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx h0, h0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, h0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.llrint.i64.f16(half %x) %sum = bitcast i64 %val to double ret double %sum } define double @llrint_i64_f32_simd(float %x) { -; CHECK-LABEL: llrint_i64_f32_simd: -; CHECK: // %bb.0: -; CHECK-NEXT: frintx s0, s0 -; CHECK-NEXT: fcvtzs d0, s0 -; CHECK-NEXT: ret +; CHECK-FPRCVT-LABEL: llrint_i64_f32_simd: +; CHECK-FPRCVT: // %bb.0: +; CHECK-FPRCVT-NEXT: frintx s0, s0 +; CHECK-FPRCVT-NEXT: fcvtzs d0, s0 +; CHECK-FPRCVT-NEXT: ret +; +; CHECK-NOFPRCVT-LABEL: llrint_i64_f32_simd: +; CHECK-NOFPRCVT: // %bb.0: +; CHECK-NOFPRCVT-NEXT: frintx s0, s0 +; CHECK-NOFPRCVT-NEXT: fcvtzs x8, s0 +; CHECK-NOFPRCVT-NEXT: fmov d0, x8 +; CHECK-NOFPRCVT-NEXT: ret %val = call i64 @llvm.llrint.i64.f32(float %x) %bc = bitcast i64 %val to double ret double %bc