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&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html";>Stmt</a>&gt;</td><td
 class="name" onclick="toggle('splatVectorExpr0')"><a 
name="splatVectorExpr0Anchor">splatVectorExpr</a></td><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1SplatVectorExpr.html";>SplatVectorExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="splatVectorExpr0"><pre>Matches builtin 
function __builtin_splatvector.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html";>Stmt</a>&gt;</td><td
 class="name" onclick="toggle('stmt0')"><a 
name="stmt0Anchor">stmt</a></td><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html";>Stmt</a>&gt;...</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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to