forked from OSchip/llvm-project
ARM NEON: add _f16 support to a couple of vector-shuffling intrinsics.
llvm-svn: 202137
This commit is contained in:
parent
5117553301
commit
87da936164
|
@ -410,9 +410,11 @@ def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST>;
|
||||||
// E.3.19 Set all lanes to same value
|
// E.3.19 Set all lanes to same value
|
||||||
let InstName = "vmov" in {
|
let InstName = "vmov" in {
|
||||||
def VDUP_N : WOpInst<"vdup_n", "ds",
|
def VDUP_N : WOpInst<"vdup_n", "ds",
|
||||||
"UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
|
"UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
|
||||||
|
OP_DUP>;
|
||||||
def VMOV_N : WOpInst<"vmov_n", "ds",
|
def VMOV_N : WOpInst<"vmov_n", "ds",
|
||||||
"UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
|
"UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
|
||||||
|
OP_DUP>;
|
||||||
}
|
}
|
||||||
let InstName = "" in
|
let InstName = "" in
|
||||||
def VDUP_LANE: WOpInst<"vdup_lane", "dgi",
|
def VDUP_LANE: WOpInst<"vdup_lane", "dgi",
|
||||||
|
|
|
@ -1887,6 +1887,12 @@ poly16x4_t test_vdup_n_p16(poly16_t a) {
|
||||||
return vdup_n_p16(a);
|
return vdup_n_p16(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: test_vdup_n_f16
|
||||||
|
// CHECK: vdup.16
|
||||||
|
float16x4_t test_vdup_n_f16(float16_t *a) {
|
||||||
|
return vdup_n_f16(*a);
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK: test_vdup_n_f32
|
// CHECK: test_vdup_n_f32
|
||||||
// CHECK: vmov
|
// CHECK: vmov
|
||||||
float32x2_t test_vdup_n_f32(float32_t a) {
|
float32x2_t test_vdup_n_f32(float32_t a) {
|
||||||
|
@ -1941,6 +1947,12 @@ poly16x8_t test_vdupq_n_p16(poly16_t a) {
|
||||||
return vdupq_n_p16(a);
|
return vdupq_n_p16(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: test_vdupq_n_f16
|
||||||
|
// CHECK: vdup.16
|
||||||
|
float16x8_t test_vdupq_n_f16(float16_t *a) {
|
||||||
|
return vdupq_n_f16(*a);
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK: test_vdupq_n_f32
|
// CHECK: test_vdupq_n_f32
|
||||||
// CHECK: vmov
|
// CHECK: vmov
|
||||||
float32x4_t test_vdupq_n_f32(float32_t a) {
|
float32x4_t test_vdupq_n_f32(float32_t a) {
|
||||||
|
@ -4868,6 +4880,12 @@ poly16x4_t test_vmov_n_p16(poly16_t a) {
|
||||||
return vmov_n_p16(a);
|
return vmov_n_p16(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: test_vmov_n_f16
|
||||||
|
// CHECK: vdup.16
|
||||||
|
float16x4_t test_vmov_n_f16(float16_t *a) {
|
||||||
|
return vmov_n_f16(*a);
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK: test_vmov_n_f32
|
// CHECK: test_vmov_n_f32
|
||||||
// CHECK: vmov
|
// CHECK: vmov
|
||||||
float32x2_t test_vmov_n_f32(float32_t a) {
|
float32x2_t test_vmov_n_f32(float32_t a) {
|
||||||
|
@ -4922,6 +4940,12 @@ poly16x8_t test_vmovq_n_p16(poly16_t a) {
|
||||||
return vmovq_n_p16(a);
|
return vmovq_n_p16(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: test_vmovq_n_f16
|
||||||
|
// CHECK: vdup.16
|
||||||
|
float16x8_t test_vmovq_n_f16(float16_t *a) {
|
||||||
|
return vmovq_n_f16(*a);
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK: test_vmovq_n_f32
|
// CHECK: test_vmovq_n_f32
|
||||||
// CHECK: vmov
|
// CHECK: vmov
|
||||||
float32x4_t test_vmovq_n_f32(float32_t a) {
|
float32x4_t test_vmovq_n_f32(float32_t a) {
|
||||||
|
|
|
@ -1436,7 +1436,7 @@ static void GenerateChecksForIntrinsic(const std::string &Name,
|
||||||
|
|
||||||
/// UseMacro - Examine the prototype string to determine if the intrinsic
|
/// UseMacro - Examine the prototype string to determine if the intrinsic
|
||||||
/// should be defined as a preprocessor macro instead of an inline function.
|
/// should be defined as a preprocessor macro instead of an inline function.
|
||||||
static bool UseMacro(const std::string &proto) {
|
static bool UseMacro(const std::string &proto, StringRef typestr) {
|
||||||
// If this builtin takes an immediate argument, we need to #define it rather
|
// If this builtin takes an immediate argument, we need to #define it rather
|
||||||
// than use a standard declaration, so that SemaChecking can range check
|
// than use a standard declaration, so that SemaChecking can range check
|
||||||
// the immediate passed by the user.
|
// the immediate passed by the user.
|
||||||
|
@ -1449,6 +1449,12 @@ static bool UseMacro(const std::string &proto) {
|
||||||
proto.find('c') != std::string::npos)
|
proto.find('c') != std::string::npos)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// It is not permitted to pass or return an __fp16 by value, so intrinsics
|
||||||
|
// taking a scalar float16_t must be implemented as macros.
|
||||||
|
if (typestr.find('h') != std::string::npos &&
|
||||||
|
proto.find('s') != std::string::npos)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1463,7 +1469,7 @@ static bool MacroArgUsedDirectly(const std::string &proto, unsigned i) {
|
||||||
// Generate the string "(argtype a, argtype b, ...)"
|
// Generate the string "(argtype a, argtype b, ...)"
|
||||||
static std::string GenArgs(const std::string &proto, StringRef typestr,
|
static std::string GenArgs(const std::string &proto, StringRef typestr,
|
||||||
const std::string &name) {
|
const std::string &name) {
|
||||||
bool define = UseMacro(proto);
|
bool define = UseMacro(proto, typestr);
|
||||||
char arg = 'a';
|
char arg = 'a';
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
|
@ -1642,7 +1648,7 @@ static std::string GenOpString(const std::string &name, OpKind op,
|
||||||
const std::string &proto, StringRef typestr) {
|
const std::string &proto, StringRef typestr) {
|
||||||
bool quad;
|
bool quad;
|
||||||
unsigned nElts = GetNumElements(typestr, quad);
|
unsigned nElts = GetNumElements(typestr, quad);
|
||||||
bool define = UseMacro(proto);
|
bool define = UseMacro(proto, typestr);
|
||||||
|
|
||||||
std::string ts = TypeString(proto[0], typestr);
|
std::string ts = TypeString(proto[0], typestr);
|
||||||
std::string s;
|
std::string s;
|
||||||
|
@ -2386,7 +2392,7 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
|
||||||
// sret-like argument.
|
// sret-like argument.
|
||||||
bool sret = IsMultiVecProto(proto[0]);
|
bool sret = IsMultiVecProto(proto[0]);
|
||||||
|
|
||||||
bool define = UseMacro(proto);
|
bool define = UseMacro(proto, typestr);
|
||||||
|
|
||||||
// Check if the prototype has a scalar operand with the type of the vector
|
// Check if the prototype has a scalar operand with the type of the vector
|
||||||
// elements. If not, bitcasting the args will take care of arg checking.
|
// elements. If not, bitcasting the args will take care of arg checking.
|
||||||
|
@ -2531,7 +2537,7 @@ static std::string GenIntrinsic(const std::string &name,
|
||||||
StringRef outTypeStr, StringRef inTypeStr,
|
StringRef outTypeStr, StringRef inTypeStr,
|
||||||
OpKind kind, ClassKind classKind) {
|
OpKind kind, ClassKind classKind) {
|
||||||
assert(!proto.empty() && "");
|
assert(!proto.empty() && "");
|
||||||
bool define = UseMacro(proto) && kind != OpUnavailable;
|
bool define = UseMacro(proto, outTypeStr) && kind != OpUnavailable;
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
// static always inline + return type
|
// static always inline + return type
|
||||||
|
|
Loading…
Reference in New Issue