https://github.com/CarolineConcatto created https://github.com/llvm/llvm-project/pull/97277
ARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic. >From the PR#323: ``` ACLE defines the `__fpm8` type, which can be used for the E5M2 and E4M3 8-bit floating-point formats. It is a storage and interchange only type with no arithmetic operations other than intrinsic calls. ```` The type should be an opaque type and its format in undefined in Clang. Only defined in the backend by a status/format register, for AArch64 the FPMR. This patch is an attempt to the add the fpm8_t scalar type. It has a parser and codegen for the new scalar type. The patch it is lowering to and 8bit unsigned as it has no format. But maybe we should add another opaque type. [1] https://github.com/ARM-software/acle/pull/323 >From fbeca5c357b1a5589757bbb2cac8208f8c9027ab Mon Sep 17 00:00:00 2001 From: Caroline Concatto <caroline.conca...@arm.com> Date: Mon, 24 Jun 2024 09:59:24 +0000 Subject: [PATCH] [WIP][CLANG][AArch64] Add the modal 8 bit floating-point scalar type ARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic. >From the PR#323: ``` ACLE defines the `__fpm8` type, which can be used for the E5M2 and E4M3 8-bit floating-point formats. It is a storage and interchange only type with no arithmetic operations other than intrinsic calls. ```` The type should be an opaque type and its format in undefined in Clang. Only defined in the backend by a status/format register, for AArch64 the FPMR. This patch is an attempt to the add the fpm8_t scalar type. It has a parser and codegen for the new scalar type. The patch it is lowering to and 8bit unsigned as it has no format. But maybe we should add another opaque type. [1] https://github.com/ARM-software/acle/pull/323 --- clang/include/clang/AST/ASTContext.h | 1 + clang/include/clang/AST/BuiltinTypes.def | 4 + clang/include/clang/AST/Type.h | 5 + clang/include/clang/Basic/Specifiers.h | 1 + clang/include/clang/Basic/TokenKinds.def | 1 + clang/include/clang/Sema/DeclSpec.h | 1 + .../include/clang/Serialization/ASTBitCodes.h | 4 +- clang/lib/AST/ASTContext.cpp | 7 ++ clang/lib/AST/ItaniumMangle.cpp | 1 + clang/lib/AST/Type.cpp | 2 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/CodeGen/CodeGenTypes.cpp | 4 +- clang/lib/CodeGen/ItaniumCXXABI.cpp | 1 + clang/lib/Index/USRGeneration.cpp | 1 + clang/lib/Lex/Lexer.cpp | 1 + clang/lib/Parse/ParseDecl.cpp | 7 ++ clang/lib/Parse/ParseExpr.cpp | 1 + clang/lib/Parse/ParseExprCXX.cpp | 3 + clang/lib/Parse/ParseTentative.cpp | 2 + clang/lib/Sema/DeclSpec.cpp | 3 + clang/lib/Sema/SemaTemplateVariadic.cpp | 1 + clang/lib/Sema/SemaType.cpp | 3 + clang/lib/Serialization/ASTCommon.cpp | 3 + clang/test/AST/fpm8_opaque.cpp | 91 +++++++++++++++++++ clang/test/CodeGen/fpm8_opaque.c | 24 +++++ 25 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 clang/test/AST/fpm8_opaque.cpp create mode 100644 clang/test/CodeGen/fpm8_opaque.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 53ece996769a8..532ec05ab90a6 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1115,6 +1115,7 @@ class ASTContext : public RefCountedBase<ASTContext> { CanQualType SatShortFractTy, SatFractTy, SatLongFractTy; CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy, SatUnsignedLongFractTy; + CanQualType Fpm8Ty; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index 444be4311a743..0c1cccf4f73b8 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -221,6 +221,10 @@ FLOATING_TYPE(Float128, Float128Ty) // '__ibm128' FLOATING_TYPE(Ibm128, Ibm128Ty) + +// '__fpm8' +UNSIGNED_TYPE(Fpm8, Fpm8Ty) + //===- Language-specific types --------------------------------------------===// // This is the type of C++0x 'nullptr'. diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index fab233b62d8d1..9f835b8459847 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2492,6 +2492,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isDoubleType() const; bool isBFloat16Type() const; bool isFloat128Type() const; + bool isFpm8Type() const; bool isIbm128Type() const; bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) @@ -7944,6 +7945,10 @@ inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } +inline bool Type::isFpm8Type() const { + return isSpecificBuiltinType(BuiltinType::Fpm8); +} + inline bool Type::isFloat128Type() const { return isSpecificBuiltinType(BuiltinType::Float128); } diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index fb11e8212f8b6..b4db94d273949 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -68,6 +68,7 @@ namespace clang { TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension TST_Fract, TST_BFloat16, + TST_Fpm8, TST_float, TST_double, TST_float128, diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 9c4b17465e18a..c08cf760962f3 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -655,6 +655,7 @@ KEYWORD(__bool , KEYALTIVEC|KEYZVECTOR) // ARM NEON extensions. ALIAS("__fp16", half , KEYALL) KEYWORD(__bf16 , KEYALL) +KEYWORD(__fpm8 , KEYALL) // OpenCL Extension. KEYWORD(half , HALFSUPPORT) diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 23bc780e04979..097cb8eb642ac 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -287,6 +287,7 @@ class DeclSpec { static const TST TST_bitint = clang::TST_bitint; static const TST TST_half = clang::TST_half; static const TST TST_BFloat16 = clang::TST_BFloat16; + static const TST TST_Fpm8 = clang::TST_Fpm8; static const TST TST_float = clang::TST_float; static const TST TST_double = clang::TST_double; static const TST TST_float16 = clang::TST_Float16; diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index a4728b1c06b3f..b2853c5e787d6 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1078,6 +1078,8 @@ enum PredefinedTypeIDs { /// \brief The '__ibm128' type PREDEF_TYPE_IBM128_ID = 74, + PREDEF_TYPE_FPM8_ID = 75, + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1109,7 +1111,7 @@ enum PredefinedTypeIDs { /// /// Type IDs for non-predefined types will start at /// NUM_PREDEF_TYPE_IDs. -const unsigned NUM_PREDEF_TYPE_IDS = 503; +const unsigned NUM_PREDEF_TYPE_IDS = 504; // Ensure we do not overrun the predefined types we reserved // in the enum PredefinedTypeIDs above. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 34aa399fda2f8..7d810c1f8751e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1408,6 +1408,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, // half type (OpenCL 6.1.1.1) / ARM NEON __fp16 InitBuiltinType(HalfTy, BuiltinType::Half); + InitBuiltinType(Fpm8Ty, BuiltinType::Fpm8); + InitBuiltinType(BFloat16Ty, BuiltinType::BFloat16); // Builtin type used to help define __builtin_va_list. @@ -1977,6 +1979,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Width = Target->getBoolWidth(); Align = Target->getBoolAlign(); break; + case BuiltinType::Fpm8: case BuiltinType::Char_S: case BuiltinType::Char_U: case BuiltinType::UChar: @@ -8129,6 +8132,7 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C, case BuiltinType::LongDouble: return 'D'; case BuiltinType::NullPtr: return '*'; // like char* + case BuiltinType::Fpm8: case BuiltinType::BFloat16: case BuiltinType::Float16: case BuiltinType::Float128: @@ -11466,6 +11470,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, else Type = Context.CharTy; break; + case '£': + Type = Context.Fpm8Ty; + break; case 'b': // boolean assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!"); Type = Context.BoolTy; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index ed9e6eeb36c75..f974cf1b5f8a8 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3181,6 +3181,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { case BuiltinType::SChar: Out << 'a'; break; + case BuiltinType::Fpm8: case BuiltinType::WChar_S: case BuiltinType::WChar_U: Out << 'w'; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 33acae2cbafac..f629ae6d7b016 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3372,6 +3372,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return "unsigned __int128"; case Half: return Policy.Half ? "half" : "__fp16"; + case Fpm8: + return "__fpm8"; case BFloat16: return "__bf16"; case Float: diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 9dd90d9bf4e54..8df92d3921c44 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -361,6 +361,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::Long: case BuiltinType::LongLong: case BuiltinType::Int128: + case BuiltinType::Fpm8: case BuiltinType::Half: case BuiltinType::Float: case BuiltinType::Double: diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 0a926e4ac27fe..626525f66e3e7 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -419,7 +419,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { Context.getFloatTypeSemantics(T), /* UseNativeHalf = */ false); break; - + case BuiltinType::Fpm8: + ResultType = llvm::Type::getInt8Ty(getLLVMContext()); + break; case BuiltinType::NullPtr: // Model std::nullptr_t as i8* ResultType = llvm::PointerType::getUnqual(getLLVMContext()); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 5a3e83de625c9..8ae3c1c38b3e5 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3331,6 +3331,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { case BuiltinType::Float: case BuiltinType::Double: case BuiltinType::LongDouble: + case BuiltinType::Fpm8: case BuiltinType::Float16: case BuiltinType::Float128: case BuiltinType::Ibm128: diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 31c4a3345c09d..553b788ee0e75 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -691,6 +691,7 @@ void USRGenerator::VisitType(QualType T) { Out << 'v'; break; case BuiltinType::Bool: Out << 'b'; break; + case BuiltinType::Fpm8: case BuiltinType::UChar: Out << 'c'; break; case BuiltinType::Char8: diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index e59c7805b3862..7806ea9d8604f 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -97,6 +97,7 @@ bool Token::isSimpleTypeSpecifier(const LangOptions &LangOpts) const { case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___fpm8: case tok::kw___ibm128: case tok::kw_wchar_t: case tok::kw_bool: diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c528917437332..25838d65f3e51 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4477,6 +4477,10 @@ void Parser::ParseDeclarationSpecifiers( isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw___fpm8: + isInvalid = + DS.SetTypeSpecType(DeclSpec::TST_Fpm8, Loc, PrevSpec, DiagID, Policy); + break; case tok::kw_half: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy); @@ -5752,6 +5756,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { case tok::kw__ExtInt: case tok::kw__BitInt: case tok::kw___bf16: + case tok::kw___fpm8: case tok::kw_half: case tok::kw_float: case tok::kw_double: @@ -5835,6 +5840,7 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw_int: case tok::kw__ExtInt: case tok::kw__BitInt: + case tok::kw___fpm8: case tok::kw_half: case tok::kw___bf16: case tok::kw_float: @@ -6057,6 +6063,7 @@ bool Parser::isDeclarationSpecifier( case tok::kw_int: case tok::kw__ExtInt: case tok::kw__BitInt: + case tok::kw___fpm8: case tok::kw_half: case tok::kw___bf16: case tok::kw_float: diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index eb7447fa038e4..9103275aa9772 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1594,6 +1594,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, case tok::kw__BitInt: case tok::kw_signed: case tok::kw_unsigned: + case tok::kw___fpm8: case tok::kw_half: case tok::kw_float: case tok::kw_double: diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 1d364f77a8146..72c4782cb53b3 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2405,6 +2405,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { case tok::kw___int128: DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw___fpm8: + DS.SetTypeSpecType(DeclSpec::TST_Fpm8, Loc, PrevSpec, DiagID, Policy); + break; case tok::kw___bf16: DS.SetTypeSpecType(DeclSpec::TST_BFloat16, Loc, PrevSpec, DiagID, Policy); break; diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index ea17c3e3252ec..695bbbba9433d 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1779,6 +1779,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, case tok::kw_short: case tok::kw_int: case tok::kw_long: + case tok::kw___fpm8: case tok::kw___int64: case tok::kw___int128: case tok::kw_signed: @@ -1907,6 +1908,7 @@ bool Parser::isCXXDeclarationSpecifierAType() { case tok::kw_long: case tok::kw___int64: case tok::kw___int128: + case tok::kw___fpm8: case tok::kw_signed: case tok::kw_unsigned: case tok::kw_half: diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 60e8189025700..168b98e90e6ec 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -358,6 +358,7 @@ bool Declarator::isDeclarationOfFunction() const { case TST_Fract: case TST_Float16: case TST_float128: + case TST_Fpm8: case TST_ibm128: case TST_enum: case TST_error: @@ -575,6 +576,8 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, case DeclSpec::TST_fract: return "_Fract"; case DeclSpec::TST_float16: return "_Float16"; case DeclSpec::TST_float128: return "__float128"; + case DeclSpec::TST_Fpm8: + return "fpm8_t"; case DeclSpec::TST_ibm128: return "__ibm128"; case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool"; case DeclSpec::TST_decimal32: return "_Decimal32"; diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 7a44b978aacdb..d7c4c04c130ef 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -908,6 +908,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { case TST_char32: case TST_int: case TST_int128: + case TST_Fpm8: case TST_half: case TST_float: case TST_double: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 441fdcca0758f..89c523990ce52 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1134,6 +1134,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__bf16"; Result = Context.BFloat16Ty; break; + case DeclSpec::TST_Fpm8: + Result = Context.Fpm8Ty; + break; case DeclSpec::TST_float: Result = Context.FloatTy; break; case DeclSpec::TST_double: if (DS.getTypeSpecWidth() == TypeSpecifierWidth::Long) diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index bc662a87a7bf3..a01d57cc1fcab 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -35,6 +35,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::Char_U: ID = PREDEF_TYPE_CHAR_U_ID; break; + case BuiltinType::Fpm8: + ID = PREDEF_TYPE_FPM8_ID; + break; case BuiltinType::UChar: ID = PREDEF_TYPE_UCHAR_ID; break; diff --git a/clang/test/AST/fpm8_opaque.cpp b/clang/test/AST/fpm8_opaque.cpp new file mode 100644 index 0000000000000..3aeb3159ddc6a --- /dev/null +++ b/clang/test/AST/fpm8_opaque.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace + +/* Various contexts where type __fpm8 can appear. */ + +/* Namespace */ +namespace { + __fpm8 f2n; + __fpm8 arr1n[10]; +} + +//CHECK: |-NamespaceDecl {{.*}} +//CHECK-NEXT: | |-VarDecl {{.*}} f2n '__fpm8' +//CHECK-NEXT: | `-VarDecl {{.*}} arr1n '__fpm8[10]' + + __fpm8 arr1[10]; + //__fpm8 arr2n[] { 1, 3, 3 }; cannot initialize + + const __fpm8 func1n(const __fpm8 fpm8) { + // this should fail + __fpm8 f1n; + f1n = fpm8; + return f1n; + } + +//CHECK: |-VarDecl {{.*}} '__fpm8[10]' + +//CHECK: | `-VarDecl {{.*}} f1n '__fpm8' +//CHECK-NEXT: |-BinaryOperator {{.*}} '__fpm8' lvalue '=' +//CHECK-NEXT: | |-DeclRefExpr {{.*}} '__fpm8' lvalue Var {{.*}} 'f1n' '__fpm8' +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue> +//CHECK-NEXT: | `-DeclRefExpr {{.*}} 'const __fpm8' lvalue ParmVar {{.*}} 'fpm8' 'const __fpm8' +//CHECK-NEXT: `-ReturnStmt {{.*}} +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue> +//CHECK-NEXT: `-DeclRefExpr {{.*}} '__fpm8' lvalue Var {{.*}} 'f1n' '__fpm8' + + +/* Class */ + +class C1 { + __fpm8 f1c; + static const __fpm8 f2c; + volatile __fpm8 f3c; +public: + C1(__fpm8 arg) : f1c(arg), f3c(arg) { } + __fpm8 func1c(__fpm8 arg ) { + return arg; + } + static __fpm8 func2c(__fpm8 arg) { + return arg; + } +}; + +//CHECK: | |-CXXRecordDecl {{.*}} referenced class C1 +//CHECK-NEXT: | |-FieldDecl {{.*}} f1c '__fpm8' +//CHECK-NEXT: | |-VarDecl {{.*}} f2c 'const __fpm8' static +//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile __fpm8' +//CHECK-NEXT: | |-AccessSpecDecl {{.*}} +//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} C1 'void (__fpm8)' implicit-inline +//CHECK-NEXT: | | |-ParmVarDecl {{.*}} arg '__fpm8' +//CHECK-NEXT: | | |-CXXCtorInitializer {{.*}} 'f1c' '__fpm8' +//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue> +//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8' +//CHECK-NEXT: | | |-CXXCtorInitializer {{.*}} 'f3c' 'volatile __fpm8' +//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue> +//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8' +//CHECK-NEXT: | | `-CompoundStmt {{.*}} +//CHECK-NEXT: | |-CXXMethodDecl {{.*}} func1c '__fpm8 (__fpm8)' implicit-inline +//CHECK-NEXT: | | |-ParmVarDecl {{.*}} arg '__fpm8' +//CHECK-NEXT: | | `-CompoundStmt {{.*}} +//CHECK-NEXT: | | `-ReturnStmt {{.*}} +//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue> +//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}}8 'arg' '__fpm8' +//CHECK-NEXT: | `-CXXMethodDecl {{.*}} func2c '__fpm8 (__fpm8)' static implicit-inline +//CHECK-NEXT: | |-ParmVarDecl {{.*}} arg '__fpm8' +//CHECK-NEXT: | `-CompoundStmt {{.*}} +//CHECK-NEXT: | `-ReturnStmt {{.*}} +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue> +//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8' + +template <class C> struct S1 { + C mem1; +}; + +template <> struct S1<__fpm8> { + __fpm8 mem2; +}; + +//CHECK: |-TemplateArgument type '__fpm8' +//CHECK-NEXT: | `-BuiltinType {{.*}} '__fpm8' +//CHECK-NEXT: |-CXXRecordDecl {{.*}} implicit struct S1 +//CHECK-NEXT: `-FieldDecl {{.*}} mem2 '__fpm8' diff --git a/clang/test/CodeGen/fpm8_opaque.c b/clang/test/CodeGen/fpm8_opaque.c new file mode 100644 index 0000000000000..19b5128b8eff9 --- /dev/null +++ b/clang/test/CodeGen/fpm8_opaque.c @@ -0,0 +1,24 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// CHECK-LABEL: define dso_local i8 @func1n( +// CHECK-SAME: i8 noundef [[FPM8:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[FPM8_ADDR:%.*]] = alloca i8, align 1 +// CHECK-NEXT: [[F1N:%.*]] = alloca [10 x i8], align 1 +// CHECK-NEXT: store i8 [[FPM8]], ptr [[FPM8_ADDR]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[FPM8_ADDR]], align 1 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2 +// CHECK-NEXT: store i8 [[TMP0]], ptr [[ARRAYIDX]], align 1 +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2 +// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 +// CHECK-NEXT: ret i8 [[TMP1]] +// +__fpm8 func1n(__fpm8 fpm8) { + __fpm8 f1n[10]; + f1n[2] = fpm8; + return f1n[2]; +} + + + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits