[clang] [RFC][clang] Add `__builtin_convert_from_arbitrary_fp` (PR #212647)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 28 16:59:33 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Chinmay Deshpande (chinmaydd)

<details>
<summary>Changes</summary>

Expose the `llvm.convert.from.arbitrary.fp` intrinsic as a target-independent builtin. It reinterprets an integer as the bits of a narrow floating-point format that has no corresponding C type, and widens it to a native floating-point type:

```
  _Float16 h = __builtin_convert_from_arbitrary_fp(b, "Float8E4M3FN", _Float16);
```

Since the destination type cannot be derived from the arguments, it is passed as a type argument and the builtin is parsed as a keyword, following the `__builtin_convertvector` precedent.

The format is a string literal validated with `APFloatBase::isValidArbitraryFPFormat`, so every format the IR verifier accepts is accepted here; formats that no target lowers yet keep being reported by the backend. The integer operand may be any integer type whose width matches the format, which covers char/unsigned char for the 8-bit formats and `_BitInt` for the narrower ones. 

Vector operands are supported with matching element counts. Clang only permits `_BitInt` vector elements of power-of-two width, so vectors of the 6-bit formats cannot be spelled.

NOTE: Support for `__builtin_convert_to_arbitrary_fp` will follow.

AI Disclosure: Most of this PR was generated with the help of an LLM, but I have reviewed every line of it.

---

Patch is 61.84 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/212647.diff


40 Files Affected:

- (modified) clang/docs/LanguageExtensions.md (+55) 
- (modified) clang/docs/ReleaseNotes.md (+2) 
- (modified) clang/include/clang/AST/ComputeDependence.h (+2) 
- (modified) clang/include/clang/AST/Expr.h (+66) 
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+3) 
- (modified) clang/include/clang/Basic/Builtins.td (+6) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+22) 
- (modified) clang/include/clang/Basic/StmtNodes.td (+1) 
- (modified) clang/include/clang/Basic/TokenKinds.def (+1) 
- (modified) clang/include/clang/Sema/Sema.h (+20) 
- (modified) clang/include/clang/Serialization/ASTBitCodes.h (+3) 
- (modified) clang/lib/AST/ASTImporter.cpp (+18) 
- (modified) clang/lib/AST/ComputeDependence.cpp (+9) 
- (modified) clang/lib/AST/Expr.cpp (+1) 
- (modified) clang/lib/AST/ExprClassification.cpp (+1) 
- (modified) clang/lib/AST/ExprConstant.cpp (+1) 
- (modified) clang/lib/AST/ItaniumMangle.cpp (+11) 
- (modified) clang/lib/AST/StmtPrinter.cpp (+11) 
- (modified) clang/lib/AST/StmtProfile.cpp (+6) 
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+14) 
- (modified) clang/lib/Parse/ParseExpr.cpp (+42) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+114) 
- (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+1) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+9) 
- (modified) clang/lib/Sema/TreeTransform.h (+32) 
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+14) 
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+11) 
- (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1) 
- (modified) clang/test/AST/ast-dump-expr.c (+8) 
- (added) clang/test/CodeGen/builtins-convert-from-arbitrary-fp.c (+194) 
- (modified) clang/test/CodeGenCXX/mangle-exprs.cpp (+18) 
- (added) clang/test/Index/convert-from-arbitrary-fp.c (+14) 
- (modified) clang/test/PCH/exprs.c (+3) 
- (modified) clang/test/PCH/exprs.h (+5) 
- (added) clang/test/Sema/builtins-convert-from-arbitrary-fp-rvv.c (+9) 
- (added) clang/test/Sema/builtins-convert-from-arbitrary-fp.c (+89) 
- (added) clang/test/SemaCXX/builtins-convert-from-arbitrary-fp.cpp (+60) 
- (added) clang/test/SemaOpenCL/builtins-convert-from-arbitrary-fp.cl (+5) 
- (modified) clang/tools/libclang/CIndex.cpp (+6) 
- (modified) clang/tools/libclang/CXCursor.cpp (+1) 


