diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 7dd6d49bf2022..4d7c3cfa5f764 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4280,7 +4280,7 @@ let Predicates = [HasSVE2p2orSME2p2] in { defm SCVTF_ZPzZ : sve_fp_z2op_p_zd_c<0b0, "scvtf">; defm UCVTF_ZPzZ : sve_fp_z2op_p_zd_c<0b1, "ucvtf">; // Signed integer base 2 logarithm of fp value, zeroing predicate - defm FLOGB_ZPzZ : sve_fp_z2op_p_zd_d_flogb<"flogb">; + defm FLOGB_ZPzZ : sve_fp_z2op_p_zd_d_flogb<"flogb", int_aarch64_sve_flogb>; // SVE2 integer unary operations, zeroing predicate def URECPE_ZPzZ : sve2_int_un_pred_arit_z<0b10, 0b00, "urecpe", ZPR32>; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 0ef862fc1a27c..979e1a0f4a92b 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -3316,10 +3316,14 @@ multiclass sve_fp_z2op_p_zd_c { def _DtoD : sve_fp_z2op_p_zd<{ 0b111011, U }, asm, ZPR64, ZPR64>; } -multiclass sve_fp_z2op_p_zd_d_flogb { +multiclass sve_fp_z2op_p_zd_d_flogb { def _H : sve_fp_z2op_p_zd<0b0011001, asm, ZPR16, ZPR16>; def _S : sve_fp_z2op_p_zd<0b0011010, asm, ZPR32, ZPR32>; def _D : sve_fp_z2op_p_zd<0b0011011, asm, ZPR64, ZPR64>; + + defm : SVE_3_Op_UndefZero_Pat(NAME # _H)>; + defm : SVE_3_Op_UndefZero_Pat(NAME # _S)>; + defm : SVE_3_Op_UndefZero_Pat(NAME # _D)>; } multiclass sve_fp_z2op_p_zd_b_0 { diff --git a/llvm/test/CodeGen/AArch64/zeroing-forms-flogb.ll b/llvm/test/CodeGen/AArch64/zeroing-forms-flogb.ll new file mode 100644 index 0000000000000..23620a3419b99 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/zeroing-forms-flogb.ll @@ -0,0 +1,258 @@ +; 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_svlogb_f16_x_1( %pg, %x) { +; CHECK-LABEL: test_svlogb_f16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: flogb z0.h, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.h, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv8f16( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_f16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svlogb_f16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: flogb z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv8f16( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_f16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svlogb_f16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: flogb z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv8f16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svlogb_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svlogb_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: flogb z0.s, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.s, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv4f32( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svlogb_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: flogb z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv4f32( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svlogb_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: flogb z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv4f32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svlogb_f64_x_1( %pg, %x) { +; CHECK-LABEL: test_svlogb_f64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: flogb z0.d, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.d, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv2f64( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_f64_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svlogb_f64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: flogb z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv2f64( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_f64_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svlogb_f64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: flogb z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_f64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: flogb z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.flogb.nxv2f64( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svlogb_nxv8f16_ptrue_u(double %z0, %x) { +; CHECK-LABEL: test_svlogb_nxv8f16_ptrue_u: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: ptrue p0.h +; CHECK-NEXT: flogb z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_nxv8f16_ptrue_u: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: ptrue p0.h +; CHECK-2p2-NEXT: flogb z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %pg = call @llvm.aarch64.sve.ptrue.nxv8i1(i32 31) + %0 = tail call @llvm.aarch64.sve.flogb.nxv8f16( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_nxv8f16_ptrue(double %z0, %x, %y) { +; CHECK-LABEL: test_svlogb_nxv8f16_ptrue: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, z1.d +; CHECK-NEXT: ptrue p0.h +; CHECK-NEXT: flogb z0.h, p0/m, z2.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_nxv8f16_ptrue: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: ptrue p0.h +; CHECK-2p2-NEXT: flogb z0.h, p0/z, z2.h +; CHECK-2p2-NEXT: ret +entry: + %pg = call @llvm.aarch64.sve.ptrue.nxv8i1(i32 31) + %0 = tail call @llvm.aarch64.sve.flogb.nxv8f16( %x, %pg, %y) + ret %0 +} + +define @test_svlogb_nxv4f32_ptrue_u(double %z0, %x) { +; CHECK-LABEL: test_svlogb_nxv4f32_ptrue_u: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: flogb z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_nxv4f32_ptrue_u: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: ptrue p0.s +; CHECK-2p2-NEXT: flogb z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %pg = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) + %0 = tail call @llvm.aarch64.sve.flogb.nxv4f32( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_nxv4f32_ptrue(double %z0, %x, %y) { +; CHECK-LABEL: test_svlogb_nxv4f32_ptrue: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, z1.d +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: flogb z0.s, p0/m, z2.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_nxv4f32_ptrue: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: ptrue p0.s +; CHECK-2p2-NEXT: flogb z0.s, p0/z, z2.s +; CHECK-2p2-NEXT: ret +entry: + %pg = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) + %0 = tail call @llvm.aarch64.sve.flogb.nxv4f32( %x, %pg, %y) + ret %0 +} + +define @test_svlogb_nxv2f64_ptrue_u(double %z0, %x) { +; CHECK-LABEL: test_svlogb_nxv2f64_ptrue_u: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: flogb z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_nxv2f64_ptrue_u: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: ptrue p0.d +; CHECK-2p2-NEXT: flogb z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %pg = call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) + %0 = tail call @llvm.aarch64.sve.flogb.nxv2f64( poison, %pg, %x) + ret %0 +} + +define @test_svlogb_nxv2f64_ptrue(double %z0, %x, %y) { +; CHECK-LABEL: test_svlogb_nxv2f64_ptrue: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, z1.d +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: flogb z0.d, p0/m, z2.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svlogb_nxv2f64_ptrue: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: ptrue p0.d +; CHECK-2p2-NEXT: flogb z0.d, p0/z, z2.d +; CHECK-2p2-NEXT: ret +entry: + %pg = call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) + %0 = tail call @llvm.aarch64.sve.flogb.nxv2f64( %x, %pg, %y) + ret %0 +} +