[PowerPC] [Clang] Add vector int128 pack/unpack builtins
unsigned long long builtin_unpack_vector_int128 (vector int128_t, int);
vector int128_t builtin_pack_vector_int128 (unsigned long long, unsigned long long);
Builtins should behave the same way as in GCC.
Patch By: wuzish (Zixuan Wu)
Differential Revision: https://reviews.llvm.org/D52074
llvm-svn: 342614
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 90505ac..23c7602 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -11233,6 +11233,28 @@
auto RetTy = ConvertType(BIRetType);
return Builder.CreateBitCast(ShuffleCall, RetTy);
}
+
+ case PPC::BI__builtin_pack_vector_int128: {
+ bool isLittleEndian = getTarget().isLittleEndian();
+ Value *UndefValue =
+ llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), 2));
+ Value *Res = Builder.CreateInsertElement(
+ UndefValue, Ops[0], (uint64_t)(isLittleEndian ? 1 : 0));
+ Res = Builder.CreateInsertElement(Res, Ops[1],
+ (uint64_t)(isLittleEndian ? 0 : 1));
+ return Builder.CreateBitCast(Res, ConvertType(E->getType()));
+ }
+
+ case PPC::BI__builtin_unpack_vector_int128: {
+ ConstantInt *Index = cast<ConstantInt>(Ops[1]);
+ Value *Unpacked = Builder.CreateBitCast(
+ Ops[0], llvm::VectorType::get(ConvertType(E->getType()), 2));
+
+ if (getTarget().isLittleEndian())
+ Index = ConstantInt::get(Index->getType(), 1 - Index->getZExtValue());
+
+ return Builder.CreateExtractElement(Unpacked, Index);
+ }
}
}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4c504af..a1bfff4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2970,6 +2970,13 @@
return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_only_on_pwr7)
<< TheCall->getSourceRange();
+ auto SemaVSXCheck = [&](CallExpr *TheCall) -> bool {
+ if (!Context.getTargetInfo().hasFeature("vsx"))
+ return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_only_on_pwr7)
+ << TheCall->getSourceRange();
+ return false;
+ };
+
switch (BuiltinID) {
default: return false;
case PPC::BI__builtin_altivec_crypto_vshasigmaw:
@@ -2988,6 +2995,11 @@
case PPC::BI__builtin_vsx_xxpermdi:
case PPC::BI__builtin_vsx_xxsldwi:
return SemaBuiltinVSX(TheCall);
+ case PPC::BI__builtin_unpack_vector_int128:
+ return SemaVSXCheck(TheCall) ||
+ SemaBuiltinConstantArgRange(TheCall, 1, 0, 1);
+ case PPC::BI__builtin_pack_vector_int128:
+ return SemaVSXCheck(TheCall);
}
return SemaBuiltinConstantArgRange(TheCall, i, l, u);
}