From c4760fcd9d8dc36dd6321d146c977aa434e21efe Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Tue, 19 Nov 2024 11:51:27 +0000 Subject: [PATCH 1/2] [AArch64] Generate zeroing forms of certain SVE2.2 instructions (3/11) --- .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 4 +- llvm/lib/Target/AArch64/SVEInstrFormats.td | 11 +- .../AArch64/zeroing-forms-fcvtlt-fcvtx.ll | 147 ++++++++++++++++++ 3 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 6be5eaf221d17..a15e89be1a24b 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4271,10 +4271,10 @@ let Predicates = [HasSVE2p2orSME2p2] in { defm FCVTNT_ZPzZ : sve_fp_fcvtntz<"fcvtnt">; def FCVTXNT_ZPzZ_DtoS : sve_fp_fcvt2z<0b0010, "fcvtxnt", ZPR32, ZPR64>; // Placing even - def FCVTX_ZPzZ_DtoS : sve_fp_z2op_p_zd<0b0001010, "fcvtx", ZPR64, ZPR32>; + defm FCVTX_ZPzZ : sve_fp_z2op_p_zd<"fcvtx", int_aarch64_sve_fcvtx_f32f64>; // SVE2p2 floating-point convert precision up, zeroing predicate - defm FCVTLT_ZPzZ : sve_fp_fcvtltz<"fcvtlt">; + defm FCVTLT_ZPzZ : sve_fp_fcvtltz<"fcvtlt", "int_aarch64_sve_fcvtlt">; // SVE2p2 floating-point convert single-to-bf (placing odd), zeroing predicate def BFCVTNT_ZPzZ : sve_fp_fcvt2z<0b1010, "bfcvtnt", ZPR16, ZPR32>; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 1d32f2ab75852..828a048eaf6fb 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -2858,9 +2858,12 @@ multiclass sve_fp_fcvtntz { def _DtoS : sve_fp_fcvt2z<0b1110, asm, ZPR32, ZPR64>; } -multiclass sve_fp_fcvtltz { +multiclass sve_fp_fcvtltz { def _HtoS : sve_fp_fcvt2z<0b1001, asm, ZPR32, ZPR16>; def _StoD : sve_fp_fcvt2z<0b1111, asm, ZPR64, ZPR32>; + + def : SVE_3_Op_UndefZero_Pat(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast(NAME # _HtoS)>; + def : SVE_3_Op_UndefZero_Pat(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast(NAME # _StoD)>; } //===----------------------------------------------------------------------===// @@ -3267,6 +3270,12 @@ class sve_fp_z2op_p_zd opc,string asm, RegisterOperand i_zprtype, let mayRaiseFPException = 1; } +multiclass sve_fp_z2op_p_zd { + def _DtoS : sve_fp_z2op_p_zd<0b0001010, asm, ZPR64, ZPR32>; + + def : SVE_3_Op_UndefZero_Pat(NAME # _DtoS)>; +} + multiclass sve_fp_z2op_p_zd_hsd opc, string asm> { def _H : sve_fp_z2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16>; def _S : sve_fp_z2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32>; diff --git a/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll new file mode 100644 index 0000000000000..d2a948ce60f4a --- /dev/null +++ b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll @@ -0,0 +1,147 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mattr=+sve2 < %s | FileCheck %s +; RUN: llc -mattr=+sve2p2 < %s | FileCheck %s -check-prefix CHECK-2p2 + +; RUN: llc -mattr=+sme2 -force-streaming < %s | FileCheck %s +; RUN: llc -mattr=+sme2p2 -force-streaming < %s | FileCheck %s -check-prefix CHECK-2p2 + +target triple = "aarch64-linux" + +define @test_svcvtlt_f32_f16_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvtlt_f32_f16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.s, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f32_f16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.s, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f32f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f32_f16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f32_f16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.s, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f32_f16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.s, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f32f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f32_f16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f32_f16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: fcvtlt z0.s, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f32_f16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.s, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f32f16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f64_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvtlt_f64_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.d, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f64_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.d, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f64f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f64_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f64_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.d, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f64_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.d, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f64f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f64_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f64_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: fcvtlt z0.d, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f64_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.d, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f64f32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvtx_f32_f64_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvtx_f32_f64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtx z0.s, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtx_f32_f64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvtx_f32_f64_x_2( %pg, %x) { +; CHECK-LABEL: test_svcvtx_f32_f64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtx z0.s, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtx_f32_f64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvtx_f32_f64_z( %pg, %x) { +; CHECK-LABEL: test_svcvtx_f32_f64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z1.s, #0 // =0x0 +; CHECK-NEXT: fcvtx z1.s, p0/m, z0.d +; CHECK-NEXT: mov z0.d, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtx_f32_f64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( zeroinitializer, %pg, %x) + ret %0 +} From 9b0d3b216d05a1f8bc1ed88aa7ceada8552461e7 Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Mon, 2 Dec 2024 12:11:49 +0000 Subject: [PATCH 2/2] [fixup] Add some missing "double %z0" to tests (NFC) --- .../CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll index d2a948ce60f4a..60879b1529230 100644 --- a/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll +++ b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll @@ -114,32 +114,31 @@ entry: ret %0 } -define @test_svcvtx_f32_f64_x_2( %pg, %x) { +define @test_svcvtx_f32_f64_x_2( %pg, double %z0, %x) { ; CHECK-LABEL: test_svcvtx_f32_f64_x_2: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: fcvtx z0.s, p0/m, z0.d +; CHECK-NEXT: fcvtx z0.s, p0/m, z1.d ; CHECK-NEXT: ret ; ; CHECK-2p2-LABEL: test_svcvtx_f32_f64_x_2: ; CHECK-2p2: // %bb.0: // %entry -; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z1.d ; CHECK-2p2-NEXT: ret entry: %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( undef, %pg, %x) ret %0 } -define @test_svcvtx_f32_f64_z( %pg, %x) { +define @test_svcvtx_f32_f64_z( %pg, double %z0, %x) { ; CHECK-LABEL: test_svcvtx_f32_f64_z: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov z1.s, #0 // =0x0 -; CHECK-NEXT: fcvtx z1.s, p0/m, z0.d -; CHECK-NEXT: mov z0.d, z1.d +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: fcvtx z0.s, p0/m, z1.d ; CHECK-NEXT: ret ; ; CHECK-2p2-LABEL: test_svcvtx_f32_f64_z: ; CHECK-2p2: // %bb.0: // %entry -; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z1.d ; CHECK-2p2-NEXT: ret entry: %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( zeroinitializer, %pg, %x)