``````````diff
diff --git a/clang/docs/LanguageExtensions.md b/clang/docs/LanguageExtensions.md
index f5313e0378ca0..087d9e15855ca 100644
--- a/clang/docs/LanguageExtensions.md
+++ b/clang/docs/LanguageExtensions.md
@@ -3610,6 +3610,61 @@ C-style cast applied to each element of the first argument.
 
 Query for this feature with `__has_builtin(__builtin_convertvector)`.
 
+(langext-__builtin_convert_from_arbitrary_fp)=
+(langext-builtin-convert-from-arbitrary-fp)=
+
+### `__builtin_convert_from_arbitrary_fp`
+
+`__builtin_convert_from_arbitrary_fp` interprets an integer as the bits of a value in a narrow floating-point format that has no corresponding C type, and converts it to a native floating-point type.
+
+**Syntax**:
+
+```c++
+__builtin_convert_from_arbitrary_fp(bits, format, dst_type)
+```
+
+**Examples**:
+
+```c++
+typedef unsigned char uchar4 __attribute__((ext_vector_type(4)));
+typedef float float4 __attribute__((ext_vector_type(4)));
+
+unsigned char b; uchar4 vb;
+
+// Interpret b as a Float8E4M3FN value and widen it to _Float16.
+__builtin_convert_from_arbitrary_fp(b, "Float8E4M3FN", _Float16)
+
+// The same, elementwise, for four Float8E5M2 values.
+__builtin_convert_from_arbitrary_fp(vb, "Float8E5M2", float4)
+```
+
+**Description**:
+
+`bits` is an integer, or a vector of integers, holding the encoded floating-point value.
+`format` must be an ordinary string literal naming the source format.
+`dst_type` must be a floating-point type, or a vector of floating-point types with the same number of elements as `bits`.
+Supported destination element semantics are IEEE half, bfloat16, IEEE single, and IEEE double.
+Other destination types, including types with x87 extended, PPC double-double, or IEEE quad semantics and the `__mfp8` type, are rejected.
+Vector source and destination operands must be fixed-length vectors; sizeless SVE and RVV vectors are rejected.
+The width of `bits` (its element width, for vectors) must equal the width of `format`.
+
+Clang's target-independent semantic analysis accepts all verifier-valid format names:
+
+- 8-bit: `"Float8E5M2"`, `"Float8E5M2FNUZ"`, `"Float8E4M3"`, `"Float8E4M3FN"`,
+  `"Float8E4M3FNUZ"`, `"Float8E4M3B11FNUZ"`, `"Float8E3M4"`, `"Float8E8M0FNU"`
+- 6-bit: `"Float6E3M2FN"`, `"Float6E2M3FN"`
+- 4-bit: `"Float4E2M1FN"`
+
+Only the signedness-free width of `bits` matters, so for an 8-bit format any of `char`, `signed char`, `unsigned char`, or `_BitInt(8)` of either signedness may be used.
+The 6-bit and 4-bit formats require a `_BitInt` of the matching width.
+Because Clang only permits `_BitInt` vector elements whose width is a power of two, vectors of the 6-bit formats cannot be expressed.
+
+This builtin maps to the `llvm.convert.from.arbitrary.fp` intrinsic; see its description in the LLVM Language Reference for the exact conversion semantics.
+Backend lowering is currently implemented only for `"Float8E5M2"`, `"Float8E4M3FN"`, `"Float6E3M2FN"`, `"Float6E2M3FN"`, and `"Float4E2M1FN"`; this does not guarantee support on any particular target.
+The other verifier-accepted formats, `"Float8E5M2FNUZ"`, `"Float8E4M3"`, `"Float8E4M3FNUZ"`, `"Float8E4M3B11FNUZ"`, `"Float8E3M4"`, and `"Float8E8M0FNU"`, can be emitted to LLVM IR but currently fail during backend lowering.
+
+Query for this feature with `__has_builtin(__builtin_convert_from_arbitrary_fp)`.
+
 ### `__builtin_bitreverse`
 
 - `__builtin_bitreverse8`
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index f631d9f858f9f..2ae50448d49d6 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -146,6 +146,8 @@ features cannot lower the translation-unit ABI level;
 
 ### Non-comprehensive list of changes in this release
 
