Skip to content

Commit 2a0162c

Browse files
authored
[AArch64][SVE] Change the immediate argument in svextq (#115340)
In order to align with `svext` and NEON `vext`/`vextq`, this patch changes immediate argument in `svextq` such that it refers to elements of the size of those of the source vector, rather than bytes. The [spec for this intrinsic](https://github.com/ARM-software/acle/blob/main/main/acle.md#extq) is ambiguous about the meaning of this argument, this issue was raised after there was a differing interpretation for it from the implementers of the ACLE in GCC. For example (with our current implementation): `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`. After this patch, the behavior of `svextq_f64(zn_f64, zm_f64, 1)` would be, for each 128-bit vector segment of `zn_f64`, to concatenate the higher doubleword of this segment with the lower doubleword of the corresponding segment of `zm_f64`. The range of the immediate argument in `svextq` would be 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}`
1 parent ced2fc7 commit 2a0162c

File tree

6 files changed

+118
-48
lines changed

6 files changed

+118
-48
lines changed

clang/include/clang/Basic/arm_sve.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2286,7 +2286,7 @@ let SVETargetGuard = "sve2p1", SMETargetGuard = InvalidMode in {
22862286
def SVTBLQ : SInst<"svtblq[_{d}]", "ddu", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_tblq">;
22872287
def SVTBXQ : SInst<"svtbxq[_{d}]", "dddu", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_tbxq">;
22882288
// EXTQ
2289-
def EXTQ : SInst<"svextq[_{d}]", "dddk", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_extq", [], [ImmCheck<2, ImmCheck0_15>]>;
2289+
def EXTQ : SInst<"svextq[_{d}]", "dddk", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_extq", [], [ImmCheck<2, ImmCheckLaneIndex, 0>]>;
22902290

22912291
// PMOV
22922292
// Move to Pred

clang/test/CodeGen/AArch64/sve2p1-intrinsics/acle_sve2p1_extq.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -103,111 +103,111 @@ svuint32_t test_svextq_u32(svuint32_t zn, svuint32_t zm) {
103103
// CHECK-LABEL: define dso_local <vscale x 4 x i32> @test_svextq_s32
104104
// CHECK-SAME: (<vscale x 4 x i32> [[ZN:%.*]], <vscale x 4 x i32> [[ZM:%.*]]) #[[ATTR0]] {
105105
// CHECK-NEXT: entry:
106-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.aarch64.sve.extq.nxv4i32(<vscale x 4 x i32> [[ZN]], <vscale x 4 x i32> [[ZM]], i32 6)
106+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.aarch64.sve.extq.nxv4i32(<vscale x 4 x i32> [[ZN]], <vscale x 4 x i32> [[ZM]], i32 3)
107107
// CHECK-NEXT: ret <vscale x 4 x i32> [[TMP0]]
108108
//
109109
// CPP-CHECK-LABEL: define dso_local <vscale x 4 x i32> @_Z15test_svextq_s32u11__SVInt32_tS_
110110
// CPP-CHECK-SAME: (<vscale x 4 x i32> [[ZN:%.*]], <vscale x 4 x i32> [[ZM:%.*]]) #[[ATTR0]] {
111111
// CPP-CHECK-NEXT: entry:
112-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.aarch64.sve.extq.nxv4i32(<vscale x 4 x i32> [[ZN]], <vscale x 4 x i32> [[ZM]], i32 6)
112+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.aarch64.sve.extq.nxv4i32(<vscale x 4 x i32> [[ZN]], <vscale x 4 x i32> [[ZM]], i32 3)
113113
// CPP-CHECK-NEXT: ret <vscale x 4 x i32> [[TMP0]]
114114
//
115115
svint32_t test_svextq_s32(svint32_t zn, svint32_t zm) {
116-
return SVE_ACLE_FUNC(svextq, _s32,,)(zn, zm, 6);
116+
return SVE_ACLE_FUNC(svextq, _s32,,)(zn, zm, 3);
117117
}
118118

119119
// CHECK-LABEL: define dso_local <vscale x 2 x i64> @test_svextq_u64
120120
// CHECK-SAME: (<vscale x 2 x i64> [[ZN:%.*]], <vscale x 2 x i64> [[ZM:%.*]]) #[[ATTR0]] {
121121
// CHECK-NEXT: entry:
122-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 3)
122+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 1)
123123
// CHECK-NEXT: ret <vscale x 2 x i64> [[TMP0]]
124124
//
125125
// CPP-CHECK-LABEL: define dso_local <vscale x 2 x i64> @_Z15test_svextq_u64u12__SVUint64_tS_
126126
// CPP-CHECK-SAME: (<vscale x 2 x i64> [[ZN:%.*]], <vscale x 2 x i64> [[ZM:%.*]]) #[[ATTR0]] {
127127
// CPP-CHECK-NEXT: entry:
128-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 3)
128+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 1)
129129
// CPP-CHECK-NEXT: ret <vscale x 2 x i64> [[TMP0]]
130130
//
131131
svuint64_t test_svextq_u64(svuint64_t zn, svuint64_t zm) {
132-
return SVE_ACLE_FUNC(svextq, _u64,,)(zn, zm, 3);
132+
return SVE_ACLE_FUNC(svextq, _u64,,)(zn, zm, 1);
133133
}
134134

