[SveEmitter] Explicitly merge with zero/undef
Builtins that have the merge type MergeAnyExp or MergeZeroExp,
merge into a 'undef' or 'zero' vector respectively, which enables the
_x and _z behaviour for unary operations.
This patch also adds builtins for svabs and svneg.
Reviewers: SjoerdMeijer, efriedma, rovka
Reviewed By: efriedma
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77591
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 96c7c9e..df45fef 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -7591,6 +7591,18 @@
return Builder.CreateCall(F, {Val, Predicate, BasePtr});
}
+static void InsertExplicitZeroOperand(CGBuilderTy &Builder, llvm::Type *Ty,
+ SmallVectorImpl<Value *> &Ops) {
+ auto *SplatZero = Constant::getNullValue(Ty);
+ Ops.insert(Ops.begin(), SplatZero);
+}
+
+static void InsertExplicitUndefOperand(CGBuilderTy &Builder, llvm::Type *Ty,
+ SmallVectorImpl<Value *> &Ops) {
+ auto *SplatUndef = UndefValue::get(Ty);
+ Ops.insert(Ops.begin(), SplatUndef);
+}
+
Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
// Find out if any arguments are required to be integer constant expressions.
@@ -7630,6 +7642,12 @@
else if (Builtin->LLVMIntrinsic != 0) {
llvm::Type* OverloadedTy = getSVEType(TypeFlags);
+ if (TypeFlags.getMergeType() == SVETypeFlags::MergeZeroExp)
+ InsertExplicitZeroOperand(Builder, Ty, Ops);
+
+ if (TypeFlags.getMergeType() == SVETypeFlags::MergeAnyExp)
+ InsertExplicitUndefOperand(Builder, Ty, Ops);
+
// Predicates must match the main datatype.
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
if (auto PredTy = dyn_cast<llvm::VectorType>(Ops[i]->getType()))