Skip to content

Commit fc3417c

Browse files
committed
[ARM][MVE][Intrinsics] Add VQADDQ, VHADDQ, VRHADDQ, VQSUBQ, VHSUBQ, VQDMULHQ, VQRDMULHQ intrinsics.
Summary: Add VQADDQ, VHADDQ, VRHADDQ, VQSUBQ, VHSUBQ, VQDMULHQ, VQRDMULHQ intrinsics and unit tests. Reviewers: simon_tatham, ostannard, dmgreen, miyuki Subscribers: kristof.beyls, hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D71198
1 parent 2eb61fa commit fc3417c

File tree

17 files changed

+1584
-70
lines changed

17 files changed

+1584
-70
lines changed

clang/include/clang/Basic/arm_mve.td

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,51 @@ def "": Intrinsic<Vector, (args Vector:$a, Vector:$b),
3838
(bitcast (bitop (bitcast $a, UVector), (not (bitcast $b, UVector))), Vector)>;
3939
}
4040

41+
let params = T.Signed in {
42+
def vqaddq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
43+
(IRIntBase<"sadd_sat", [Vector]> $a, $b)>;
44+
def vqsubq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
45+
(IRIntBase<"ssub_sat", [Vector]> $a, $b)>;
46+
}
47+
let params = T.Unsigned in {
48+
def vqaddq_u: Intrinsic<Vector, (args Vector:$a, Vector:$b),
49+
(IRIntBase<"uadd_sat", [Vector]> $a, $b)>,
50+
NameOverride<"vqaddq">;
51+
def vqsubq_u: Intrinsic<Vector, (args Vector:$a, Vector:$b),
52+
(IRIntBase<"usub_sat", [Vector]> $a, $b)>,
53+
NameOverride<"vqsubq">;
54+
}
55+
56+
// Some intrinsics below are implemented not as IR fragments, but as
57+
// special-purpose IR intrinsics. This is because such a general form
58+
// (such as NEON uses) required a variable-width vector size, and we are
59+
// restricted to 128 bit. Although we can possibly get clever with lane
60+
// operations, the consequent IR representation would be very hard to
61+
// write sensibly. In particular, doubling a vector's width would be a
62+
// mess. Other intrinsics just don't translate nicely into IR.
4163
let params = T.Int in {
4264
def vaddq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (add $a, $b)>;
65+
def vhaddq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
66+
(IRInt<"vhadd", [Vector]> $a, $b)>;
67+
def vrhaddq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
68+
(IRInt<"vrhadd", [Vector]> $a, $b)>;
4369
def vandq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (and $a, $b)>;
4470
def vbicq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (and $a, (not $b))>;
4571
def veorq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (xor $a, $b)>;
4672
def vornq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (or $a, (not $b))>;
4773
def vorrq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (or $a, $b)>;
4874
def vsubq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (sub $a, $b)>;
75+
def vhsubq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
76+
(IRInt<"vhsub", [Vector]> $a, $b)>;
4977
def vmulq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (mul $a, $b)>;
5078
def vmulhq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
51-
(IRInt<"vmulh", [Vector]> $a, $b)>;
79+
(IRInt<"vmulh", [Vector]> $a, $b)>;
5280
def vrmulhq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
53-
(IRInt<"vrmulh", [Vector]> $a, $b)>;
81+
(IRInt<"vrmulh", [Vector]> $a, $b)>;
82+
def vqdmulhq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
83+
(IRInt<"vqdmulh", [Vector]> $a, $b)>;
84+
def vqrdmulhq: Intrinsic<Vector, (args Vector:$a, Vector:$b),
85+
(IRInt<"vqrdmulh", [Vector]> $a, $b)>;
5486
def vmullbq_int: Intrinsic<DblVector, (args Vector:$a, Vector:$b),
5587
(IRInt<"vmull", [DblVector, Vector]>
5688
$a, $b, 0)>;
@@ -138,6 +170,12 @@ def vmulhq_m: Intrinsic<
138170
def vrmulhq_m: Intrinsic<
139171
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
140172
(IRInt<"rmulh_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
173+
def vqdmulhq_m: Intrinsic<
174+
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
175+
(IRInt<"qdmulh_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
176+
def vqrdmulhq_m: Intrinsic<
177+
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
178+
(IRInt<"qrdmulh_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
141179
def vmullbq_int_m: Intrinsic<
142180
DblVector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
143181
(IRInt<"mull_int_predicated", [DblVector, Vector, Predicate]> $a, $b, 0,
@@ -146,6 +184,21 @@ def vmulltq_int_m: Intrinsic<
146184
DblVector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
147185
(IRInt<"mull_int_predicated", [DblVector, Vector, Predicate]> $a, $b, 1,
148186
$pred, $inactive)>;
187+
def vqaddq_m: Intrinsic<
188+
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
189+
(IRInt<"qadd_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
190+
def vhaddq_m: Intrinsic<
191+
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
192+
(IRInt<"hadd_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
193+
def vrhaddq_m: Intrinsic<
194+
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
195+
(IRInt<"rhadd_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
196+
def vqsubq_m: Intrinsic<
197+
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
198+
(IRInt<"qsub_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
199+
def vhsubq_m: Intrinsic<
200+
Vector, (args Vector:$inactive, Vector:$a, Vector:$b, Predicate:$pred),
201+
(IRInt<"hsub_predicated", [Vector, Predicate]> $a, $b, $pred, $inactive)>;
149202
}
150203

151204
let params = T.Poly, overrideKindLetter = "p" in {
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
3+
// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
4+
5+
#include <arm_mve.h>
6+
7+
// CHECK-LABEL: @test_vhaddq_u8(
8+
// CHECK-NEXT: entry:
9+
// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.arm.mve.vhadd.v16i8(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]])
10+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
11+
//
12+
uint8x16_t test_vhaddq_u8(uint8x16_t a, uint8x16_t b)
13+
{
14+
#ifdef POLYMORPHIC
15+
return vhaddq(a, b);
16+
#else /* POLYMORPHIC */
17+
return vhaddq_u8(a, b);
18+
#endif /* POLYMORPHIC */
19+
}
20+
21+
// CHECK-LABEL: @test_vhaddq_s16(
22+
// CHECK-NEXT: entry:
23+
// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i16> @llvm.arm.mve.vhadd.v8i16(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]])
24+
// CHECK-NEXT: ret <8 x i16> [[TMP0]]
25+
//
26+
int16x8_t test_vhaddq_s16(int16x8_t a, int16x8_t b)
27+
{
28+
#ifdef POLYMORPHIC
29+
return vhaddq(a, b);
30+
#else /* POLYMORPHIC */
31+
return vhaddq_s16(a, b);
32+
#endif /* POLYMORPHIC */
33+
}
34+
35+
// CHECK-LABEL: @test_vhaddq_u32(
36+
// CHECK-NEXT: entry:
37+
// CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.arm.mve.vhadd.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]])
38+
// CHECK-NEXT: ret <4 x i32> [[TMP0]]
39+
//
40+
uint32x4_t test_vhaddq_u32(uint32x4_t a, uint32x4_t b)
41+
{
42+
#ifdef POLYMORPHIC
43+
return vhaddq(a, b);
44+
#else /* POLYMORPHIC */
45+
return vhaddq_u32(a, b);
46+
#endif /* POLYMORPHIC */
47+
}
48+
49+
// CHECK-LABEL: @test_vhaddq_m_s8(
50+
// CHECK-NEXT: entry:
51+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
52+
// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]])
53+
// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.hadd.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]])
54+
// CHECK-NEXT: ret <16 x i8> [[TMP2]]
55+
//
56+
int8x16_t test_vhaddq_m_s8(int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
57+
{
58+
#ifdef POLYMORPHIC
59+
return vhaddq_m(inactive, a, b, p);
60+
#else /* POLYMORPHIC */
61+
return vhaddq_m_s8(inactive, a, b, p);
62+
#endif /* POLYMORPHIC */
63+
}
64+
65+
// CHECK-LABEL: @test_vhaddq_m_u16(
66+
// CHECK-NEXT: entry:
67+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
68+
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
69+
// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.hadd.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]])
70+
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
71+
//
72+
uint16x8_t test_vhaddq_m_u16(uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
73+
{
74+
#ifdef POLYMORPHIC
75+
return vhaddq_m(inactive, a, b, p);
76+
#else /* POLYMORPHIC */
77+
return vhaddq_m_u16(inactive, a, b, p);
78+
#endif /* POLYMORPHIC */
79+
}
80+
81+
// CHECK-LABEL: @test_vhaddq_m_s32(
82+
// CHECK-NEXT: entry:
83+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
84+
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
85+
// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.hadd.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]])
86+
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
87+
//
88+
int32x4_t test_vhaddq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
89+
{
90+
#ifdef POLYMORPHIC
91+
return vhaddq_m(inactive, a, b, p);
92+
#else /* POLYMORPHIC */
93+
return vhaddq_m_s32(inactive, a, b, p);
94+
#endif /* POLYMORPHIC */
95+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
3+
// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
4+
5+
#include <arm_mve.h>
6+
7+
// CHECK-LABEL: @test_vhsubq_u8(
8+
// CHECK-NEXT: entry:
9+
// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.arm.mve.vhsub.v16i8(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]])
10+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
11+
//
12+
uint8x16_t test_vhsubq_u8(uint8x16_t a, uint8x16_t b)
13+
{
14+
#ifdef POLYMORPHIC
15+
return vhsubq(a, b);
16+
#else /* POLYMORPHIC */
17+
return vhsubq_u8(a, b);
18+
#endif /* POLYMORPHIC */
19+
}
20+
21+
// CHECK-LABEL: @test_vhsubq_s16(
22+
// CHECK-NEXT: entry:
23+
// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i16> @llvm.arm.mve.vhsub.v8i16(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]])
24+
// CHECK-NEXT: ret <8 x i16> [[TMP0]]
25+
//
26+
int16x8_t test_vhsubq_s16(int16x8_t a, int16x8_t b)
27+
{
28+
#ifdef POLYMORPHIC
29+
return vhsubq(a, b);
30+
#else /* POLYMORPHIC */
31+
return vhsubq_s16(a, b);
32+
#endif /* POLYMORPHIC */
33+
}
34+
35+
// CHECK-LABEL: @test_vhsubq_u32(
36+
// CHECK-NEXT: entry:
37+
// CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.arm.mve.vhsub.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]])
38+
// CHECK-NEXT: ret <4 x i32> [[TMP0]]
39+
//
40+
uint32x4_t test_vhsubq_u32(uint32x4_t a, uint32x4_t b)
41+
{
42+
#ifdef POLYMORPHIC
43+
return vhsubq(a, b);
44+
#else /* POLYMORPHIC */
45+
return vhsubq_u32(a, b);
46+
#endif /* POLYMORPHIC */
47+
}
48+
49+
// CHECK-LABEL: @test_vhsubq_m_s8(
50+
// CHECK-NEXT: entry:
51+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
52+
// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]])
53+
// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.hsub.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]])
54+
// CHECK-NEXT: ret <16 x i8> [[TMP2]]
55+
//
56+
int8x16_t test_vhsubq_m_s8(int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
57+
{
58+
#ifdef POLYMORPHIC
59+
return vhsubq_m(inactive, a, b, p);
60+
#else /* POLYMORPHIC */
61+
return vhsubq_m_s8(inactive, a, b, p);
62+
#endif /* POLYMORPHIC */
63+
}
64+
65+
// CHECK-LABEL: @test_vhsubq_m_u16(
66+
// CHECK-NEXT: entry:
67+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
68+
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
69+
// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.hsub.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]])
70+
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
71+
//
72+
uint16x8_t test_vhsubq_m_u16(uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
73+
{
74+
#ifdef POLYMORPHIC
75+
return vhsubq_m(inactive, a, b, p);
76+
#else /* POLYMORPHIC */
77+
return vhsubq_m_u16(inactive, a, b, p);
78+
#endif /* POLYMORPHIC */
79+
}
80+
81+
// CHECK-LABEL: @test_vhsubq_m_s32(
82+
// CHECK-NEXT: entry:
83+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
84+
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
85+
// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.hsub.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]])
86+
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
87+
//
88+
int32x4_t test_vhsubq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
89+
{
90+
#ifdef POLYMORPHIC
91+
return vhsubq_m(inactive, a, b, p);
92+
#else /* POLYMORPHIC */
93+
return vhsubq_m_s32(inactive, a, b, p);
94+
#endif /* POLYMORPHIC */
95+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
3+
// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
4+
5+
#include <arm_mve.h>
6+
7+
// CHECK-LABEL: @test_vqaddq_u8(
8+
// CHECK-NEXT: entry:
9+
// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]])
10+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
11+
//
12+
uint8x16_t test_vqaddq_u8(uint8x16_t a, uint8x16_t b)
13+
{
14+
#ifdef POLYMORPHIC
15+
return vqaddq(a, b);
16+
#else /* POLYMORPHIC */
17+
return vqaddq_u8(a, b);
18+
#endif /* POLYMORPHIC */
19+
}
20+
21+
// CHECK-LABEL: @test_vqaddq_s16(
22+
// CHECK-NEXT: entry:
23+
// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]])
24+
// CHECK-NEXT: ret <8 x i16> [[TMP0]]
25+
//
26+
int16x8_t test_vqaddq_s16(int16x8_t a, int16x8_t b)
27+
{
28+
#ifdef POLYMORPHIC
29+
return vqaddq(a, b);
30+
#else /* POLYMORPHIC */
31+
return vqaddq_s16(a, b);
32+
#endif /* POLYMORPHIC */
33+
}
34+
35+
// CHECK-LABEL: @test_vqaddq_u32(
36+
// CHECK-NEXT: entry:
37+
// CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]])
38+
// CHECK-NEXT: ret <4 x i32> [[TMP0]]
39+
//
40+
uint32x4_t test_vqaddq_u32(uint32x4_t a, uint32x4_t b)
41+
{
42+
#ifdef POLYMORPHIC
43+
return vqaddq(a, b);
44+
#else /* POLYMORPHIC */
45+
return vqaddq_u32(a, b);
46+
#endif /* POLYMORPHIC */
47+
}
48+
49+
// CHECK-LABEL: @test_vqaddq_m_s8(
50+
// CHECK-NEXT: entry:
51+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
52+
// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]])
53+
// CHECK-NEXT: [[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.qadd.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]], <16 x i8> [[INACTIVE:%.*]])
54+
// CHECK-NEXT: ret <16 x i8> [[TMP2]]
55+
//
56+
int8x16_t test_vqaddq_m_s8(int8x16_t inactive, int8x16_t a, int8x16_t b, mve_pred16_t p)
57+
{
58+
#ifdef POLYMORPHIC
59+
return vqaddq_m(inactive, a, b, p);
60+
#else /* POLYMORPHIC */
61+
return vqaddq_m_s8(inactive, a, b, p);
62+
#endif /* POLYMORPHIC */
63+
}
64+
65+
// CHECK-LABEL: @test_vqaddq_m_u16(
66+
// CHECK-NEXT: entry:
67+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
68+
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
69+
// CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.arm.mve.qadd.predicated.v8i16.v8i1(<8 x i16> [[A:%.*]], <8 x i16> [[B:%.*]], <8 x i1> [[TMP1]], <8 x i16> [[INACTIVE:%.*]])
70+
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
71+
//
72+
uint16x8_t test_vqaddq_m_u16(uint16x8_t inactive, uint16x8_t a, uint16x8_t b, mve_pred16_t p)
73+
{
74+
#ifdef POLYMORPHIC
75+
return vqaddq_m(inactive, a, b, p);
76+
#else /* POLYMORPHIC */
77+
return vqaddq_m_u16(inactive, a, b, p);
78+
#endif /* POLYMORPHIC */
79+
}
80+
81+
// CHECK-LABEL: @test_vqaddq_m_s32(
82+
// CHECK-NEXT: entry:
83+
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
84+
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
85+
// CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.arm.mve.qadd.predicated.v4i32.v4i1(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i1> [[TMP1]], <4 x i32> [[INACTIVE:%.*]])
86+
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
87+
//
88+
int32x4_t test_vqaddq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, mve_pred16_t p)
89+
{
90+
#ifdef POLYMORPHIC
91+
return vqaddq_m(inactive, a, b, p);
92+
#else /* POLYMORPHIC */
93+
return vqaddq_m_s32(inactive, a, b, p);
94+
#endif /* POLYMORPHIC */
95+
}

0 commit comments

Comments
 (0)