135135
// CHECK-LABEL: define dso_local <vscale x 2 x i64> @test_svextq_s64
136136
// CHECK-SAME: (<vscale x 2 x i64> [[ZN:%.*]], <vscale x 2 x i64> [[ZM:%.*]]) #[[ATTR0]] {
137137
// CHECK-NEXT: entry:
138-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 7)
138+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 0)
139139
// CHECK-NEXT: ret <vscale x 2 x i64> [[TMP0]]
140140
//
141141
// CPP-CHECK-LABEL: define dso_local <vscale x 2 x i64> @_Z15test_svextq_s64u11__SVInt64_tS_
142142
// CPP-CHECK-SAME: (<vscale x 2 x i64> [[ZN:%.*]], <vscale x 2 x i64> [[ZM:%.*]]) #[[ATTR0]] {
143143
// CPP-CHECK-NEXT: entry:
144-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 7)
144+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.aarch64.sve.extq.nxv2i64(<vscale x 2 x i64> [[ZN]], <vscale x 2 x i64> [[ZM]], i32 0)
145145
// CPP-CHECK-NEXT: ret <vscale x 2 x i64> [[TMP0]]
146146
//
147147
svint64_t test_svextq_s64(svint64_t zn, svint64_t zm) {
148-
return SVE_ACLE_FUNC(svextq, _s64,,)(zn, zm, 7);
148+
return SVE_ACLE_FUNC(svextq, _s64,,)(zn, zm, 0);
149149
}
150150

151151
// CHECK-LABEL: define dso_local <vscale x 8 x half> @test_svextq_f16
152152
// CHECK-SAME: (<vscale x 8 x half> [[ZN:%.*]], <vscale x 8 x half> [[ZM:%.*]]) #[[ATTR0]] {
153153
// CHECK-NEXT: entry:
154-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x half> @llvm.aarch64.sve.extq.nxv8f16(<vscale x 8 x half> [[ZN]], <vscale x 8 x half> [[ZM]], i32 8)
154+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x half> @llvm.aarch64.sve.extq.nxv8f16(<vscale x 8 x half> [[ZN]], <vscale x 8 x half> [[ZM]], i32 7)
155155
// CHECK-NEXT: ret <vscale x 8 x half> [[TMP0]]
156156
//
157157
// CPP-CHECK-LABEL: define dso_local <vscale x 8 x half> @_Z15test_svextq_f16u13__SVFloat16_tS_
158158
// CPP-CHECK-SAME: (<vscale x 8 x half> [[ZN:%.*]], <vscale x 8 x half> [[ZM:%.*]]) #[[ATTR0]] {
159159
// CPP-CHECK-NEXT: entry:
160-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x half> @llvm.aarch64.sve.extq.nxv8f16(<vscale x 8 x half> [[ZN]], <vscale x 8 x half> [[ZM]], i32 8)
160+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x half> @llvm.aarch64.sve.extq.nxv8f16(<vscale x 8 x half> [[ZN]], <vscale x 8 x half> [[ZM]], i32 7)
161161
// CPP-CHECK-NEXT: ret <vscale x 8 x half> [[TMP0]]
162162
//
163163
svfloat16_t test_svextq_f16(svfloat16_t zn, svfloat16_t zm) {
164-
return SVE_ACLE_FUNC(svextq, _f16,,)(zn, zm, 8);
164+
return SVE_ACLE_FUNC(svextq, _f16,,)(zn, zm, 7);
165165
}
166166

