[llvm] 5c9b497 - [AArch64][GlobalISel] Select *v1f16 for f16->s16 to_int_sat_gi (#154562)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 29 09:02:02 PDT 2025
Author: Kajetan Puchalski
Date: 2025-08-29T17:01:58+01:00
New Revision: 5c9b497ce4d3e5a63a55a80a4ab987955197d799
URL: https://github.com/llvm/llvm-project/commit/5c9b497ce4d3e5a63a55a80a4ab987955197d799
DIFF: https://github.com/llvm/llvm-project/commit/5c9b497ce4d3e5a63a55a80a4ab987955197d799.diff
LOG: [AArch64][GlobalISel] Select *v1f16 for f16->s16 to_int_sat_gi (#154562)
Conversions from f16 to s16 performed by to_int_sat_gi can be done
directly within FPRs, e.g. `fcvtzs h0, h0`.
Generating this format reduces the number of instruction required for
correct behaviour, as it sidesteps the issues with incorrect saturation
that arise when using `fcvtzs w0, h0` for the same casts.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski at arm.com>
Added:
Modified:
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll
llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 07c07008c0e05..9ab02eafc0c8a 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -6539,6 +6539,12 @@ defm UQXTN : SIMDTwoScalarMixedBHS<1, 0b10100, "uqxtn", int_aarch64_neon_scalar
defm USQADD : SIMDTwoScalarBHSDTied< 1, 0b00011, "usqadd",
int_aarch64_neon_usqadd>;
+// f16 -> s16 conversions
+let Predicates = [HasFullFP16] in {
+ def : Pat<(i16(fp_to_sint_sat_gi f16:$Rn)), (FCVTZSv1f16 f16:$Rn)>;
+ def : Pat<(i16(fp_to_uint_sat_gi f16:$Rn)), (FCVTZUv1f16 f16:$Rn)>;
+}
+
def : Pat<(v1i64 (AArch64vashr (v1i64 V64:$Rn), (i32 63))),
(CMLTv1i64rz V64:$Rn)>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index b403a319e4350..82391f13d1370 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -879,8 +879,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
{v2s32, v2s32},
{v4s32, v4s32},
{v2s64, v2s64}})
- .legalFor(HasFP16,
- {{s32, s16}, {s64, s16}, {v4s16, v4s16}, {v8s16, v8s16}})
+ .legalFor(
+ HasFP16,
+ {{s16, s16}, {s32, s16}, {s64, s16}, {v4s16, v4s16}, {v8s16, v8s16}})
// Handle types larger than i64 by scalarizing/lowering.
.scalarizeIf(scalarOrEltWiderThan(0, 64), 0)
.scalarizeIf(scalarOrEltWiderThan(1, 64), 1)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 1b919abd222e4..cf391c446a955 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -848,10 +848,20 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
break;
}
+ case TargetOpcode::G_FPTOSI_SAT:
+ case TargetOpcode::G_FPTOUI_SAT: {
+ LLT DstType = MRI.getType(MI.getOperand(0).getReg());
+ if (DstType.isVector())
+ break;
+ if (DstType == LLT::scalar(16)) {
+ OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
+ break;
+ }
+ OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
+ break;
+ }
case TargetOpcode::G_FPTOSI:
case TargetOpcode::G_FPTOUI:
- case TargetOpcode::G_FPTOSI_SAT:
- case TargetOpcode::G_FPTOUI_SAT:
case TargetOpcode::G_INTRINSIC_LRINT:
case TargetOpcode::G_INTRINSIC_LLRINT:
if (MRI.getType(MI.getOperand(0).getReg()).isVector())
diff --git a/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll b/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll
index 83a1893cdbc75..ddee23cc3fc50 100644
--- a/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll
@@ -689,13 +689,8 @@ define i16 @test_signed_i16_f16(half %f) nounwind {
;
; CHECK-GI-FP16-LABEL: test_signed_i16_f16:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: fcvtzs w8, h0
-; CHECK-GI-FP16-NEXT: mov w9, #32767 // =0x7fff
-; CHECK-GI-FP16-NEXT: cmp w8, w9
-; CHECK-GI-FP16-NEXT: csel w8, w8, w9, lt
-; CHECK-GI-FP16-NEXT: mov w9, #-32768 // =0xffff8000
-; CHECK-GI-FP16-NEXT: cmn w8, #8, lsl #12 // =32768
-; CHECK-GI-FP16-NEXT: csel w0, w8, w9, gt
+; CHECK-GI-FP16-NEXT: fcvtzs h0, h0
+; CHECK-GI-FP16-NEXT: fmov w0, s0
; CHECK-GI-FP16-NEXT: ret
%x = call i16 @llvm.fptosi.sat.i16.f16(half %f)
ret i16 %x
diff --git a/llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll b/llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll
index 2613f8337a918..8abad4419663c 100644
--- a/llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll
@@ -546,10 +546,8 @@ define i16 @test_unsigned_i16_f16(half %f) nounwind {
;
; CHECK-GI-FP16-LABEL: test_unsigned_i16_f16:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: fcvtzu w8, h0
-; CHECK-GI-FP16-NEXT: mov w9, #65535 // =0xffff
-; CHECK-GI-FP16-NEXT: cmp w8, w9
-; CHECK-GI-FP16-NEXT: csel w0, w8, w9, lo
+; CHECK-GI-FP16-NEXT: fcvtzu h0, h0
+; CHECK-GI-FP16-NEXT: fmov w0, s0
; CHECK-GI-FP16-NEXT: ret
%x = call i16 @llvm.fptoui.sat.i16.f16(half %f)
ret i16 %x
More information about the llvm-commits
mailing list