+- Added `__builtin_convert_from_arbitrary_fp`, which converts an integer holding the bits of a narrow floating-point format such as `Float8E4M3FN` to a native floating-point type.
+
 ### New Compiler Flags
 
 - New option `-fdefined-pointer-subtraction` added to preserve stable semantics
diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h
index 3a3c86842501a..ed843cbe4750b 100644
--- a/clang/include/clang/AST/ComputeDependence.h
+++ b/clang/include/clang/AST/ComputeDependence.h
@@ -38,6 +38,7 @@ class ConditionalOperator;
 class BinaryConditionalOperator;
 class StmtExpr;
 class ConvertVectorExpr;
+class ConvertFromArbitraryFPExpr;
 class VAArgExpr;
 class ChooseExpr;
 class NoInitExpr;
@@ -129,6 +130,7 @@ ExprDependence computeDependence(ConditionalOperator *E);
 ExprDependence computeDependence(BinaryConditionalOperator *E);
 ExprDependence computeDependence(StmtExpr *E, unsigned TemplateDepth);
 ExprDependence computeDependence(ConvertVectorExpr *E);
+ExprDependence computeDependence(ConvertFromArbitraryFPExpr *E);
 ExprDependence computeDependence(VAArgExpr *E);
 ExprDependence computeDependence(ChooseExpr *E);
 ExprDependence computeDependence(NoInitExpr *E);
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index f95f87cc4e8e0..992fbf76b158d 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4842,6 +4842,72 @@ class ConvertVectorExpr final
   }
 };
 
