2018-12-06 06:03:04 +08:00
|
|
|
// RUN: %clang_cc1 -triple hexagon -target-cpu hexagonv66 -target-feature +hvxv66 -target-feature +hvx-length64b -emit-llvm -o - %s | FileCheck %s
|
|
|
|
// REQUIRES: hexagon-registered-target
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test1
|
|
|
|
// CHECK: call i32 @llvm.hexagon.M2.mnaci(i32 %0, i32 %1, i32 %2)
|
|
|
|
int test1(int rx, int rs, int rt) {
|
|
|
|
return __builtin_HEXAGON_M2_mnaci(rx, rs, rt);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test2
|
|
|
|
// CHECK: call double @llvm.hexagon.F2.dfadd(double %0, double %1)
|
|
|
|
double test2(double rss, double rtt) {
|
|
|
|
return __builtin_HEXAGON_F2_dfadd(rss, rtt);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test3
|
|
|
|
// CHECK: call double @llvm.hexagon.F2.dfsub(double %0, double %1)
|
|
|
|
double test3(double rss, double rtt) {
|
|
|
|
return __builtin_HEXAGON_F2_dfsub(rss, rtt);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test4
|
|
|
|
// CHECK: call i32 @llvm.hexagon.S2.mask(i32 1, i32 2)
|
|
|
|
int test4() {
|
|
|
|
return __builtin_HEXAGON_S2_mask(1, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef long HEXAGON_VecPred64 __attribute__((__vector_size__(64)))
|
|
|
|
__attribute__((aligned(64)));
|
|
|
|
typedef long HEXAGON_Vect512 __attribute__((__vector_size__(64)))
|
|
|
|
__attribute__((aligned(64)));
|
|
|
|
typedef long HEXAGON_Vect1024 __attribute__((__vector_size__(128)))
|
|
|
|
__attribute__((aligned(128)));
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test5
|
2020-02-07 23:33:18 +08:00
|
|
|
// CHECK: call <16 x i32> @llvm.hexagon.V6.vaddcarrysat(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}}, <64 x i1> %{{[0-9]+}})
|
2018-12-06 06:03:04 +08:00
|
|
|
HEXAGON_Vect512 test5(void *in, void *out) {
|
|
|
|
HEXAGON_Vect512 v1, v2;
|
|
|
|
HEXAGON_Vect512 *p;
|
|
|
|
HEXAGON_VecPred64 q1;
|
|
|
|
|
|
|
|
p = (HEXAGON_Vect512 *)in;
|
|
|
|
v1 = *p++;
|
|
|
|
v2 = *p++;
|
|
|
|
q1 = *p++;
|
|
|
|
|
[Hexagon] Make conversions to vector predicate types explicit for builtins
HVX does not have load/store instructions for vector predicates (i.e. bool
vectors). Because of that, vector predicates need to be converted to another
type before being stored, and the most convenient representation is an HVX
vector.
As a consequence, in C/C++, source-level builtins that either take or
produce vector predicates take or return regular vectors instead. On the
other hand, the corresponding LLVM intrinsics do have boolean types that,
and so a conversion of the operand or the return value was necessary.
This conversion would happen inside clang's codegen, but was somewhat
fragile.
This patch changes the strategy: a builtin that takes a vector predicate
now really expects a vector predicate. Since such a predicate cannot be
provided via a variable, this builtin must be composed with other builtins
that either convert vector to a predicate (V6_vandvrt) or predicate to a
vector (V6_vandqrt).
For users using builtins defined in hvx_hexagon_protos.h there is no impact:
the conversions were added to that file. Other users will need to insert
- __builtin_HEXAGON_V6_vandvrt[_128B](V, -1) to convert vector V to a
vector predicate, or
- __builtin_HEXAGON_V6_vandqrt[_128B](Q, -1) to convert vector predicate Q
to a vector.
Builtins __builtin_HEXAGON_V6_vmaskedstore.* are a temporary exception to
that, but they are deprecated and should not be used anyway. In the future
they will either follow the same rule, or be removed.
2021-12-23 03:29:36 +08:00
|
|
|
return __builtin_HEXAGON_V6_vaddcarrysat(v1, v2, __builtin_HEXAGON_V6_vandvrt(q1, -1));
|
2018-12-06 06:03:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test6
|
|
|
|
// CHECK: call <16 x i32> @llvm.hexagon.V6.vrotr(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
|
|
|
|
HEXAGON_Vect512 test6(void *in, void *out) {
|
|
|
|
HEXAGON_Vect512 v1, v2;
|
|
|
|
HEXAGON_Vect512 *p;
|
|
|
|
|
|
|
|
p = (HEXAGON_Vect512 *)in;
|
|
|
|
v1 = *p++;
|
|
|
|
v2 = *p++;
|
|
|
|
|
|
|
|
return __builtin_HEXAGON_V6_vrotr(v1, v2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test7
|
|
|
|
// CHECK: call <16 x i32> @llvm.hexagon.V6.vsatdw(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
|
|
|
|
HEXAGON_Vect512 test7(void *in, void *out) {
|
|
|
|
HEXAGON_Vect512 v1, v2;
|
|
|
|
HEXAGON_Vect512 *p;
|
|
|
|
|
|
|
|
p = (HEXAGON_Vect512 *)in;
|
|
|
|
v1 = *p++;
|
|
|
|
v2 = *p++;
|
|
|
|
|
|
|
|
return __builtin_HEXAGON_V6_vsatdw(v1, v2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test8
|
|
|
|
// CHECK: call <32 x i32> @llvm.hexagon.V6.vasr.into(<32 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
|
|
|
|
HEXAGON_Vect1024 test8(void *in1, void *in2, void *out) {
|
|
|
|
HEXAGON_Vect512 v1, v2;
|
|
|
|
HEXAGON_Vect512 *p1;
|
|
|
|
HEXAGON_Vect1024 *p2;
|
|
|
|
HEXAGON_Vect1024 vr;
|
|
|
|
|
|
|
|
p1 = (HEXAGON_Vect512 *)in1;
|
|
|
|
v1 = *p1++;
|
|
|
|
v2 = *p1++;
|
|
|
|
p2 = (HEXAGON_Vect1024 *)in2;
|
|
|
|
vr = *p2;
|
|
|
|
|
|
|
|
return __builtin_HEXAGON_V6_vasr_into(vr, v1, v2);
|
|
|
|
}
|