aqjune created this revision.
Herald added subscribers: steakhal, martong, arphaman.
Herald added a reviewer: shafik.
Herald added a reviewer: NoQ.
Herald added a project: All.
aqjune requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch adds a builtin constant that lowers to `freeze(poison)`.
This is necessary to patch the intrinsics like e.g., `mm256_castsi128_si256` to 
be lowered to the following sequence:

  %a1 = freeze <2 x double> poison // <- would like to represent this as 
'__builtin_unspecified_value' in C/C++.
  %res = shufflevector <2 x double> %a0, <2 x double> %a1, <4 x i32> <i32 0, 
i32 1, i32 2, i32 3>

Currently it is being lowered to:

  %res = shufflevector <2x  double> %a0, undef, <4 x i32> <i32 0, i32 1, i32 
-1, i32 -1>

The current lowering may incorrectly introduce undefined behavior.

A related, previous patch was here: https://reviews.llvm.org/D130339


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136737

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===================================================================
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -475,6 +475,10 @@
     K = CXCursor_GNUNullExpr;
     break;
 
+  case Stmt::UnspecifiedValueExprClass:
+    K = CXCursor_UnspecifiedValueExpr;
+    break;
+
   case Stmt::CXXStaticCastExprClass:
     K = CXCursor_CXXStaticCastExpr;
     break;
Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1889,6 +1889,7 @@
     case Stmt::ObjCSelectorExprClass:
     case Stmt::ParenListExprClass:
     case Stmt::ShuffleVectorExprClass:
+    case Stmt::UnspecifiedValueExprClass:
     case Stmt::ConvertVectorExprClass:
     case Stmt::VAArgExprClass:
     case Stmt::CUDAKernelCallExprClass:
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1195,6 +1195,12 @@
   Code = serialization::EXPR_GNU_NULL;
 }
 
+void ASTStmtWriter::VisitUnspecifiedValueExpr(UnspecifiedValueExpr *E) {
+  VisitExpr(E);
+  Record.AddSourceLocation(E->getTokenLocation());
+  Code = serialization::EXPR_UNSPECIFIED_VALUE;
+}
+
 void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getNumSubExprs());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1316,6 +1316,11 @@
   E->setTokenLocation(readSourceLocation());
 }
 
+void ASTStmtReader::VisitUnspecifiedValueExpr(UnspecifiedValueExpr *E) {
+  VisitExpr(E);
+  E->setTokenLocation(readSourceLocation());
+}
+
 void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
   VisitExpr(E);
   SmallVector<Expr *, 16> Exprs;
@@ -3077,6 +3082,10 @@
       S = new (Context) GNUNullExpr(Empty);
       break;
 
+    case EXPR_UNSPECIFIED_VALUE:
+      S = new (Context) UnspecifiedValueExpr(Empty);
+      break;
+
     case EXPR_SHUFFLE_VECTOR:
       S = new (Context) ShuffleVectorExpr(Empty);
       break;
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -11719,6 +11719,12 @@
   return E;
 }
 
+template<typename Derived>
+ExprResult
+TreeTransform<Derived>::TransformUnspecifiedValueExpr(UnspecifiedValueExpr *E) {
+  return E;
+}
+
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
Index: clang/lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- clang/lib/Sema/SemaExceptionSpec.cpp
+++ clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1404,6 +1404,7 @@
   case Expr::SourceLocExprClass:
   case Expr::ConceptSpecializationExprClass:
   case Expr::RequiresExprClass:
+  case Expr::UnspecifiedValueExprClass:
     // These expressions can never throw.
     return CT_Cannot;
 
Index: clang/lib/AST/StmtProfile.cpp
===================================================================
--- clang/lib/AST/StmtProfile.cpp
+++ clang/lib/AST/StmtProfile.cpp
@@ -1472,6 +1472,10 @@
   VisitExpr(S);
 }
 
+void StmtProfiler::VisitUnspecifiedValueExpr(const UnspecifiedValueExpr *S) {
+  VisitExpr(S);
+}
+
 void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
   VisitExpr(S);
 }
Index: clang/lib/AST/StmtPrinter.cpp
===================================================================
--- clang/lib/AST/StmtPrinter.cpp
+++ clang/lib/AST/StmtPrinter.cpp
@@ -1674,6 +1674,10 @@
   OS << "__null";
 }
 
+void StmtPrinter::VisitUnspecifiedValueExpr(UnspecifiedValueExpr *) {
+  OS << "__builtin_unspecified_value";
+}
+
 void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
   OS << "__builtin_shufflevector(";
   for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
Index: clang/lib/AST/ExprClassification.cpp
===================================================================
--- clang/lib/AST/ExprClassification.cpp
+++ clang/lib/AST/ExprClassification.cpp
@@ -167,6 +167,7 @@
   case Expr::OffsetOfExprClass:
   case Expr::CXXThrowExprClass:
   case Expr::ShuffleVectorExprClass:
+  case Expr::UnspecifiedValueExprClass:
   case Expr::ConvertVectorExprClass:
   case Expr::IntegerLiteralClass:
   case Expr::FixedPointLiteralClass:
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -3638,6 +3638,7 @@
   case SubstNonTypeTemplateParmExprClass:
   case MaterializeTemporaryExprClass:
   case ShuffleVectorExprClass:
