[Power9] Builtins for ELF v.2 ABI conformance - front end portion

This patch corresponds to review:
https://reviews.llvm.org/D24397

It adds the __POWER9_VECTOR__ macro and the -mpower9-vector option along with
a number of altivec.h functions (refer to the code review for a list).

llvm-svn: 282481
This commit is contained in:
Nemanja Ivanovic 2016-09-27 10:45:22 +00:00
parent 54f8efaa26
commit 10e2b5dcaa
8 changed files with 1431 additions and 10 deletions

View File

@ -134,6 +134,14 @@ BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpequd, "V2LLiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
BUILTIN(__builtin_altivec_vcmpneb, "V16cV16cV16c", "")
BUILTIN(__builtin_altivec_vcmpneh, "V8sV8sV8s", "")
BUILTIN(__builtin_altivec_vcmpnew, "V4iV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpnezb, "V16cV16cV16c", "")
BUILTIN(__builtin_altivec_vcmpnezh, "V8sV8sV8s", "")
BUILTIN(__builtin_altivec_vcmpnezw, "V4iV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
@ -223,6 +231,11 @@ BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpequd_p, "iiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
BUILTIN(__builtin_altivec_vcmpneb_p, "iiV16cV16c", "")
BUILTIN(__builtin_altivec_vcmpneh_p, "iiV8sV8s", "")
BUILTIN(__builtin_altivec_vcmpnew_p, "iiV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpned_p, "iiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
@ -254,6 +267,16 @@ BUILTIN(__builtin_altivec_vclzb, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vclzh, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vclzw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vclzd, "V2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vctzb, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "")
// Vector population count built-ins
BUILTIN(__builtin_altivec_vpopcntb, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vpopcnth, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vpopcntw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vpopcntd, "V2ULLiV2ULLi", "")
// VSX built-ins.

View File

@ -1572,6 +1572,10 @@ def mpower8_vector : Flag<["-"], "mpower8-vector">,
Group<m_ppc_Features_Group>;
def mno_power8_vector : Flag<["-"], "mno-power8-vector">,
Group<m_ppc_Features_Group>;
def mpower9_vector : Flag<["-"], "mpower9-vector">,
Group<m_ppc_Features_Group>;
def mno_power9_vector : Flag<["-"], "mno-power9-vector">,
Group<m_ppc_Features_Group>;
def mpower8_crypto : Flag<["-"], "mcrypto">,
Group<m_ppc_Features_Group>;
def mnopower8_crypto : Flag<["-"], "mno-crypto">,

View File

@ -870,6 +870,7 @@ class PPCTargetInfo : public TargetInfo {
bool HasHTM;
bool HasBPERMD;
bool HasExtDiv;
bool HasP9Vector;
protected:
std::string ABI;
@ -878,7 +879,7 @@ public:
PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false),
HasBPERMD(false), HasExtDiv(false) {
HasBPERMD(false), HasExtDiv(false), HasP9Vector(false) {
SimdDefaultAlign = 128;
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
@ -1157,6 +1158,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasHTM = true;
} else if (Feature == "+float128") {
HasFloat128 = true;
} else if (Feature == "+power9-vector") {
HasP9Vector = true;
}
// TODO: Finish this list and add an assert that we've handled them
// all.
@ -1326,6 +1329,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__HTM__");
if (HasFloat128)
Builder.defineMacro("__FLOAT128__");
if (HasP9Vector)
Builder.defineMacro("__POWER9_VECTOR__");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
@ -1355,8 +1360,12 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
}
// Handle explicit options being passed to the compiler here: if we've
// explicitly turned off vsx and turned on power8-vector or direct-move then
// go ahead and error since the customer has expressed a somewhat incompatible
// explicitly turned off vsx and turned on any of:
// - power8-vector
// - direct-move
// - float128
// - power9-vector
// then go ahead and error since the customer has expressed an incompatible
// set of options.
static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
const std::vector<std::string> &FeaturesVec) {
@ -1383,6 +1392,13 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
<< "-mno-vsx";
return false;
}
if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") !=
FeaturesVec.end()) {
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector"
<< "-mno-vsx";
return false;
}
}
return true;
@ -1407,6 +1423,7 @@ bool PPCTargetInfo::initFeatureMap(
.Default(false);
Features["qpx"] = (CPU == "a2q");
Features["power9-vector"] = (CPU == "pwr9");
Features["crypto"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
@ -1459,6 +1476,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
.Case("bpermd", HasBPERMD)
.Case("extdiv", HasExtDiv)
.Case("float128", HasFloat128)
.Case("power9-vector", HasP9Vector)
.Default(false);
}
@ -1468,19 +1486,21 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
// as well. Do the inverse if we're disabling vsx. We'll diagnose any user
// incompatible options.
if (Enabled) {
if (Name == "direct-move") {
Features[Name] = Features["vsx"] = true;
} else if (Name == "power8-vector") {
Features[Name] = Features["vsx"] = true;
} else if (Name == "float128") {
if (Name == "direct-move" ||
Name == "power8-vector" ||
Name == "float128" ||
Name == "power9-vector") {
// power9-vector is really a superset of power8-vector so encode that.
Features[Name] = Features["vsx"] = true;
if (Name == "power9-vector")
Features["power8-vector"] = true;
} else {
Features[Name] = true;
}
} else {
if (Name == "vsx") {
Features[Name] = Features["direct-move"] = Features["power8-vector"] =
Features["float128"] = false;
Features["float128"] = Features["power9-vector"] = false;
} else {
Features[Name] = false;
}

View File

@ -7637,6 +7637,25 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
return Builder.CreateCall(F, {X, Undef});
}
case PPC::BI__builtin_altivec_vctzb:
case PPC::BI__builtin_altivec_vctzh:
case PPC::BI__builtin_altivec_vctzw:
case PPC::BI__builtin_altivec_vctzd: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
return Builder.CreateCall(F, {X, Undef});
}
case PPC::BI__builtin_altivec_vpopcntb:
case PPC::BI__builtin_altivec_vpopcnth:
case PPC::BI__builtin_altivec_vpopcntw:
case PPC::BI__builtin_altivec_vpopcntd: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
return Builder.CreateCall(F, X);
}
// Copy sign
case PPC::BI__builtin_vsx_xvcpsgnsp:
case PPC::BI__builtin_vsx_xvcpsgndp: {

View File

@ -1595,6 +1595,133 @@ vec_cmpeq(vector double __a, vector double __b) {
}
#endif
#ifdef __POWER9_VECTOR__
/* vec_cmpne */
static __inline__ vector bool char __ATTRS_o_ai
vec_cmpne(vector bool char __a, vector bool char __b) {
return (vector bool char)__builtin_altivec_vcmpneb((vector char)__a,
(vector char)__b);
}
static __inline__ vector bool char __ATTRS_o_ai
vec_cmpne(vector signed char __a, vector signed char __b) {
return (vector bool char)__builtin_altivec_vcmpneb((vector char)__a,
(vector char)__b);
}
static __inline__ vector bool char __ATTRS_o_ai
vec_cmpne(vector unsigned char __a, vector unsigned char __b) {
return (vector bool char)__builtin_altivec_vcmpneb((vector char)__a,
(vector char)__b);
}
static __inline__ vector bool short __ATTRS_o_ai
vec_cmpne(vector bool short __a, vector bool short __b) {
return (vector bool short)__builtin_altivec_vcmpneh((vector short)__a,
(vector short)__b);
}
static __inline__ vector bool short __ATTRS_o_ai
vec_cmpne(vector signed short __a, vector signed short __b) {
return (vector bool short)__builtin_altivec_vcmpneh((vector short)__a,
(vector short)__b);
}
static __inline__ vector bool short __ATTRS_o_ai
vec_cmpne(vector unsigned short __a, vector unsigned short __b) {
return (vector bool short)__builtin_altivec_vcmpneh((vector short)__a,
(vector short)__b);
}
static __inline__ vector bool int __ATTRS_o_ai
vec_cmpne(vector bool int __a, vector bool int __b) {
return (vector bool int)__builtin_altivec_vcmpnew((vector int)__a,
(vector int)__b);
}
static __inline__ vector bool int __ATTRS_o_ai
vec_cmpne(vector signed int __a, vector signed int __b) {
return (vector bool int)__builtin_altivec_vcmpnew((vector int)__a,
(vector int)__b);
}
static __inline__ vector bool int __ATTRS_o_ai
vec_cmpne(vector unsigned int __a, vector unsigned int __b) {
return (vector bool int)__builtin_altivec_vcmpnew((vector int)__a,
(vector int)__b);
}
static __inline__ vector bool long long __ATTRS_o_ai
vec_cmpne(vector bool long long __a, vector bool long long __b) {
return (vector bool long long)
~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
}
static __inline__ vector bool long long __ATTRS_o_ai
vec_cmpne(vector signed long long __a, vector signed long long __b) {
return (vector bool long long)
~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
}
static __inline__ vector bool long long __ATTRS_o_ai
vec_cmpne(vector unsigned long long __a, vector unsigned long long __b) {
return (vector bool long long)
~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
}
static __inline__ vector bool int __ATTRS_o_ai
vec_cmpne(vector float __a, vector float __b) {
return (vector bool int)__builtin_altivec_vcmpnew((vector int)__a,
(vector int)__b);
}
static __inline__ vector bool long long __ATTRS_o_ai
vec_cmpne(vector double __a, vector double __b) {
return (vector bool long long)
~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
}
/* vec_cmpnez */
static __inline__ vector bool char __ATTRS_o_ai
vec_cmpnez(vector signed char __a, vector signed char __b) {
return (vector bool char)__builtin_altivec_vcmpnezb((vector char)__a,
(vector char)__b);
}
static __inline__ vector bool char __ATTRS_o_ai
vec_cmpnez(vector unsigned char __a, vector unsigned char __b) {
return (vector bool char)__builtin_altivec_vcmpnezb((vector char)__a,
(vector char)__b);
}
static __inline__ vector bool short __ATTRS_o_ai
vec_cmpnez(vector signed short __a, vector signed short __b) {
return (vector bool short)__builtin_altivec_vcmpnezh((vector short)__a,
(vector short)__b);
}
static __inline__ vector bool short __ATTRS_o_ai
vec_cmpnez(vector unsigned short __a, vector unsigned short __b) {
return (vector bool short)__builtin_altivec_vcmpnezh((vector short)__a,
(vector short)__b);
}
static __inline__ vector bool int __ATTRS_o_ai
vec_cmpnez(vector signed int __a, vector signed int __b) {
return (vector bool int)__builtin_altivec_vcmpnezw((vector int)__a,
(vector int)__b);
}
static __inline__ vector bool int __ATTRS_o_ai
vec_cmpnez(vector unsigned int __a, vector unsigned int __b) {
return (vector bool int)__builtin_altivec_vcmpnezw((vector int)__a,
(vector int)__b);
}
#endif
/* vec_cmpgt */
static __inline__ vector bool char __ATTRS_o_ai
@ -1882,6 +2009,41 @@ vec_cmplt(vector unsigned long long __a, vector unsigned long long __b) {
return vec_cmpgt(__b, __a);
}
/* vec_popcnt */
static __inline__ vector signed char __ATTRS_o_ai
vec_popcnt(vector signed char __a) {
return __builtin_altivec_vpopcntb(__a);
}
static __inline__ vector unsigned char __ATTRS_o_ai
vec_popcnt(vector unsigned char __a) {
return __builtin_altivec_vpopcntb(__a);
}
static __inline__ vector signed short __ATTRS_o_ai
vec_popcnt(vector signed short __a) {
return __builtin_altivec_vpopcnth(__a);
}
static __inline__ vector unsigned short __ATTRS_o_ai
vec_popcnt(vector unsigned short __a) {
return __builtin_altivec_vpopcnth(__a);
}
static __inline__ vector signed int __ATTRS_o_ai
vec_popcnt(vector signed int __a) {
return __builtin_altivec_vpopcntw(__a);
}
static __inline__ vector unsigned int __ATTRS_o_ai
vec_popcnt(vector unsigned int __a) {
return __builtin_altivec_vpopcntw(__a);
}
static __inline__ vector signed long long __ATTRS_o_ai
vec_popcnt(vector signed long long __a) {
return __builtin_altivec_vpopcntd(__a);
}
static __inline__ vector unsigned long long __ATTRS_o_ai
vec_popcnt(vector unsigned long long __a) {
return __builtin_altivec_vpopcntd(__a);
}
/* vec_cntlz */
static __inline__ vector signed char __ATTRS_o_ai
@ -1918,6 +2080,425 @@ vec_cntlz(vector unsigned long long __a) {
}
#endif
#ifdef __POWER9_VECTOR__
/* vec_cnttz */
static __inline__ vector signed char __ATTRS_o_ai
vec_cnttz(vector signed char __a) {
return __builtin_altivec_vctzb(__a);
}
static __inline__ vector unsigned char __ATTRS_o_ai
vec_cnttz(vector unsigned char __a) {
return __builtin_altivec_vctzb(__a);
}
static __inline__ vector signed short __ATTRS_o_ai
vec_cnttz(vector signed short __a) {
return __builtin_altivec_vctzh(__a);
}
static __inline__ vector unsigned short __ATTRS_o_ai
vec_cnttz(vector unsigned short __a) {
return __builtin_altivec_vctzh(__a);
}
static __inline__ vector signed int __ATTRS_o_ai
vec_cnttz(vector signed int __a) {
return __builtin_altivec_vctzw(__a);
}
static __inline__ vector unsigned int __ATTRS_o_ai
vec_cnttz(vector unsigned int __a) {
return __builtin_altivec_vctzw(__a);
}
static __inline__ vector signed long long __ATTRS_o_ai
vec_cnttz(vector signed long long __a) {
return __builtin_altivec_vctzd(__a);
}
static __inline__ vector unsigned long long __ATTRS_o_ai
vec_cnttz(vector unsigned long long __a) {
return __builtin_altivec_vctzd(__a);
}
/* vec_first_match_index */
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_index(vector signed char __a, vector signed char __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpeq(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpeq(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_index(vector unsigned char __a, vector unsigned char __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpeq(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpeq(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_index(vector signed short __a, vector signed short __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpeq(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpeq(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_index(vector unsigned short __a, vector unsigned short __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpeq(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpeq(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_index(vector signed int __a, vector signed int __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpeq(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpeq(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_index(vector unsigned int __a, vector unsigned int __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpeq(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpeq(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
/* vec_first_match_or_eos_index */
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_or_eos_index(vector signed char __a, vector signed char __b) {
/* Compare the result of the comparison of two vectors with either and OR the
result. Either the elements are equal or one will equal the comparison
result if either is zero.
*/
vector bool char __tmp1 = vec_cmpeq(__a, __b);
vector bool char __tmp2 = __tmp1 | vec_cmpeq(__tmp1, __a) |
vec_cmpeq(__tmp1, __b);
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)__tmp2);
#else
vec_cntlz((vector unsigned long long)__tmp2);
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_or_eos_index(vector unsigned char __a,
vector unsigned char __b) {
vector bool char __tmp1 = vec_cmpeq(__a, __b);
vector bool char __tmp2 = __tmp1 | vec_cmpeq(__tmp1, __a) |
vec_cmpeq(__tmp1, __b);
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)__tmp2);
#else
vec_cntlz((vector unsigned long long)__tmp2);
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_or_eos_index(vector signed short __a, vector signed short __b) {
vector bool short __tmp1 = vec_cmpeq(__a, __b);
vector bool short __tmp2 = __tmp1 | vec_cmpeq(__tmp1, __a) |
vec_cmpeq(__tmp1, __b);
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)__tmp2);
#else
vec_cntlz((vector unsigned long long)__tmp2);
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_or_eos_index(vector unsigned short __a,
vector unsigned short __b) {
vector bool short __tmp1 = vec_cmpeq(__a, __b);
vector bool short __tmp2 = __tmp1 | vec_cmpeq(__tmp1, __a) |
vec_cmpeq(__tmp1, __b);
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)__tmp2);
#else
vec_cntlz((vector unsigned long long)__tmp2);
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_or_eos_index(vector signed int __a, vector signed int __b) {
vector bool int __tmp1 = vec_cmpeq(__a, __b);
vector bool int __tmp2 = __tmp1 | vec_cmpeq(__tmp1, __a) |
vec_cmpeq(__tmp1, __b);
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)__tmp2);
#else
vec_cntlz((vector unsigned long long)__tmp2);
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_match_or_eos_index(vector unsigned int __a,
vector unsigned int __b) {
vector bool int __tmp1 = vec_cmpeq(__a, __b);
vector bool int __tmp2 = __tmp1 | vec_cmpeq(__tmp1, __a) |
vec_cmpeq(__tmp1, __b);
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)__tmp2);
#else
vec_cntlz((vector unsigned long long)__tmp2);
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
/* vec_first_mismatch_index */
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_index(vector signed char __a, vector signed char __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpne(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpne(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_index(vector unsigned char __a, vector unsigned char __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpne(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpne(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_index(vector signed short __a, vector signed short __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpne(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpne(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_index(vector unsigned short __a, vector unsigned short __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpne(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpne(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_index(vector signed int __a, vector signed int __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpne(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpne(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_index(vector unsigned int __a, vector unsigned int __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpne(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpne(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
/* vec_first_mismatch_or_eos_index */
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_or_eos_index(vector signed char __a,
vector signed char __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpnez(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpnez(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_or_eos_index(vector unsigned char __a,
vector unsigned char __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpnez(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpnez(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 3;
}
return __res[0] >> 3;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_or_eos_index(vector signed short __a,
vector signed short __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpnez(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpnez(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_or_eos_index(vector unsigned short __a,
vector unsigned short __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpnez(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpnez(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 4;
}
return __res[0] >> 4;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_or_eos_index(vector signed int __a, vector signed int __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpnez(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpnez(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
static __inline__ unsigned __ATTRS_o_ai
vec_first_mismatch_or_eos_index(vector unsigned int __a,
vector unsigned int __b) {
vector unsigned long long __res =
#ifdef __LITTLE_ENDIAN__
vec_cnttz((vector unsigned long long)vec_cmpnez(__a, __b));
#else
vec_cntlz((vector unsigned long long)vec_cmpnez(__a, __b));
#endif
if (__res[0] == 64) {
return (__res[1] + 64) >> 5;
}
return __res[0] >> 5;
}
#endif
/* vec_cpsgn */
#ifdef __VSX__

View File

@ -0,0 +1,748 @@
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -faltivec -target-feature +power9-vector \
// RUN: -triple powerpc64-unknown-unknown -emit-llvm %s \
// RUN: -O2 -o - | FileCheck %s -check-prefix=CHECK-BE
// RUN: %clang_cc1 -faltivec -target-feature +power9-vector \
// RUN: -triple powerpc64le-unknown-unknown -emit-llvm %s \
// RUN: -O2 -o - | FileCheck %s
#include <altivec.h>
vector signed char vsca, vscb;
vector unsigned char vuca, vucb;
vector bool char vbca, vbcb;
vector signed short vssa, vssb;
vector unsigned short vusa, vusb;
vector bool short vbsa, vbsb;
vector signed int vsia, vsib;
vector unsigned int vuia, vuib;
vector bool int vbia, vbib;
vector signed long long vsla, vslb;
vector unsigned long long vula, vulb;
vector bool long long vbla, vblb;
vector float vfa, vfb;
vector double vda, vdb;
unsigned test1(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_match_index (vsca, vscb);
}
unsigned test2(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_match_index (vuca, vucb);
}
unsigned test3(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_match_index (vsia, vsib);
}
unsigned test4(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_match_index (vuia, vuib);
}
unsigned test5(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_match_index (vssa, vssb);
}
unsigned test6(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_match_index (vusa, vusb);
}
unsigned test7(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: or <16 x i8>
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: or <16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: or <16 x i8>
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: or <16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_match_or_eos_index (vsca, vscb);
}
unsigned test8(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: or <16 x i8>
// CHECK-BE: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK-BE: or <16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: or <16 x i8>
// CHECK: @llvm.ppc.altivec.vcmpequb(<16 x i8>
// CHECK: or <16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_match_or_eos_index (vuca, vucb);
}
unsigned test9(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: or <4 x i32>
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: or <4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: or <4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: or <4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_match_or_eos_index (vsia, vsib);
}
unsigned test10(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: or <4 x i32>
// CHECK-BE: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK-BE: or <4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: or <4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpequw(<4 x i32>
// CHECK: or <4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_match_or_eos_index (vuia, vuib);
}
unsigned test11(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: or <8 x i16>
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: or <8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: or <8 x i16>
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: or <8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_match_or_eos_index (vssa, vssb);
}
unsigned test12(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: or <8 x i16>
// CHECK-BE: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK-BE: or <8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: or <8 x i16>
// CHECK: @llvm.ppc.altivec.vcmpequh(<8 x i16>
// CHECK: or <8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_match_or_eos_index (vusa, vusb);
}
unsigned test13(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_mismatch_index (vsca, vscb);
}
unsigned test14(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_mismatch_index (vuca, vucb);
}
unsigned test15(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_mismatch_index (vsia, vsib);
}
unsigned test16(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_mismatch_index (vuia, vuib);
}
unsigned test17(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_mismatch_index (vssa, vssb);
}
unsigned test18(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_mismatch_index (vusa, vusb);
}
unsigned test19(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnezb(<16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpnezb(<16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_mismatch_or_eos_index (vsca, vscb);
}
unsigned test20(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnezb(<16 x i8>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 3
// CHECK: @llvm.ppc.altivec.vcmpnezb(<16 x i8>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 3
return vec_first_mismatch_or_eos_index (vuca, vucb);
}
unsigned test21(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnezw(<4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpnezw(<4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_mismatch_or_eos_index (vsia, vsib);
}
unsigned test22(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnezw(<4 x i32>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 5
// CHECK: @llvm.ppc.altivec.vcmpnezw(<4 x i32>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 5
return vec_first_mismatch_or_eos_index (vuia, vuib);
}
unsigned test23(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnezh(<8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpnezh(<8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_mismatch_or_eos_index (vssa, vssb);
}
unsigned test24(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnezh(<8 x i16>
// CHECK-BE: @llvm.ctlz.v2i64(<2 x i64>
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: icmp eq i64 {{.*}}, 64
// CHECK-BE: extractelement <2 x i64>
// CHECK-BE: add i64 {{.*}}, 64
// CHECK-BE: select i1
// CHECK-BE: lshr i64 {{.*}}, 4
// CHECK: @llvm.ppc.altivec.vcmpnezh(<8 x i16>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK: extractelement <2 x i64>
// CHECK: icmp eq i64 {{.*}}, 64
// CHECK: extractelement <2 x i64>
// CHECK: add i64 {{.*}}, 64
// CHECK: select i1
// CHECK: lshr i64 {{.*}}, 4
return vec_first_mismatch_or_eos_index (vusa, vusb);
}
vector bool char test25(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-NEXT: ret <16 x i8>
return vec_cmpne (vbca, vbcb);
}
vector bool char test26(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-NEXT: ret <16 x i8>
return vec_cmpne (vsca, vscb);
}
vector bool char test27(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK: @llvm.ppc.altivec.vcmpneb(<16 x i8>
// CHECK-NEXT: ret <16 x i8>
return vec_cmpne (vuca, vucb);
}
vector bool int test28(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_cmpne (vbia, vbib);
}
vector bool int test29(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_cmpne (vsia, vsib);
}
vector bool int test30(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_cmpne (vuia, vuib);
}
vector bool long long test31(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK-BE: xor <2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK: xor <2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_cmpne (vbla, vblb);
}
vector bool long long test32(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK-BE: xor <2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK: xor <2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_cmpne (vsla, vslb);
}
vector bool long long test33(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK-BE: xor <2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK: xor <2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_cmpne (vula, vulb);
}
vector bool short test34(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-NEXT: ret <8 x i16>
return vec_cmpne (vbsa, vbsb);
}
vector bool short test35(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-NEXT: ret <8 x i16>
return vec_cmpne (vssa, vssb);
}
vector bool short test36(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK: @llvm.ppc.altivec.vcmpneh(<8 x i16>
// CHECK-NEXT: ret <8 x i16>
return vec_cmpne (vusa, vusb);
}
vector bool long long test37(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK-BE: xor <2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.ppc.altivec.vcmpequd(<2 x i64>
// CHECK: xor <2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_cmpne (vda, vdb);
}
vector bool int test38(void) {
// CHECK-BE: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.ppc.altivec.vcmpnew(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_cmpne (vfa, vfb);
}
vector signed char test39(void) {
// CHECK-BE: @llvm.cttz.v16i8(<16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK: @llvm.cttz.v16i8(<16 x i8>
// CHECK-NEXT: ret <16 x i8>
return vec_cnttz (vsca);
}
vector unsigned char test40(void) {
// CHECK-BE: @llvm.cttz.v16i8(<16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK: @llvm.cttz.v16i8(<16 x i8>
// CHECK-NEXT: ret <16 x i8>
return vec_cnttz (vuca);
}
vector signed int test41(void) {
// CHECK-BE: @llvm.cttz.v4i32(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.cttz.v4i32(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_cnttz (vsia);
}
vector unsigned int test42(void) {
// CHECK-BE: @llvm.cttz.v4i32(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.cttz.v4i32(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_cnttz (vuia);
}
vector signed long long test43(void) {
// CHECK-BE: @llvm.cttz.v2i64(<2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_cnttz (vsla);
}
vector unsigned long long test44(void) {
// CHECK-BE: @llvm.cttz.v2i64(<2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.cttz.v2i64(<2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_cnttz (vula);
}
vector signed short test45(void) {
// CHECK-BE: @llvm.cttz.v8i16(<8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK: @llvm.cttz.v8i16(<8 x i16>
// CHECK-NEXT: ret <8 x i16>
return vec_cnttz (vssa);
}
vector unsigned short test46(void) {
// CHECK-BE: @llvm.cttz.v8i16(<8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK: @llvm.cttz.v8i16(<8 x i16>
// CHECK-NEXT: ret <8 x i16>
return vec_cnttz (vusa);
}
vector unsigned char test47(void) {
// CHECK-BE: @llvm.ctpop.v16i8(<16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK: @llvm.ctpop.v16i8(<16 x i8>
// CHECK-NEXT: ret <16 x i8>
return vec_popcnt (vsca);
}
vector unsigned char test48(void) {
// CHECK-BE: @llvm.ctpop.v16i8(<16 x i8>
// CHECK-BE-NEXT: ret <16 x i8>
// CHECK: @llvm.ctpop.v16i8(<16 x i8>
// CHECK-NEXT: ret <16 x i8>
return vec_popcnt (vuca);
}
vector unsigned int test49(void) {
// CHECK-BE: @llvm.ctpop.v4i32(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.ctpop.v4i32(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_popcnt (vsia);
}
vector unsigned int test50(void) {
// CHECK-BE: @llvm.ctpop.v4i32(<4 x i32>
// CHECK-BE-NEXT: ret <4 x i32>
// CHECK: @llvm.ctpop.v4i32(<4 x i32>
// CHECK-NEXT: ret <4 x i32>
return vec_popcnt (vuia);
}
vector unsigned long long test51(void) {
// CHECK-BE: @llvm.ctpop.v2i64(<2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.ctpop.v2i64(<2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_popcnt (vsla);
}
vector unsigned long long test52(void) {
// CHECK-BE: @llvm.ctpop.v2i64(<2 x i64>
// CHECK-BE-NEXT: ret <2 x i64>
// CHECK: @llvm.ctpop.v2i64(<2 x i64>
// CHECK-NEXT: ret <2 x i64>
return vec_popcnt (vula);
}
vector unsigned short test53(void) {
// CHECK-BE: @llvm.ctpop.v8i16(<8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK: @llvm.ctpop.v8i16(<8 x i16>
// CHECK-NEXT: ret <8 x i16>
return vec_popcnt (vssa);
}
vector unsigned short test54(void) {
// CHECK-BE: @llvm.ctpop.v8i16(<8 x i16>
// CHECK-BE-NEXT: ret <8 x i16>
// CHECK: @llvm.ctpop.v8i16(<8 x i16>
// CHECK-NEXT: ret <8 x i16>
return vec_popcnt (vusa);
}

View File

@ -42,6 +42,18 @@
// RUN: -mcpu=power6 -std=c++11 -mdirect-move %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-VSX
// RUN: not %clang -target powerpc64le-unknown-unknown -fsyntax-only \
// RUN: -mcpu=power9 -std=c++11 %s 2>&1 | FileCheck %s \
// RUN: -check-prefix=CHECK-DEFAULT-P9
// RUN: not %clang -target powerpc64le-unknown-unknown -fsyntax-only \
// RUN: -mcpu=power9 -std=c++11 -mno-vsx -mpower9-vector %s 2>&1 | \
// RUN: FileCheck %s -check-prefix=CHECK-NVSX-P9V
// RUN: not %clang -target powerpc64le-unknown-unknown -fsyntax-only \
// RUN: -mcpu=power9 -std=c++11 -mno-vsx -mfloat128 %s 2>&1 | \
// RUN: FileCheck %s -check-prefix=CHECK-NVSX-FLT128
#ifdef __VSX__
static_assert(false, "VSX enabled");
#endif
@ -50,13 +62,21 @@ static_assert(false, "VSX enabled");
static_assert(false, "P8V enabled");
#endif
#if !defined(__VSX__) && !defined(__POWER8_VECTOR__)
#ifdef __POWER9_VECTOR__
static_assert(false, "P9V enabled");
#endif
#if !defined(__VSX__) && !defined(__POWER8_VECTOR__) && \
!defined(__POWER9_VECTOR__)
static_assert(false, "Neither enabled");
#endif
// CHECK-DEFAULT: VSX enabled
// CHECK-DEFAULT: P8V enabled
// CHECK-DEFAULT-P9: P9V enabled
// CHECK-NVSX-P8V: error: option '-mpower8-vector' cannot be specified with '-mno-vsx'
// CHECK-NVSX-P9V: error: option '-mpower9-vector' cannot be specified with '-mno-vsx'
// CHECK-NVSX-FLT128: error: option '-mfloat128' cannot be specified with '-mno-vsx'
// CHECK-NVSX-DMV: error: option '-mdirect-move' cannot be specified with '-mno-vsx'
// CHECK-NVSX: Neither enabled
// CHECK-VSX: VSX enabled

View File

@ -1865,6 +1865,12 @@
//
// CHECK_PPC_POWER8_VECTOR_M64: #define __POWER8_VECTOR__ 1
//
// RUN: %clang -mpower9-vector -E -dM %s -o - 2>&1 \
// RUN: -target powerpc64-unknown-linux \
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_PPC_POWER9_VECTOR_M64
//
// CHECK_PPC_POWER9_VECTOR_M64: #define __POWER9_VECTOR__ 1
//
// RUN: %clang -mcrypto -E -dM %s -o - 2>&1 \
// RUN: -target powerpc64-unknown-linux \
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_PPC_CRYPTO_M64