167167
// CHECK-LABEL: define dso_local <vscale x 4 x float> @test_svextq_f32
168168
// CHECK-SAME: (<vscale x 4 x float> [[ZN:%.*]], <vscale x 4 x float> [[ZM:%.*]]) #[[ATTR0]] {
169169
// CHECK-NEXT: entry:
170-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.extq.nxv4f32(<vscale x 4 x float> [[ZN]], <vscale x 4 x float> [[ZM]], i32 9)
170+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.extq.nxv4f32(<vscale x 4 x float> [[ZN]], <vscale x 4 x float> [[ZM]], i32 2)
171171
// CHECK-NEXT: ret <vscale x 4 x float> [[TMP0]]
172172
//
173173
// CPP-CHECK-LABEL: define dso_local <vscale x 4 x float> @_Z15test_svextq_f32u13__SVFloat32_tS_
174174
// CPP-CHECK-SAME: (<vscale x 4 x float> [[ZN:%.*]], <vscale x 4 x float> [[ZM:%.*]]) #[[ATTR0]] {
175175
// CPP-CHECK-NEXT: entry:
176-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.extq.nxv4f32(<vscale x 4 x float> [[ZN]], <vscale x 4 x float> [[ZM]], i32 9)
176+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x float> @llvm.aarch64.sve.extq.nxv4f32(<vscale x 4 x float> [[ZN]], <vscale x 4 x float> [[ZM]], i32 2)
177177
// CPP-CHECK-NEXT: ret <vscale x 4 x float> [[TMP0]]
178178
//
179179
svfloat32_t test_svextq_f32(svfloat32_t zn, svfloat32_t zm) {
180-
return SVE_ACLE_FUNC(svextq, _f32,,)(zn, zm, 9);
180+
return SVE_ACLE_FUNC(svextq, _f32,,)(zn, zm, 2);
181181
}
182182

183183
// CHECK-LABEL: define dso_local <vscale x 2 x double> @test_svextq_f64
184184
// CHECK-SAME: (<vscale x 2 x double> [[ZN:%.*]], <vscale x 2 x double> [[ZM:%.*]]) #[[ATTR0]] {
185185
// CHECK-NEXT: entry:
186-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.extq.nxv2f64(<vscale x 2 x double> [[ZN]], <vscale x 2 x double> [[ZM]], i32 10)
186+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.extq.nxv2f64(<vscale x 2 x double> [[ZN]], <vscale x 2 x double> [[ZM]], i32 0)
187187
// CHECK-NEXT: ret <vscale x 2 x double> [[TMP0]]
188188
//
189189
// CPP-CHECK-LABEL: define dso_local <vscale x 2 x double> @_Z15test_svextq_f64u13__SVFloat64_tS_
190190
// CPP-CHECK-SAME: (<vscale x 2 x double> [[ZN:%.*]], <vscale x 2 x double> [[ZM:%.*]]) #[[ATTR0]] {
191191
// CPP-CHECK-NEXT: entry:
192-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.extq.nxv2f64(<vscale x 2 x double> [[ZN]], <vscale x 2 x double> [[ZM]], i32 10)
192+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.extq.nxv2f64(<vscale x 2 x double> [[ZN]], <vscale x 2 x double> [[ZM]], i32 0)
193193
// CPP-CHECK-NEXT: ret <vscale x 2 x double> [[TMP0]]
194194
//
195195
svfloat64_t test_svextq_f64(svfloat64_t zn, svfloat64_t zm) {
196-
return SVE_ACLE_FUNC(svextq, _f64,,)(zn, zm, 10);
196+
return SVE_ACLE_FUNC(svextq, _f64,,)(zn, zm, 0);
197197
}
198198

199199
// CHECK-LABEL: define dso_local <vscale x 8 x bfloat> @test_svextq_bf16
200200
// CHECK-SAME: (<vscale x 8 x bfloat> [[ZN:%.*]], <vscale x 8 x bfloat> [[ZM:%.*]]) #[[ATTR0]] {
201201
// CHECK-NEXT: entry:
202-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.aarch64.sve.extq.nxv8bf16(<vscale x 8 x bfloat> [[ZN]], <vscale x 8 x bfloat> [[ZM]], i32 11)
202+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.aarch64.sve.extq.nxv8bf16(<vscale x 8 x bfloat> [[ZN]], <vscale x 8 x bfloat> [[ZM]], i32 6)
203203
// CHECK-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
204204
//
205205
// CPP-CHECK-LABEL: define dso_local <vscale x 8 x bfloat> @_Z16test_svextq_bf16u14__SVBfloat16_tS_
206206
// CPP-CHECK-SAME: (<vscale x 8 x bfloat> [[ZN:%.*]], <vscale x 8 x bfloat> [[ZM:%.*]]) #[[ATTR0]] {
207207
// CPP-CHECK-NEXT: entry:
208-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.aarch64.sve.extq.nxv8bf16(<vscale x 8 x bfloat> [[ZN]], <vscale x 8 x bfloat> [[ZM]], i32 11)
208+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.aarch64.sve.extq.nxv8bf16(<vscale x 8 x bfloat> [[ZN]], <vscale x 8 x bfloat> [[ZM]], i32 6)
209209
// CPP-CHECK-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
210210
//
211211
svbfloat16_t test_svextq_bf16(svbfloat16_t zn, svbfloat16_t zm) {
212-
return SVE_ACLE_FUNC(svextq, _bf16,,)(zn, zm, 11);
212+
return SVE_ACLE_FUNC(svextq, _bf16,,)(zn, zm, 6);
213213
}

clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,47 @@ void test_svbfmul_lane(svbfloat16_t zn, svbfloat16_t zm, uint64_t idx){
138138
}
139139

140140
__attribute__((target("+sve2p1")))
141-
void test_svextq_lane(svint16_t zn_i16, svint16_t zm_i16, svfloat16_t zn_f16, svfloat16_t zm_f16){
142-
svextq_s16(zn_i16, zm_i16, -1); // expected-error {{argument value -1 is outside the valid range [0, 15]}}
143-
svextq_f16(zn_f16, zm_f16, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
141+
void test_svextq_8b_offset(svint8_t s8, svuint8_t u8){
142+
svextq_s8(s8, s8, -1); // expected-error {{argument value -1 is outside the valid range [0, 15]}}
143+
svextq_u8(u8, u8, -1); // expected-error {{argument value -1 is outside the valid range [0, 15]}}
144+
145+
svextq_s8(s8, s8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
146+
svextq_u8(u8, u8, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
147+
}
148+
149+
__attribute__((target("+sve2p1")))
150+
void test_svextq_16b_offset(svint16_t s16, svuint16_t u16, svfloat16_t f16, svbfloat16_t bf16){
151+
svextq_s16(s16, s16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}}
152+
svextq_u16(u16, u16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}}
153+
svextq_f16(f16, f16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}}
154+
svextq_bf16(bf16, bf16, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}}
155+
156+
svextq_s16(s16, s16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
157+
svextq_u16(u16, u16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
158+
svextq_f16(f16, f16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
159+
svextq_bf16(bf16, bf16, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}}
160+
}
161+
162+
__attribute__((target("+sve2p1")))
163+
void test_svextq_32b_offset(svint32_t s32, svuint32_t u32, svfloat32_t f32){
164+
svextq_s32(s32, s32, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
165+
svextq_u32(u32, u32, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
166+
svextq_f32(f32, f32, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
167+
168+
svextq_s32(s32, s32, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
169+
svextq_u32(u32, u32, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
170+
svextq_f32(f32, f32, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
171+
}
172+
173+
__attribute__((target("+sve2p1")))
174+
void test_svextq_64b_offset(svint64_t s64, svuint64_t u64, svfloat64_t f64){
175+
svextq_s64(s64, s64, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
176+
svextq_u64(u64, u64, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
177+
svextq_f64(f64, f64, -1); // expected-error {{argument value -1 is outside the valid range [0, 1]}}
178+
179+
svextq_s64(s64, s64, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
180+
svextq_u64(u64, u64, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
181+
svextq_f64(f64, f64, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
144182
}
145183

146184
__attribute__((target("+sve2p1")))

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,18 @@ def UImmS8XForm : SDNodeXForm<imm, [{
529529
return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);
530530
}]>;
531531

532+
def UImmM2XForm : SDNodeXForm<imm, [{
533+
return CurDAG->getTargetConstant(N->getZExtValue() * 2, SDLoc(N), MVT::i32);
534+
}]>;
535+
536+
def UImmM4XForm : SDNodeXForm<imm, [{
537+
return CurDAG->getTargetConstant(N->getZExtValue() * 4, SDLoc(N), MVT::i32);
538+
}]>;
539+
540+
def UImmM8XForm : SDNodeXForm<imm, [{
541+
return CurDAG->getTargetConstant(N->getZExtValue() * 8, SDLoc(N), MVT::i32);
542+
}]>;
543+
532544
// uimm5sN predicate - True if the immediate is a multiple of N in the range
533545
// [0 * N, 32 * N].
534546
def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
@@ -1098,6 +1110,13 @@ def timm32_0_1 : Operand<i32>, TImmLeaf<i32, [{
10981110
let ParserMatchClass = Imm0_1Operand;
10991111
}
11001112

1113+
// extq_timm32_0_1m8 - True if the 32-bit immediate is in the range [0,1], scale this immediate
1114+
// by a factor of 8 after a match is made.
1115+
def extq_timm32_0_1m8 : Operand<i32>, TImmLeaf<i32, [{
1116+
return ((uint32_t)Imm) < 2;}], UImmM8XForm> {
1117+
let ParserMatchClass = Imm0_15Operand;
1118+
}
1119+
11011120
// timm32_1_1 - True if the 32-bit immediate is in the range [1,1]
11021121
def timm32_1_1 : Operand<i32>, TImmLeaf<i32, [{
11031122
return ((uint32_t)Imm) == 1;
@@ -1140,13 +1159,27 @@ def timm32_0_3 : Operand<i32>, TImmLeaf<i32, [{
11401159
let ParserMatchClass = Imm0_3Operand;
11411160
}
11421161

1162+
// extq_timm32_0_3m4 - True if the 32-bit immediate is in the range [0,3], scale this immediate
1163+
// by a factor of 4 after a match is made.
1164+
def extq_timm32_0_3m4 : Operand<i32>, TImmLeaf<i32, [{
1165+
return ((uint32_t)Imm) < 4;}], UImmM4XForm> {
1166+
let ParserMatchClass = Imm0_15Operand;
1167+
}
1168+
11431169
// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]
11441170
def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{
11451171
return ((uint32_t)Imm) < 8;
11461172
}]> {
11471173
let ParserMatchClass = Imm0_7Operand;
11481174
}
11491175

1176+
// extq_timm32_0_7m2 - True if the 32-bit immediate is in the range [0,7], scale this immediate
1177+
// by a factor of 2 after a match is made.
1178+
def extq_timm32_0_7m2 : Operand<i32>, TImmLeaf<i32, [{
1179+
return ((uint32_t)Imm) < 8;}], UImmM2XForm> {
1180+
let ParserMatchClass = Imm0_15Operand;
1181+
}
1182+
11501183
// timm32_1_7 predicate - True if the 32-bit immediate is in the range [1,7]
11511184
def timm32_1_7 : Operand<i32>, TImmLeaf<i32, [{
11521185
return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 8;

llvm/lib/Target/AArch64/SVEInstrFormats.td

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10459,15 +10459,14 @@ class sve2p1_extq<string mnemonic>
1045910459
multiclass sve2p1_extq<string mnemonic, SDPatternOperator Op> {
1046010460
def NAME : sve2p1_extq<mnemonic>;
1046110461
def : SVE_3_Op_Imm_Pat<nxv16i8, Op, nxv16i8, nxv16i8, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10462-
def : SVE_3_Op_Imm_Pat<nxv8i16, Op, nxv8i16, nxv8i16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10463-
def : SVE_3_Op_Imm_Pat<nxv4i32, Op, nxv4i32, nxv4i32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10464-
def : SVE_3_Op_Imm_Pat<nxv2i64, Op, nxv2i64, nxv2i64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10465-
10466-
def : SVE_3_Op_Imm_Pat<nxv8f16, Op, nxv8f16, nxv8f16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10467-
def : SVE_3_Op_Imm_Pat<nxv4f32, Op, nxv4f32, nxv4f32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10468-
def : SVE_3_Op_Imm_Pat<nxv2f64, Op, nxv2f64, nxv2f64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10469-
def : SVE_3_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, nxv8bf16, i32, timm32_0_15, !cast<Instruction>(NAME
10470-
)>;
10462+
def : SVE_3_Op_Imm_Pat<nxv8i16, Op, nxv8i16, nxv8i16, i32, extq_timm32_0_7m2, !cast<Instruction>(NAME)>;
10463+
def : SVE_3_Op_Imm_Pat<nxv4i32, Op, nxv4i32, nxv4i32, i32, extq_timm32_0_3m4, !cast<Instruction>(NAME)>;
10464+
def : SVE_3_Op_Imm_Pat<nxv2i64, Op, nxv2i64, nxv2i64, i32, extq_timm32_0_1m8, !cast<Instruction>(NAME)>;
10465+
10466+
def : SVE_3_Op_Imm_Pat<nxv8f16, Op, nxv8f16, nxv8f16, i32, extq_timm32_0_7m2, !cast<Instruction>(NAME)>;
10467+
def : SVE_3_Op_Imm_Pat<nxv4f32, Op, nxv4f32, nxv4f32, i32, extq_timm32_0_3m4, !cast<Instruction>(NAME)>;
10468+
def : SVE_3_Op_Imm_Pat<nxv2f64, Op, nxv2f64, nxv2f64, i32, extq_timm32_0_1m8, !cast<Instruction>(NAME)>;
10469+
def : SVE_3_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, nxv8bf16, i32, extq_timm32_0_7m2, !cast<Instruction>(NAME)>;
1047110470
}
1047210471

1047310472
// SVE move predicate from vector

0 commit comments

Comments
 (0)