+  case UnspecifiedValueExprClass:
   case ConvertVectorExprClass:
   case AsTypeExprClass:
     // These have a side-effect if any subexpression does.
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -618,6 +618,7 @@
     ExpectedStmt VisitChooseExpr(ChooseExpr *E);
     ExpectedStmt VisitShuffleVectorExpr(ShuffleVectorExpr *E);
     ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
+    ExpectedStmt VisitUnspecifiedValueExpr(UnspecifiedValueExpr *E);
     ExpectedStmt VisitGenericSelectionExpr(GenericSelectionExpr *E);
     ExpectedStmt VisitPredefinedExpr(PredefinedExpr *E);
     ExpectedStmt VisitDeclRefExpr(DeclRefExpr *E);
@@ -6987,6 +6988,20 @@
   return new (Importer.getToContext()) GNUNullExpr(*TypeOrErr, *BeginLocOrErr);
 }
 
+ExpectedStmt ASTNodeImporter::VisitUnspecifiedValueExpr(
+    UnspecifiedValueExpr *E) {
+  ExpectedType TypeOrErr = import(E->getType());
+  if (!TypeOrErr)
+    return TypeOrErr.takeError();
+
+  ExpectedSLoc BeginLocOrErr = import(E->getBeginLoc());
+  if (!BeginLocOrErr)
+    return BeginLocOrErr.takeError();
+
+  return new (Importer.getToContext()) UnspecifiedValueExpr(*TypeOrErr,
+                                                            *BeginLocOrErr);
+}
+
 ExpectedStmt
 ASTNodeImporter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   Error Err = Error::success();
Index: clang/include/clang/Serialization/ASTBitCodes.h
===================================================================
--- clang/include/clang/Serialization/ASTBitCodes.h
+++ clang/include/clang/Serialization/ASTBitCodes.h
@@ -1706,6 +1706,9 @@
   /// A GNUNullExpr record.
   EXPR_GNU_NULL,
 
+  // An UnspecifiedValueExpr record.
+  EXPR_UNSPECIFIED_VALUE,
+
   /// A SourceLocExpr record.
   EXPR_SOURCE_LOC,
 
Index: clang/include/clang/Basic/StmtNodes.td
===================================================================
--- clang/include/clang/Basic/StmtNodes.td
+++ clang/include/clang/Basic/StmtNodes.td
@@ -202,6 +202,7 @@
 def TypoExpr : StmtNode<Expr>;
 def RecoveryExpr : StmtNode<Expr>;
 def BuiltinBitCastExpr : StmtNode<ExplicitCastExpr>;
+def UnspecifiedValueExpr : StmtNode<Expr>;
 
 // Microsoft Extensions.
 def MSPropertyRefExpr : StmtNode<Expr>;
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2797,6 +2797,7 @@
 DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
 DEF_TRAVERSE_STMT(StmtExpr, {})
 DEF_TRAVERSE_STMT(SourceLocExpr, {})
+DEF_TRAVERSE_STMT(UnspecifiedValueExpr, {})
 
 DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4634,6 +4634,43 @@
   }
 };
 
+/// UnspecifiedValueExpr - clang-specific value __builtin_unspecified_value.
+/// This AST node represents freeze(poison) in LLVM IR.
+class UnspecifiedValueExpr : public Expr {
+  /// TokenLoc - The location of the __builtin_specified_value keyword.
+  SourceLocation TokenLoc;
+
+public:
+  UnspecifiedValueExpr(QualType Ty, SourceLocation Loc)
+      : Expr(UnspecifiedValueExprClass, Ty, VK_PRValue, OK_Ordinary),
+        TokenLoc(Loc) {
+    setDependence(ExprDependence::None);
+  }
+
+  /// Build an empty GNU __null expression.
+  explicit UnspecifiedValueExpr(EmptyShell Empty) :
+      Expr(UnspecifiedValueExprClass, Empty) { }
+
+  /// getTokenLocation - The location of the __null token.
+  SourceLocation getTokenLocation() const { return TokenLoc; }
+  void setTokenLocation(SourceLocation L) { TokenLoc = L; }
+
+  SourceLocation getBeginLoc() const LLVM_READONLY { return TokenLoc; }
+  SourceLocation getEndLoc() const LLVM_READONLY { return TokenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnspecifiedValueExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+};
+
 /// Represents a call to the builtin function \c __builtin_va_arg.
 class VAArgExpr : public Expr {
   Stmt *Val;
Index: clang/include/clang-c/Index.h
===================================================================
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -1531,7 +1531,12 @@
    */
   CXCursor_RequiresExpr = 154,
 
-  CXCursor_LastExpr = CXCursor_RequiresExpr,
+  /**
+   * A clang-builtin of unspecified value.
+   */
+  CXCursor_UnspecifiedValueExpr = 155,
+
+  CXCursor_LastExpr = CXCursor_UnspecifiedValueExpr,
 
   /* Statements */
   CXCursor_FirstStmt = 200,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to