+/// ConvertFromArbitraryFPExpr - Clang builtin function
+/// __builtin_convert_from_arbitrary_fp. This AST node provides support for
+/// interpreting an integer as the bits of the specified floating-point format
+/// and converting it to the destination floating-point type.
+class ConvertFromArbitraryFPExpr : public Expr {
+  enum { SRC, FORMAT, END_EXPR };
+  Stmt *SubExprs[END_EXPR];
+  TypeSourceInfo *TInfo;
+  SourceLocation BuiltinLoc, RParenLoc;
+
+  friend class ASTStmtReader;
+
+public:
+  ConvertFromArbitraryFPExpr(Expr *SrcExpr, Expr *Format, TypeSourceInfo *TI,
+                             QualType DstType, ExprValueKind VK,
+                             ExprObjectKind OK, SourceLocation BuiltinLoc,
+                             SourceLocation RParenLoc)
+      : Expr(ConvertFromArbitraryFPExprClass, DstType, VK, OK), TInfo(TI),
+        BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {
+    SubExprs[SRC] = SrcExpr;
+    SubExprs[FORMAT] = Format;
+    setDependence(computeDependence(this));
+  }
+
+  explicit ConvertFromArbitraryFPExpr(EmptyShell Empty)
+      : Expr(ConvertFromArbitraryFPExprClass, Empty) {}
+
+  /// getSrcExpr - Return the integer expression holding the format bits.
+  Expr *getSrcExpr() const { return cast<Expr>(SubExprs[SRC]); }
+
+  /// getFormatExpr - Return the expression naming the source format.
+  Expr *getFormatExpr() const { return cast<Expr>(SubExprs[FORMAT]); }
+
+  /// getFormat - Return the name of the source arbitrary floating-point format.
+  StringRef getFormat() const {
+    return cast<StringLiteral>(getFormatExpr()->IgnoreParenImpCasts())
+        ->getString();
+  }
+
+  /// getTypeSourceInfo - Return the destination type.
+  TypeSourceInfo *getTypeSourceInfo() const { return TInfo; }
+  void setTypeSourceInfo(TypeSourceInfo *TI) { TInfo = TI; }
+
+  /// getBuiltinLoc - Return the location of the
+  /// __builtin_convert_from_arbitrary_fp 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() == ConvertFromArbitraryFPExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+  }
+  const_child_range children() const {
+    return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+  }
+};
+
 /// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
 /// This AST node is similar to the conditional operator (?:) in C, with
 /// the following exceptions:
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index cdf8a71d54cc9..0cac0b9c1eeb0 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3051,6 +3051,9 @@ DEF_TRAVERSE_STMT(OpenACCAsteriskSizeExpr, {})
 DEF_TRAVERSE_STMT(PredefinedExpr, {})
 DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
 DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertFromArbitraryFPExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
 DEF_TRAVERSE_STMT(StmtExpr, {})
 DEF_TRAVERSE_STMT(SourceLocExpr, {})
 DEF_TRAVERSE_STMT(EmbedExpr, {
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 06d559a5c3ce2..8c33f9f8ace88 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1481,6 +1481,12 @@ def ConvertVector : Builtin {
   let Prototype = "void(...)";
 }
 
+def ConvertFromArbitraryFP : Builtin {
+  let Spellings = ["__builtin_convert_from_arbitrary_fp"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "void(...)";
+}
+
 def MaskedLoad : Builtin {
   let Spellings = ["__builtin_masked_load"];
   let Attributes = [NoThrow, CustomTypeChecking];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d9d0d485f16ac..ee0e540685789 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11491,6 +11491,28 @@ def err_builtin_non_vector_type : Error<
 def err_convertvector_incompatible_vector : Error<
   "first two arguments to __builtin_convertvector must have the same number of elements">;
 
+def err_arbitrary_fp_invalid_format : Error<
+  "'%0' is not a supported arbitrary floating-point format">;
+def err_arbitrary_fp_non_ordinary_string_literal : Error<
+  "format argument to __builtin_convert_from_arbitrary_fp must be an ordinary "
+  "string literal">;
+def err_arbitrary_fp_int_width : Error<
+  "%select{argument type %1 must be an integer type|vector element type %1 "
+  "must be}0 %2 bits wide to match format '%3'">;
+def err_arbitrary_fp_sizeless_vector : Error<
+  "%0 argument to %1 has sizeless vector type; only fixed-length vectors are "
+  "supported">;
+def err_arbitrary_fp_non_fp_type : Error<
+  "%0 argument to %1 must be a floating-point type or a vector of "
+  "floating-point types">;
+def err_arbitrary_fp_non_int_type : Error<
+  "%0 argument to %1 must be an integer type or a vector of integer types">;
+def err_arbitrary_fp_unsupported_dst_type : Error<
+  "destination type %0 is not supported by %1">;
+def err_arbitrary_fp_incompatible_vector : Error<
+  "floating-point and integer arguments to %0 must have the same number of "
+  "elements">;
+
 def err_first_argument_to_cwsc_not_call : Error<
   "first argument to __builtin_call_with_static_chain must be a non-member call expression">;
 def err_first_argument_to_cwsc_block_call : Error<
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index f5fa397c92ef3..d2db9797ab8c7 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -219,6 +219,7 @@ def CUDAKernelCallExpr : StmtNode<CallExpr>;
 // Clang Extensions.
 def ShuffleVectorExpr : StmtNode<Expr>;
 def ConvertVectorExpr : StmtNode<Expr>;
+def ConvertFromArbitraryFPExpr : StmtNode<Expr>;
 def BlockExpr : StmtNode<Expr>;
 def OpaqueValueExpr : StmtNode<Expr>;
 def RecoveryExpr : StmtNode<Expr>;
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 3d8d42caa39cf..d82cd66b13920 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -669,6 +669,7 @@ ALIAS("_pascal"      , __pascal   , KEYBORLAND)
 
 // Clang Extensions.
 KEYWORD(__builtin_convertvector          , KEYALL)
+KEYWORD(__builtin_convert_from_arbitrary_fp, KEYALL)
 ALIAS("__char16_t"   , char16_t          , KEYCXX)
 ALIAS("__char32_t"   , char32_t          , KEYCXX)
 KEYWORD(__builtin_bit_cast               , KEYALL)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index d46edeb0d2872..7bbb058a98b53 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2678,6 +2678,16 @@ class Sema final : public SemaBase {
                                SourceLocation BuiltinLoc,
                                SourceLocation RParenLoc);
 
+  /// ConvertFromArbitraryFPExpr - Handle __builtin_convert_from_arbitrary_fp
+  ExprResult ConvertFromArbitraryFPExpr(Expr *E, Expr *Format,
+                                        TypeSourceInfo *TInfo,
+                                        SourceLocation BuiltinLoc,
+                                        SourceLocation RParenLoc);
+
+  /// Check that \p E is an ordinary string literal naming an arbitrary
+  /// floating-point format. Returns the literal, or null after diagnosing.
+  const StringLiteral *CheckArbitraryFPFormatArg(Expr *E);
+
   static StringRef GetFormatStringTypeName(FormatStringType FST);
   static FormatStringType GetFormatStringType(StringRef FormatFlavor);
   static FormatStringType GetFormatStringType(const FormatAttr *Format);
@@ -7722,6 +7732,16 @@ class Sema final : public SemaBase {
                                     SourceLocation BuiltinLoc,
                                     SourceLocation RParenLoc);
 
+  /// ActOnConvertFromArbitraryFPExpr - create a new convert-from-arbitrary-fp
+  /// expression from the provided arguments.
+  ///
+  /// __builtin_convert_from_arbitrary_fp( value, format, dst type )
+  ///
+  ExprResult ActOnConvertFromArbitraryFPExpr(Expr *E, Expr *Format,
+                                             ParsedType ParsedDestTy,
+                                             SourceLocation BuiltinLoc,
+                                             SourceLocation RParenLoc);
+
   //===---------------------------- OpenCL Features -----------------------===//
 
   /// Parse a __builtin_astype expression.
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 671341488278e..dda950cefc857 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1759,6 +1759,9 @@ enum StmtCode {
   /// A ConvertVectorExpr record.
   EXPR_CONVERT_VECTOR,
 
+  /// A ConvertFromArbitraryFPExpr record.
+  EXPR_CONVERT_FROM_ARBITRARY_FP,
+
   /// BlockExpr
   EXPR_BLOCK,
 
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3ad71a223903c..122a2656d26d7 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -629,6 +629,7 @@ namespace clang {
     ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
     ExpectedStmt VisitChooseExpr(ChooseExpr *E);
     ExpectedStmt VisitConvertVectorExpr(ConvertVectorExpr *E);
+    ExpectedStmt VisitConvertFromArbitraryFPExpr(ConvertFromArbitraryFPExpr *E);
     ExpectedStmt VisitShuffleVectorExpr(ShuffleVectorExpr *E);
     ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
     ExpectedStmt VisitGenericSelectionExpr(GenericSelectionExpr *E);
@@ -7820,6 +7821,23 @@ ExpectedStmt ASTNodeImporter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
       E->getStoredFPFeaturesOrDefault());
 }
 
+ExpectedStmt ASTNodeImporter::VisitConvertFromArbitraryFPExpr(
+    ConvertFromArbitraryFPExpr *E) {
+  Error Err = Error::success();
+  auto *ToSrcExpr = importChecked(Err, E->getSrcExpr());
+  auto *ToFormatExpr = importChecked(Err, E->getFormatExpr());
+  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 new (Importer.getToContext()) ConvertFromArbitraryFPExpr(
+      ToSrcExpr, ToFormatExpr, ToTSI, ToType, E->getValueKind(),
+      E->getObjectKind(), ToBuiltinLoc, ToRParenLoc);
+}
+
 ExpectedStmt ASTNodeImporter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
   Error Err = Error::success();
   auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index a819bb6dec599..e028d80302c4c 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -201,6 +201,15 @@ ExprDependence clang::computeDependence(ConvertVectorExpr *E) {
   return D;
 }
 
+ExprDependence clang::computeDependence(ConvertFromArbitraryFPExpr *E) {
+  auto D = toExprDependenceAsWritten(
+               E->getTypeSourceInfo()->getType()->getDependence()) |
+           E->getSrcExpr()->getDependence();
+  if (!E->getType()->isDependentType())
+    D &= ~ExprDependence::Type;
+  return D;
+}
+
 ExprDependence clang::computeDependence(ChooseExpr *E) {
   if (E->isConditionDependent())
     return ExprDependence::TypeValueInstantiation |
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9a9a76e265f6a..a586480dc5cbb 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3846,6 +3846,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
   case MaterializeTemporaryExprClass:
   case ShuffleVectorExprClass:
   case ConvertVectorExprClass:
+  case ConvertFromArbitraryFPExprClass:
   case AsTypeExprClass:
   case CXXParenListInitExprClass:
     // These have a side-effect if any subexpression does.
diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index ef071cdef66b6..c9ac4dac810e5 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -182,6 +182,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
   case Expr::CXXThrowExprClass:
   case Expr::ShuffleVectorExprClass:
   case Expr::ConvertVectorExprClass:
+  case Expr::ConvertFromArbitraryFPExprClass:
   case Expr::IntegerLiteralClass:
   case Expr::FixedPointLiteralClass:
   case Expr::CharacterLiteralClass:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a3385d3b7318f..9ba5bcded84e4 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -22354,6 +22354,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
   case Expr::ObjCAvailabilityCheckExprClass:
   case Expr::ShuffleVectorExprClass:
   case Expr::ConvertVectorExprClass:
+  case Expr::ConvertFromArbitraryFPExprClass:
   case Expr::BlockExprClass:
   case Expr::NoStmtClass:
   case Expr::OpaqueValueExprClass:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index f8e6b898be250..263ff66aba332 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -5968,6 +5968,17 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
     Out << "v18co_yield";
     mangleExpression(cast<CoawaitExpr>(E)->getOperand());
     break;
+
+  case Expr::ConvertFromArbitraryFPExprClass: {
+    const auto *CE = cast<ConvertFromArbitraryFPExpr>(E);
+    NotPrimaryExpr();
+    mangleVendorType("__builtin_convert_from_arbitrary_fp");
+    mangleTemplateArgExpr(CE->getSrcExpr());
+    mangleVendorType(CE->getFormat());
+    mangleType(CE->getTypeSourceInfo()->getType());
+    Out << 'E';
+    break;
+  }
   case Expr::SYCLUniqueStableNameExprClass: {
     const auto *USN = cast<SYCLUniqueStableNameExpr>(E);
     NotPrimaryExpr();
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 877191d456b35..57866934df997 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1995,6 +1995,17 @@ void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
   OS << ")";
 }
 
+void StmtPrinter::VisitConvertFromArbitraryFPExpr(
+    ConvertFromArbitraryFPExpr *Node) {
+  OS << "__builtin_convert_from_arbitrary_fp(";
+  PrintExpr(Node->getSrcExpr());
+  OS << ", ";
+  PrintExpr(Node->getFormatExpr());
+  OS << ", ";
+  Node->getTypeSourceInfo()->getType().print(OS, Policy);
+  OS << ")";
+}
+
 void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
   if (Node->getSyntacticForm()) {
     Visit(Node->getSyntacticForm());
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 00c132f1ed9e...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/212647


More information about the cfe-commits mailing list