From bac0e8b46c284b17f04a68d95b87e8b8bf28f438 Mon Sep 17 00:00:00 2001 From: Spencer Abson Date: Thu, 7 Nov 2024 11:44:27 +0000 Subject: [PATCH] [AArch64][SVE] Fix the immediate argument in svextq The meaning of the immediate argument in svextq should be tied to the element size of its operands. For example: svextq_f64(zn_f64, zm_f64, 1) would, for each 128-bit segment of zn_f64, concatenate the highest 15 bytes of this segment with the first byte of the corresponding segment of zm_f64. The intuitive behavior of svextq_f64(zn_f64, zm_f64, 1) is to concatenate the higher doubleword of zn_f64 with the lower doubleword of zm_f64. The range of the immediate argument in svextq has been modified such that it is: - [0,15] for svextq_{s8,u8} - [0,7] for svextq_{s16,u16,f16,bf16} - [0,3] for svextq_{s32,u32,f32} - [0,1] for svextq_{s64,u64,f64} --- clang/include/clang/Basic/arm_sve.td | 2 +- .../sve2p1-intrinsics/acle_sve2p1_extq.c | 42 +++++++++--------- .../acle_sve2p1_imm.cpp | 44 +++++++++++++++++-- .../lib/Target/AArch64/AArch64InstrFormats.td | 33 ++++++++++++++ llvm/lib/Target/AArch64/SVEInstrFormats.td | 17 ++++--- .../CodeGen/AArch64/sve2p1-intrinsics-extq.ll | 28 ++++++------ 6 files changed, 118 insertions(+), 48 deletions(-) diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index d492fae4145b9..c6b7cd637b9ec 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -2286,7 +2286,7 @@ let SVETargetGuard = "sve2p1", SMETargetGuard = InvalidMode in { def SVTBLQ : SInst<"svtblq[_{d}]", "ddu", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_tblq">; def SVTBXQ : SInst<"svtbxq[_{d}]", "dddu", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_tbxq">; // EXTQ - def EXTQ : SInst<"svextq[_{d}]", "dddk", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_extq", [], [ImmCheck<2, ImmCheck0_15>]>; + def EXTQ : SInst<"svextq[_{d}]", "dddk", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_extq", [], [ImmCheck<2, ImmCheckLaneIndex, 0>]>; // PMOV // Move to Pred diff --git a/clang/test/CodeGen/AArch64/sve2p1-intrinsics/acle_sve2p1_extq.c b/clang/test/CodeGen/AArch64/sve2p1-intrinsics/acle_sve2p1_extq.c index 5fbfa881500ba..06eec1e00900c 100644 --- a/clang/test/CodeGen/AArch64/sve2p1-intrinsics/acle_sve2p1_extq.c +++ b/clang/test/CodeGen/AArch64/sve2p1-intrinsics/acle_sve2p1_extq.c @@ -103,111 +103,111 @@ svuint32_t test_svextq_u32(svuint32_t zn, svuint32_t zm) { // CHECK-LABEL: define dso_local @test_svextq_s32 // CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4i32( [[ZN]], [[ZM]], i32 6) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4i32( [[ZN]], [[ZM]], i32 3) // CHECK-NEXT: ret [[TMP0]] // // CPP-CHECK-LABEL: define dso_local @_Z15test_svextq_s32u11__SVInt32_tS_ // CPP-CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4i32( [[ZN]], [[ZM]], i32 6) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4i32( [[ZN]], [[ZM]], i32 3) // CPP-CHECK-NEXT: ret [[TMP0]] // svint32_t test_svextq_s32(svint32_t zn, svint32_t zm) { - return SVE_ACLE_FUNC(svextq, _s32,,)(zn, zm, 6); + return SVE_ACLE_FUNC(svextq, _s32,,)(zn, zm, 3); } // CHECK-LABEL: define dso_local @test_svextq_u64 // CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 3) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 1) // CHECK-NEXT: ret [[TMP0]] // // CPP-CHECK-LABEL: define dso_local @_Z15test_svextq_u64u12__SVUint64_tS_ // CPP-CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 3) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 1) // CPP-CHECK-NEXT: ret [[TMP0]] // svuint64_t test_svextq_u64(svuint64_t zn, svuint64_t zm) { - return SVE_ACLE_FUNC(svextq, _u64,,)(zn, zm, 3); + return SVE_ACLE_FUNC(svextq, _u64,,)(zn, zm, 1); } // CHECK-LABEL: define dso_local @test_svextq_s64 // CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 0) // CHECK-NEXT: ret [[TMP0]] // // CPP-CHECK-LABEL: define dso_local @_Z15test_svextq_s64u11__SVInt64_tS_ // CPP-CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 7) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2i64( [[ZN]], [[ZM]], i32 0) // CPP-CHECK-NEXT: ret [[TMP0]] // svint64_t test_svextq_s64(svint64_t zn, svint64_t zm) { - return SVE_ACLE_FUNC(svextq, _s64,,)(zn, zm, 7); + return SVE_ACLE_FUNC(svextq, _s64,,)(zn, zm, 0); } // CHECK-LABEL: define dso_local @test_svextq_f16 // CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8f16( [[ZN]], [[ZM]], i32 8) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8f16( [[ZN]], [[ZM]], i32 7) // CHECK-NEXT: ret [[TMP0]] // // CPP-CHECK-LABEL: define dso_local @_Z15test_svextq_f16u13__SVFloat16_tS_ // CPP-CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8f16( [[ZN]], [[ZM]], i32 8) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8f16( [[ZN]], [[ZM]], i32 7) // CPP-CHECK-NEXT: ret [[TMP0]] // svfloat16_t test_svextq_f16(svfloat16_t zn, svfloat16_t zm) { - return SVE_ACLE_FUNC(svextq, _f16,,)(zn, zm, 8); + return SVE_ACLE_FUNC(svextq, _f16,,)(zn, zm, 7); } // CHECK-LABEL: define dso_local @test_svextq_f32 // CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4f32( [[ZN]], [[ZM]], i32 9) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4f32( [[ZN]], [[ZM]], i32 2) // CHECK-NEXT: ret [[TMP0]] // // CPP-CHECK-LABEL: define dso_local @_Z15test_svextq_f32u13__SVFloat32_tS_ // CPP-CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4f32( [[ZN]], [[ZM]], i32 9) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv4f32( [[ZN]], [[ZM]], i32 2) // CPP-CHECK-NEXT: ret [[TMP0]] // svfloat32_t test_svextq_f32(svfloat32_t zn, svfloat32_t zm) { - return SVE_ACLE_FUNC(svextq, _f32,,)(zn, zm, 9); + return SVE_ACLE_FUNC(svextq, _f32,,)(zn, zm, 2); } // CHECK-LABEL: define dso_local @test_svextq_f64 // CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2f64( [[ZN]], [[ZM]], i32 10) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2f64( [[ZN]], [[ZM]], i32 0) // CHECK-NEXT: ret [[TMP0]] // // CPP-CHECK-LABEL: define dso_local @_Z15test_svextq_f64u13__SVFloat64_tS_ // CPP-CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2f64( [[ZN]], [[ZM]], i32 10) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv2f64( [[ZN]], [[ZM]], i32 0) // CPP-CHECK-NEXT: ret [[TMP0]] // svfloat64_t test_svextq_f64(svfloat64_t zn, svfloat64_t zm) { - return SVE_ACLE_FUNC(svextq, _f64,,)(zn, zm, 10); + return SVE_ACLE_FUNC(svextq, _f64,,)(zn, zm, 0); } // CHECK-LABEL: define dso_local @test_svextq_bf16 // CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8bf16( [[ZN]], [[ZM]], i32 11) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8bf16( [[ZN]], [[ZM]], i32 6) // CHECK-NEXT: ret [[TMP0]] // // CPP-CHECK-LABEL: define dso_local @_Z16test_svextq_bf16u14__SVBfloat16_tS_ // CPP-CHECK-SAME: ( [[ZN:%.*]], [[ZM:%.*]]) #[[ATTR0]] { // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8bf16( [[ZN]], [[ZM]], i32 11) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.extq.nxv8bf16( [[ZN]], [[ZM]], i32 6) // CPP-CHECK-NEXT: ret [[TMP0]] // svbfloat16_t test_svextq_bf16(svbfloat16_t zn, svbfloat16_t zm) { - return SVE_ACLE_FUNC(svextq, _bf16,,)(zn, zm, 11); + return SVE_ACLE_FUNC(svextq, _bf16,,)(zn, zm, 6); } diff --git a/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp b/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp index f7047c99e884e..ac7586e202b96 100644 --- a/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp +++ b/clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp @@ -138,9 +138,47 @@ void test_svbfmul_lane(svbfloat16_t zn, svbfloat16_t zm, uint64_t idx){ } __attribute__((target("+sve2p1"))) -void test_svextq_lane(svint16_t zn_i16, svint16_t zm_i16, svfloat16_t zn_f16, svfloat16_t zm_f16){ - svextq_s16(zn_i16, zm_i16, -1); // expected-error {{argument value -1 is outside the valid range [0, 15]}} - svextq_f16(zn_f16, zm_f16, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} +void test_svextq_8b_offset(svint8_t s8, svuint8_t u8){ + svextq_s8(s8, s8, -1); // expected-error {{argument value -1 is outside the valid range [0, 15]}} + svextq_u8(u8, u8, -1); // expected-error {{argument value -1 is outside the valid range [0, 15]}} + + svextq_s8(s8, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} + svextq_u8(u8, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}} +} + +__attribute__((target("+sve2p1"))) +void test_svextq_16b_offset(svint16_t s16, svuint16_t u16, svfloat16_t f16, svbfloat16_t bf16){ + svextq_s16(s16, s16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + svextq_u16(u16, u16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + svextq_f16(f16, f16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + svextq_bf16(bf16, bf16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + + svextq_s16(s16, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svextq_u16(u16, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svextq_f16(f16, f16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + svextq_bf16(bf16, bf16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} +} + +__attribute__((target("+sve2p1"))) +void test_svextq_32b_offset(svint32_t s32, svuint32_t u32, svfloat32_t f32){ + svextq_s32(s32, s32, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} + svextq_u32(u32, u32, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} + svextq_f32(f32, f32, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} + + svextq_s32(s32, s32, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svextq_u32(u32, u32, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + svextq_f32(f32, f32, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} +} + +__attribute__((target("+sve2p1"))) +void test_svextq_64b_offset(svint64_t s64, svuint64_t u64, svfloat64_t f64){ + svextq_s64(s64, s64, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} + svextq_u64(u64, u64, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} + svextq_f64(f64, f64, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}} + + svextq_s64(s64, s64, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svextq_u64(u64, u64, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} + svextq_f64(f64, f64, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}} } __attribute__((target("+sve2p1"))) diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 242aea5fbb014..a8ba89f784c8c 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -529,6 +529,18 @@ def UImmS8XForm : SDNodeXFormgetTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); }]>; +def UImmM2XForm : SDNodeXFormgetTargetConstant(N->getZExtValue() * 2, SDLoc(N), MVT::i32); +}]>; + +def UImmM4XForm : SDNodeXFormgetTargetConstant(N->getZExtValue() * 4, SDLoc(N), MVT::i32); +}]>; + +def UImmM8XForm : SDNodeXFormgetTargetConstant(N->getZExtValue() * 8, SDLoc(N), MVT::i32); +}]>; + // uimm5sN predicate - True if the immediate is a multiple of N in the range // [0 * N, 32 * N]. def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; @@ -1098,6 +1110,13 @@ def timm32_0_1 : Operand, TImmLeaf, TImmLeaf { + let ParserMatchClass = Imm0_15Operand; +} + // timm32_1_1 - True if the 32-bit immediate is in the range [1,1] def timm32_1_1 : Operand, TImmLeaf, TImmLeaf, TImmLeaf { + let ParserMatchClass = Imm0_15Operand; +} + // timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] def timm32_0_7 : Operand, TImmLeaf, TImmLeaf, TImmLeaf { + let ParserMatchClass = Imm0_15Operand; +} + // timm32_1_7 predicate - True if the 32-bit immediate is in the range [1,7] def timm32_1_7 : Operand, TImmLeaf 0 && ((uint32_t)Imm) < 8; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 1ddb913f013f5..4bdf327e0d3fc 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -10459,15 +10459,14 @@ class sve2p1_extq multiclass sve2p1_extq { def NAME : sve2p1_extq; def : SVE_3_Op_Imm_Pat(NAME)>; - def : SVE_3_Op_Imm_Pat(NAME)>; - def : SVE_3_Op_Imm_Pat(NAME)>; - def : SVE_3_Op_Imm_Pat(NAME)>; - - def : SVE_3_Op_Imm_Pat(NAME)>; - def : SVE_3_Op_Imm_Pat(NAME)>; - def : SVE_3_Op_Imm_Pat(NAME)>; - def : SVE_3_Op_Imm_Pat(NAME -)>; + def : SVE_3_Op_Imm_Pat(NAME)>; + def : SVE_3_Op_Imm_Pat(NAME)>; + def : SVE_3_Op_Imm_Pat(NAME)>; + + def : SVE_3_Op_Imm_Pat(NAME)>; + def : SVE_3_Op_Imm_Pat(NAME)>; + def : SVE_3_Op_Imm_Pat(NAME)>; + def : SVE_3_Op_Imm_Pat(NAME)>; } // SVE move predicate from vector diff --git a/llvm/test/CodeGen/AArch64/sve2p1-intrinsics-extq.ll b/llvm/test/CodeGen/AArch64/sve2p1-intrinsics-extq.ll index a49aa7cfcf8a2..bb4c67fca5dc8 100644 --- a/llvm/test/CodeGen/AArch64/sve2p1-intrinsics-extq.ll +++ b/llvm/test/CodeGen/AArch64/sve2p1-intrinsics-extq.ll @@ -4,16 +4,16 @@ define @test_extq_i8 ( %zn, %zm) { ; CHECK-LABEL: test_extq_i8: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #0 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #15 ; CHECK-NEXT: ret - %res = call @llvm.aarch64.sve.extq.nxv16i8( %zn, %zm, i32 0) + %res = call @llvm.aarch64.sve.extq.nxv16i8( %zn, %zm, i32 15) ret %res } define @test_extq_i16 ( %zn, %zm) { ; CHECK-LABEL: test_extq_i16: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #1 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #2 ; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.extq.nxv8i16( %zn, %zm, i32 1) ret %res @@ -22,7 +22,7 @@ define @test_extq_i16 ( %zn, @test_extq_i32 ( %zn, %zm) { ; CHECK-LABEL: test_extq_i32: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #2 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #8 ; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.extq.nxv4i32( %zn, %zm, i32 2) ret %res @@ -31,45 +31,45 @@ define @test_extq_i32 ( %zn, @test_extq_i64 ( %zn, %zm) { ; CHECK-LABEL: test_extq_i64: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #3 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #8 ; CHECK-NEXT: ret - %res = call @llvm.aarch64.sve.extq.nxv2i64( %zn, %zm, i32 3) + %res = call @llvm.aarch64.sve.extq.nxv2i64( %zn, %zm, i32 1) ret %res } define @test_extq_f16( %zn, %zm) { ; CHECK-LABEL: test_extq_f16: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #4 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #14 ; CHECK-NEXT: ret - %res = call @llvm.aarch64.sve.extq.nxv8f16( %zn, %zm, i32 4) + %res = call @llvm.aarch64.sve.extq.nxv8f16( %zn, %zm, i32 7) ret %res } define @test_extq_f32( %zn, %zm) { ; CHECK-LABEL: test_extq_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #5 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #4 ; CHECK-NEXT: ret - %res = call @llvm.aarch64.sve.extq.nxv4f32( %zn, %zm, i32 5) + %res = call @llvm.aarch64.sve.extq.nxv4f32( %zn, %zm, i32 1) ret %res } define @test_extq_f64( %zn, %zm) { ; CHECK-LABEL: test_extq_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #6 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #8 ; CHECK-NEXT: ret - %res = call @llvm.aarch64.sve.extq.nxv2f64( %zn, %zm, i32 6) + %res = call @llvm.aarch64.sve.extq.nxv2f64( %zn, %zm, i32 1) ret %res } define @test_extq_bf16( %zn, %zm) { ; CHECK-LABEL: test_extq_bf16: ; CHECK: // %bb.0: -; CHECK-NEXT: extq z0.b, z0.b, z1.b, #15 +; CHECK-NEXT: extq z0.b, z0.b, z1.b, #6 ; CHECK-NEXT: ret - %res = call @llvm.aarch64.sve.extq.nxv8bf16( %zn, %zm, i32 15) + %res = call @llvm.aarch64.sve.extq.nxv8bf16( %zn, %zm, i32 3) ret %res }