[clang] [clang] Introduce __builtin_splatvector (PR #212758)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 29 05:41:39 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Paul Osmialowski (pawosm-arm)
<details>
<summary>Changes</summary>
The aim of this patch is to introduce a new builtin for doing a vector splat which could work with both fided-size and scalable vectors (regardless of the underlying architecture) and also could be used in the C++ templates.
Most of the code (including the tests) follows similar code of __builtin_convertvector.
The new builtin takes two parameters: a scalar value and a desired vector type (fixed-size or scalable). A type conversion is attempted when the type of the value is not the same as the element type of the requested vector type.
---
Patch is 125.24 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/212758.diff
49 Files Affected:
- (modified) clang/docs/LanguageExtensions.md (+44-1)
- (modified) clang/docs/LibASTMatchersReference.html (+5)
- (modified) clang/include/clang/AST/ComputeDependence.h (+2)
- (modified) clang/include/clang/AST/Expr.h (+126)
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+1)
- (modified) clang/include/clang/AST/Stmt.h (+15)
- (modified) clang/include/clang/AST/TextNodeDumper.h (+1)
- (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+4)
- (modified) clang/include/clang/Basic/Builtins.td (+6)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3)
- (modified) clang/include/clang/Basic/StmtNodes.td (+1)
- (modified) clang/include/clang/Basic/TokenKinds.def (+1)
- (modified) clang/include/clang/Sema/Sema.h (+14)
- (modified) clang/include/clang/Serialization/ASTBitCodes.h (+3)
- (modified) clang/lib/AST/ASTImporter.cpp (+17)
- (modified) clang/lib/AST/ComputeDependence.cpp (+9)
- (modified) clang/lib/AST/Expr.cpp (+21)
- (modified) clang/lib/AST/ExprClassification.cpp (+1)
- (modified) clang/lib/AST/ExprConstant.cpp (+1)
- (modified) clang/lib/AST/ItaniumMangle.cpp (+1)
- (modified) clang/lib/AST/StmtPrinter.cpp (+8)
- (modified) clang/lib/AST/StmtProfile.cpp (+4)
- (modified) clang/lib/AST/TextNodeDumper.cpp (+6)
- (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+2)
- (modified) clang/lib/ASTMatchers/Dynamic/Registry.cpp (+1)
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+87)
- (modified) clang/lib/Parse/ParseExpr.cpp (+30)
- (modified) clang/lib/Sema/SemaChecking.cpp (+22)
- (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+1)
- (modified) clang/lib/Sema/SemaExpr.cpp (+8)
- (modified) clang/lib/Sema/TreeTransform.h (+28)
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+21)
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+13)
- (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1)
- (modified) clang/test/AST/ast-dump-fpfeatures.cpp (+19)
- (modified) clang/test/CodeGen/pragma-fenv_access.c (+40)
- (added) clang/test/CodeGen/splatvector-sizeless-aarch64.c (+518)
- (added) clang/test/CodeGen/splatvector-sizeless-riscv.c (+518)
- (added) clang/test/CodeGen/splatvector-template.cpp (+17)
- (added) clang/test/CodeGen/splatvector.c (+524)
- (modified) clang/test/PCH/exprs.h (+4)
- (modified) clang/test/Preprocessor/feature_tests.c (+1)
- (modified) clang/test/Preprocessor/feature_tests.cpp (+5)
- (added) clang/test/Sema/splatvector.c (+16)
- (modified) clang/test/Sema/vector-bool-assign.c (+6)
- (modified) clang/test/Sema/vector-bool-assign.cpp (+6)
- (modified) clang/tools/libclang/CXCursor.cpp (+1)
- (modified) clang/unittests/AST/ASTImporterTest.cpp (+22)
- (modified) clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (+10)
``````````diff
diff --git a/clang/docs/LanguageExtensions.md b/clang/docs/LanguageExtensions.md
index f5313e0378ca0..af38f05259bcd 100644
--- a/clang/docs/LanguageExtensions.md
+++ b/clang/docs/LanguageExtensions.md
@@ -690,7 +690,7 @@ these attributes requires the command line option `-msve-vector-bits=<N>` or
supported on both sizeless and VLS types. For RVV, the operators are only
supported on VLS types.
-See also {ref}`langext-builtin-shufflevector`, {ref}`langext-builtin-convertvector`.
+See also {ref}`langext-builtin-shufflevector`, {ref}`langext-builtin-splatvector` ,{ref}`langext-builtin-convertvector`.
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id5" role="doc-footnote">
@@ -3563,6 +3563,49 @@ indices specified.
Query for this feature with `__has_builtin(__builtin_shufflevector)`.
+(langext-__builtin_splatvector)=
+(langext-builtin-splatvector)=
+
+### `__builtin_splatvector`
+
+`__builtin_splatvector` is used to express generic vector splat
+operations. This builtin can be used within constant expressions.
+
+**Syntax**:
+
+```c++
+__builtin_splatvector(src_value, dst_vec_type)
+```
+
+**Examples**:
+
+```c++
+typedef double vector4double __attribute__((__vector_size__(32)));
+typedef float vector4float __attribute__((__vector_size__(16)));
+typedef short vector4short __attribute__((__vector_size__(8)));
+float f; short s;
+
+// splat a float value to a vector of 4 doubles.
+__builtin_splatvector(f, vector4double)
+// equivalent to:
+(vector4double) { (double) f, (double) f, (double) f, (double) f }
+
+// splat a short integer value to a vector of 4 floats.
+__builtin_splatvector(s, vector4float)
+// equivalent to:
+(vector4float) { (float) s, (float) s, (float) s, (float) s }
+```
+
+**Description**:
+
+The first argument to `__builtin_splatvector` is a value, and the second
+argument is a vector type.
+
+The result of `__builtin_splatvector` is a vector with the value from the
+first argument copied to each its element.
+
+Query for this feature with `__has_builtin(__builtin_splatvector)`.
+
(langext-__builtin_convertvector)=
(langext-builtin-convertvector)=
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 7e0bbbcb18938..035662a4976c0 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -2347,6 +2347,11 @@ <h2 id="decl-matchers">Node Matchers</h2>
</pre></td></tr>
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('splatVectorExpr0')"><a name="splatVectorExpr0Anchor">splatVectorExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1SplatVectorExpr.html">SplatVectorExpr</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="splatVectorExpr0"><pre>Matches builtin function __builtin_splatvector.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('stmt0')"><a name="stmt0Anchor">stmt</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="stmt0"><pre>Matches statements.
diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h
index 3a3c86842501a..f70aaeb06c89a 100644
--- a/clang/include/clang/AST/ComputeDependence.h
+++ b/clang/include/clang/AST/ComputeDependence.h
@@ -37,6 +37,7 @@ class BinaryOperator;
class ConditionalOperator;
class BinaryConditionalOperator;
class StmtExpr;
+class SplatVectorExpr;
class ConvertVectorExpr;
class VAArgExpr;
class ChooseExpr;
@@ -128,6 +129,7 @@ ExprDependence computeDependence(BinaryOperator *E);
ExprDependence computeDependence(ConditionalOperator *E);
ExprDependence computeDependence(BinaryConditionalOperator *E);
ExprDependence computeDependence(StmtExpr *E, unsigned TemplateDepth);
+ExprDependence computeDependence(SplatVectorExpr *E);
ExprDependence computeDependence(ConvertVectorExpr *E);
ExprDependence computeDependence(VAArgExpr *E);
ExprDependence computeDependence(ChooseExpr *E);
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index f95f87cc4e8e0..669247d158ae1 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4717,6 +4717,132 @@ class ShuffleVectorExpr : public Expr {
}
};
+/// SplatVectorExpr - clang-specific builtin-in function
+/// __builtin_splatvector.
+/// This AST node represents a operator that does a splat,
+/// similar to LLVM's splat instruction. It takes a scalar value
+/// and returns the appropriately splatted vector.
+class SplatVectorExpr final
+ : public Expr,
+ private llvm::TrailingObjects<SplatVectorExpr, FPOptionsOverride> {
+private:
+ Stmt *SrcExpr;
+ TypeSourceInfo *TInfo;
+ SourceLocation BuiltinLoc, RParenLoc;
+
+ friend TrailingObjects;
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ explicit SplatVectorExpr(bool HasFPFeatures, EmptyShell Empty)
+ : Expr(SplatVectorExprClass, Empty) {
+ SplatVectorExprBits.HasFPFeatures = HasFPFeatures;
+ }
+
+ SplatVectorExpr(Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType,
+ ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation BuiltinLoc, SourceLocation RParenLoc,
+ FPOptionsOverride FPFeatures)
+ : Expr(SplatVectorExprClass, DstType, VK, OK), SrcExpr(SrcExpr),
+ TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {
+ SplatVectorExprBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ if (hasStoredFPFeatures())
+ setStoredFPFeatures(FPFeatures);
+ setDependence(computeDependence(this));
+ }
+
+ size_t numTrailingObjects(OverloadToken<FPOptionsOverride>) const {
+ return SplatVectorExprBits.HasFPFeatures ? 1 : 0;
+ }
+
+ FPOptionsOverride &getTrailingFPFeatures() {
+ assert(SplatVectorExprBits.HasFPFeatures);
+ return *getTrailingObjects();
+ }
+
+ const FPOptionsOverride &getTrailingFPFeatures() const {
+ assert(SplatVectorExprBits.HasFPFeatures);
+ return *getTrailingObjects();
+ }
+
+public:
+ static SplatVectorExpr *CreateEmpty(const ASTContext &C, bool hasFPFeatures);
+
+ static SplatVectorExpr *Create(const ASTContext &C, Expr *SrcExpr,
+ TypeSourceInfo *TI, QualType DstType,
+ ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation BuiltinLoc,
+ SourceLocation RParenLoc,
+ FPOptionsOverride FPFeatures);
+
+ /// Get the FP contractibility status of this operator. Only meaningful for
+ /// operations on floating point types.
+ bool isFPContractableWithinStatement(const LangOptions &LO) const {
+ return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
+ }
+
+ /// Is FPFeatures in Trailing Storage?
+ bool hasStoredFPFeatures() const {
+ return SplatVectorExprBits.HasFPFeatures;
+ }
+
+ /// Get FPFeatures from trailing storage.
+ FPOptionsOverride getStoredFPFeatures() const {
+ return getTrailingFPFeatures();
+ }
+
+ /// Get the store FPOptionsOverride or default if not stored.
+ FPOptionsOverride getStoredFPFeaturesOrDefault() const {
+ return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
+ }
+
+ /// Set FPFeatures in trailing storage, used by Serialization & ASTImporter.
+ void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
+
+ /// Get the FP features status of this operator. Only meaningful for
+ /// operations on floating point types.
+ FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
+ if (SplatVectorExprBits.HasFPFeatures)
+ return getStoredFPFeatures().applyOverrides(LO);
+ return FPOptions::defaultWithoutTrailingStorage(LO);
+ }
+
+ FPOptionsOverride getFPOptionsOverride() const {
+ if (SplatVectorExprBits.HasFPFeatures)
+ return getStoredFPFeatures();
+ return FPOptionsOverride();
+ }
+
+ /// getSrcExpr - Return the Expr to be splat.
+ Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
+
+ /// getTypeSourceInfo - Return the destination type.
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return TInfo;
+ }
+ void setTypeSourceInfo(TypeSourceInfo *ti) {
+ TInfo = ti;
+ }
+
+ /// getBuiltinLoc - Return the location of the __builtin_splatvector token.
+ SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+
+ /// getRParenLoc - Return the location of final right parenthesis.
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SplatVectorExprClass;
+ }
+
+ // Iterators
+ child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
+ const_child_range children() const {
+ return const_child_range(&SrcExpr, &SrcExpr + 1);
+ }
+};
+
/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
/// This AST node provides support for converting a vector type to another
/// vector type of the same arity.
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index cdf8a71d54cc9..782eb04e7f993 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3050,6 +3050,7 @@ DEF_TRAVERSE_STMT(UnresolvedSYCLKernelCallStmt, {
DEF_TRAVERSE_STMT(OpenACCAsteriskSizeExpr, {})
DEF_TRAVERSE_STMT(PredefinedExpr, {})
DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(SplatVectorExpr, {})
DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
DEF_TRAVERSE_STMT(StmtExpr, {})
DEF_TRAVERSE_STMT(SourceLocExpr, {})
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 69db8252f931e..e58189fa60194 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1315,6 +1315,20 @@ class alignas(void *) Stmt {
SourceLocation Loc;
};
+ class SplatVectorExprBitfields {
+ friend class SplatVectorExpr;
+
+ LLVM_PREFERRED_TYPE(ExprBitfields)
+ unsigned : NumExprBits;
+
+ //
+ /// This is only meaningful for operations on floating point
+ /// types when additional values need to be in trailing storage.
+ /// It is 0 otherwise.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasFPFeatures : 1;
+ };
+
class ConvertVectorExprBitfields {
friend class ConvertVectorExpr;
@@ -1414,6 +1428,7 @@ class alignas(void *) Stmt {
// Clang Extensions
OpaqueValueExprBitfields OpaqueValueExprBits;
+ SplatVectorExprBitfields SplatVectorExprBits;
ConvertVectorExprBitfields ConvertVectorExprBits;
};
diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index 41ddd88a8326c..9d3e9f3da14e4 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -438,6 +438,7 @@ class TextNodeDumper
void VisitOpenACCRoutineDeclAttr(const OpenACCRoutineDeclAttr *A);
void VisitEmbedExpr(const EmbedExpr *S);
void VisitAtomicExpr(const AtomicExpr *AE);
+ void VisitSplatVectorExpr(const SplatVectorExpr *S);
void VisitConvertVectorExpr(const ConvertVectorExpr *S);
};
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 02d52b51a45c9..0d0310f7e987c 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2653,6 +2653,10 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr>
chooseExpr;
+/// Matches builtin function __builtin_splatvector.
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, SplatVectorExpr>
+ splatVectorExpr;
+
/// Matches builtin function __builtin_convertvector.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConvertVectorExpr>
convertVectorExpr;
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 06d559a5c3ce2..811d21dbff0a3 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1475,6 +1475,12 @@ def ShuffleVector : Builtin {
let Prototype = "void(...)";
}
+def SplatVector : Builtin {
+ let Spellings = ["__builtin_splatvector"];
+ let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
+ let Prototype = "void(...)";
+}
+
def ConvertVector : Builtin {
let Spellings = ["__builtin_convertvector"];
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d9d0d485f16ac..4d495196ced25 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11482,6 +11482,9 @@ def err_shufflevector_argument_too_large : Error<
def err_shufflevector_minus_one_is_undefined_behavior_constexpr : Error<
"index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position %0 is not permitted in a constexpr context">;
+def err_splatvector_non_scalar : Error<
+ "first argument to __builtin_splatvector must be a single value">;
+
def err_convertvector_non_vector : Error<
"first argument to __builtin_convertvector must be a vector">;
def err_convertvector_constexpr_unsupported_vector_cast : Error<
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index f5fa397c92ef3..9b43de13060d1 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -218,6 +218,7 @@ def CUDAKernelCallExpr : StmtNode<CallExpr>;
// Clang Extensions.
def ShuffleVectorExpr : StmtNode<Expr>;
+def SplatVectorExpr : StmtNode<Expr>;
def ConvertVectorExpr : StmtNode<Expr>;
def BlockExpr : StmtNode<Expr>;
def OpaqueValueExpr : StmtNode<Expr>;
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 3d8d42caa39cf..ad3e2235909ad 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -668,6 +668,7 @@ ALIAS("_w64" , __w64 , KEYMSCOMPAT)
ALIAS("_pascal" , __pascal , KEYBORLAND)
// Clang Extensions.
+KEYWORD(__builtin_splatvector , KEYALL)
KEYWORD(__builtin_convertvector , KEYALL)
ALIAS("__char16_t" , char16_t , KEYCXX)
ALIAS("__char32_t" , char32_t , KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 778c1a2f5c427..661d6e282a33e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2680,6 +2680,11 @@ class Sema final : public SemaBase {
// Used by C++ template instantiation.
ExprResult BuiltinShuffleVector(CallExpr *TheCall);
+ /// SplatVectorExpr - Handle __builtin_splatvector
+ ExprResult SplatVectorExpr(Expr *E, TypeSourceInfo *TInfo,
+ SourceLocation BuiltinLoc,
+ SourceLocation RParenLoc);
+
/// ConvertVectorExpr - Handle __builtin_convertvector
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
SourceLocation BuiltinLoc,
@@ -7720,6 +7725,15 @@ class Sema final : public SemaBase {
//===---------------------------- Clang Extensions ----------------------===//
+ /// ActOnSplatVectorExpr - create a new splat-vector expression from the
+ /// provided argument.
+ ///
+ /// __builtin_splatvector( value, dst type )
+ ///
+ ExprResult ActOnSplatVectorExpr(Expr *E, ParsedType ParsedDestTy,
+ SourceLocation BuiltinLoc,
+ SourceLocation RParenLoc);
+
/// ActOnConvertVectorExpr - create a new convert-vector expression from the
/// provided arguments.
///
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 671341488278e..c99aff4a6c61e 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1756,6 +1756,9 @@ enum StmtCode {
/// A ShuffleVectorExpr record.
EXPR_SHUFFLE_VECTOR,
+ /// A SplatVectorExpr record.
+ EXPR_SPLAT_VECTOR,
+
/// A ConvertVectorExpr record.
EXPR_CONVERT_VECTOR,
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3ad71a223903c..9c28fdb3a77fe 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -628,6 +628,7 @@ namespace clang {
ExpectedStmt VisitSourceLocExpr(SourceLocExpr *E);
ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
ExpectedStmt VisitChooseExpr(ChooseExpr *E);
+ ExpectedStmt VisitSplatVectorExpr(SplatVectorExpr *E);
ExpectedStmt VisitConvertVectorExpr(ConvertVectorExpr *E);
ExpectedStmt VisitShuffleVectorExpr(ShuffleVectorExpr *E);
ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
@@ -7804,6 +7805,22 @@ ExpectedStmt ASTNodeImporter::VisitChooseExpr(ChooseExpr *E) {
ToRParenLoc, CondIsTrue);
}
+ExpectedStmt ASTNodeImporter::VisitSplatVectorExpr(SplatVectorExpr *E) {
+ Error Err = Error::success();
+ auto *ToSrcExpr = importChecked(Err, E->getSrcExpr());
+ auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
+ auto ToBuiltinLoc = importChecked(Err, E->getBuiltinLoc());
+ auto ToType = importChecked(Err, E->getType());
+ auto *ToTSI = importChecked(Err, E->getTypeSourceInfo());
+ if (Err)
+ return std::move(Err);
+
+ return SplatVectorExpr::Create(
+ Importer.getToContext(), ToSrcExpr, ToTSI, ToType, E->getValueKind(),
+ E->getObjectKind(), ToBuiltinLoc, ToRParenLoc,
+ E->getStoredFPFeaturesOrDefault());
+}
+
ExpectedStmt ASTNodeImporter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
Error Err = Error::success();
auto *ToSrcExpr = importChecked(Err, E->getSrcExpr());
diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index a819bb6dec599..80a98fe80c587 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -192,6 +192,15 @@ ExprDependence clang::computeDependence(StmtExpr *E, unsigned TemplateDepth) {
return D & ~ExprDependence::UnexpandedPack;
}
+ExprDependence clang::computeDependence(SplatVectorExpr *E) {
+ auto D = toExprDependenceAsWritten(
+ E->getTypeSourceInfo()->getType()->getDependence()) |
+ E->getSrcExpr()->getDependence();
+ if (!E->getType()->isDependentType())
+ D &= ~ExprDependence::Type;
+ return D;
+}
+
ExprDependence clang::computeDependence(ConvertVectorExpr *E) {
auto D = toExprDependenceAsWritten(
E->getTypeSourceInfo()->getType()->getDependence()) |
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9a9a76e265f6a..4644e3a86d7f0 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3845,6 +3845,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case SubstNonTypeTemplateParmExprClass:
case MaterializeTemporaryExprClass:
case ShuffleVectorExprClass:
+ case SplatVectorExprClass:
case ConvertVectorExprClass:
case AsTypeExprClass:
case CXXParenListInitExprClass:
@@ -4007,6 +4008,8 @@ FPOptions Expr::getFPFeaturesInEffect(const LangOptions &LO) const {
return BO->getFPFeaturesInEffect(LO);
if (auto Cast = dyn_cast<CastExpr>(this))
return Cast->getFPFeaturesInEffect(LO);
+ if (auto SplatVector = dyn_cast<SplatVectorExpr>(this))
+ return SplatVector->getFPFeaturesInEffect(LO);
if (auto ConvertVector = dyn_cast<ConvertVectorExpr>(this))
return ConvertVector->getFPFeaturesInEffect(LO);
return FPOptions::defaultWithoutTrailingStorage(LO);
@@ -5684,6 +5687,24 @@ OpenACCAsteriskSizeExpr::CreateEmpty(const ASTContext &C) {
return new (C) OpenACCAsteriskSizeExpr({}, C.IntTy);
}
+SplatVectorExpr *SplatVectorExpr::CreateEmpty(const ASTContext &C,
+ bool hasFPFeatures) {
+ void *Mem = C.Allocate(total...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/212758
More information about the cfe-commits
mailing list