diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c4f0fc55b4a38..f10af8f5bd6b2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12626,6 +12626,9 @@ def err_hlsl_pointers_unsupported : Error< "%select{pointers|references}0 are unsupported in HLSL">; def err_hlsl_missing_resource_class : Error<"HLSL resource needs to have [[hlsl::resource_class()]] attribute">; def err_hlsl_attribute_needs_intangible_type: Error<"attribute %0 can be used only on HLSL intangible type %1">; +def err_hlsl_incorrect_num_initializers: Error< + "too %select{few|many}0 initializers in list for type %1 " + "(expected %2 but found %3)">; def err_hlsl_operator_unsupported : Error< "the '%select{&|*|->}0' operator is unsupported in HLSL">; diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index c9266ea50e4bf..4f4bbe95476ee 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -26,6 +26,8 @@ namespace clang { class AttributeCommonInfo; class IdentifierInfo; +class InitializedEntity; +class InitializationKind; class ParsedAttr; class Scope; class VarDecl; @@ -149,6 +151,9 @@ class SemaHLSL : public SemaBase { QualType getInoutParameterType(QualType Ty); + bool TransformInitList(const InitializedEntity &Entity, + const InitializationKind &Kind, InitListExpr *Init); + private: // HLSL resource type attributes need to be processed all at once. // This is a list to collect them. diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index e394e0515e599..1aa48f0026335 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1462,6 +1462,18 @@ void CXXRecordDecl::addedMember(Decl *D) { if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal) data().HasInheritedAssignment = true; } + + // HLSL: All user-defined data types are aggregates and use aggregate + // initialization, meanwhile most, but not all built-in types behave like + // aggregates. Resource types, and some other HLSL types that wrap handles + // don't behave like aggregates. We can identify these as different because we + // implicitly define "special" member functions, which aren't spellable in + // HLSL. This all _needs_ to change in the future. There are two + // relevant HLSL feature proposals that will depend on this changing: + // * 0005-strict-initializer-lists.md + // * https://github.com/microsoft/hlsl-specs/pull/325 + if (getLangOpts().HLSL) + data().Aggregate = data().UserDeclaredSpecialMembers == 0; } bool CXXRecordDecl::isLiteral() const { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 0b0ffd2db853f..191912ca7d800 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5551,6 +5551,12 @@ CodeGenFunction::getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e) { return EmitAnyExpr(e->getSourceExpr()); } +bool CodeGenFunction::isOpaqueValueEmitted(const OpaqueValueExpr *E) { + if (OpaqueValueMapping::shouldBindAsLValue(E)) + return OpaqueLValues.contains(E); + return OpaqueRValues.contains(E); +} + RValue CodeGenFunction::EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc) { diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index d25d0f2c2133c..625ca363d9019 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "CGCXXABI.h" +#include "CGHLSLRuntime.h" #include "CGObjCRuntime.h" #include "CGRecordLayout.h" #include "CodeGenFunction.h" @@ -1776,6 +1777,18 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( } #endif + // HLSL initialization lists in the AST are an expansion which can contain + // side-effecting expressions wrapped in opaque value expressions. To properly + // emit these we need to emit the opaque values before we emit the argument + // expressions themselves. This is a little hacky, but it prevents us needing + // to do a bigger AST-level change for a language feature that we need + // deprecate in the near future. See related HLSL language proposals: + // * 0005-strict-initializer-lists.md + // * https://github.com/microsoft/hlsl-specs/pull/325 + if (CGF.getLangOpts().HLSL && isa(ExprToVisit)) + CGF.CGM.getHLSLRuntime().emitInitListOpaqueValues( + CGF, cast(ExprToVisit)); + AggValueSlot Dest = EnsureSlot(ExprToVisit->getType()); LValue DestLV = CGF.MakeAddrLValue(Dest.getAddress(), ExprToVisit->getType()); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 03ddc87d8d3df..856d8b1b2948d 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -14,9 +14,11 @@ #include "CGHLSLRuntime.h" #include "CGDebugInfo.h" +#include "CodeGenFunction.h" #include "CodeGenModule.h" #include "TargetInfo.h" #include "clang/AST/Decl.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/TargetOptions.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/LLVMContext.h" @@ -617,3 +619,33 @@ llvm::Instruction *CGHLSLRuntime::getConvergenceToken(BasicBlock &BB) { llvm_unreachable("Convergence token should have been emitted."); return nullptr; } + +class OpaqueValueVisitor : public RecursiveASTVisitor { +public: + llvm::SmallPtrSet OVEs; + OpaqueValueVisitor() {} + + bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { + OVEs.insert(E); + return true; + } +}; + +void CGHLSLRuntime::emitInitListOpaqueValues(CodeGenFunction &CGF, + InitListExpr *E) { + + typedef CodeGenFunction::OpaqueValueMappingData OpaqueValueMappingData; + OpaqueValueVisitor Visitor; + Visitor.TraverseStmt(E); + for (auto *OVE : Visitor.OVEs) { + if (CGF.isOpaqueValueEmitted(OVE)) + continue; + if (OpaqueValueMappingData::shouldBindAsLValue(OVE)) { + LValue LV = CGF.EmitLValue(OVE->getSourceExpr()); + OpaqueValueMappingData::bind(CGF, OVE, LV); + } else { + RValue RV = CGF.EmitAnyExpr(OVE->getSourceExpr()); + OpaqueValueMappingData::bind(CGF, OVE, RV); + } + } +} diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 032b2dee82f21..8767a2ddceb96 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -55,6 +55,7 @@ class StructType; namespace clang { class VarDecl; class ParmVarDecl; +class InitListExpr; class HLSLBufferDecl; class HLSLResourceBindingAttr; class Type; @@ -65,6 +66,7 @@ class FunctionDecl; namespace CodeGen { class CodeGenModule; +class CodeGenFunction; class CGHLSLRuntime { public: @@ -161,6 +163,8 @@ class CGHLSLRuntime { llvm::Instruction *getConvergenceToken(llvm::BasicBlock &BB); + void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E); + private: void addBufferResourceAnnotation(llvm::GlobalVariable *GV, llvm::hlsl::ResourceClass RC, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 64cd8a3ac55e2..8c5362bcc33c4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3011,6 +3011,10 @@ class CodeGenFunction : public CodeGenTypeCache { /// otherwise create one. RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e); + /// isOpaqueValueEmitted - Return true if the opaque value expression has + /// already been emitted. + bool isOpaqueValueEmitted(const OpaqueValueExpr *E); + /// Get the index of the current ArrayInitLoopExpr, if any. llvm::Value *getArrayInitIndex() { return ArrayInitIndex; } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 66c233de4ef30..aae61f612a4bc 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -11679,8 +11679,12 @@ static void AnalyzeImplicitConversions( // Propagate whether we are in a C++ list initialization expression. // If so, we do not issue warnings for implicit int-float conversion // precision loss, because C++11 narrowing already handles it. - bool IsListInit = Item.IsListInit || - (isa(OrigE) && S.getLangOpts().CPlusPlus); + // + // HLSL's initialization lists are special, so they shouldn't observe the C++ + // behavior here. + bool IsListInit = + Item.IsListInit || (isa(OrigE) && + S.getLangOpts().CPlusPlus && !S.getLangOpts().HLSL); if (E->isTypeDependent() || E->isValueDependent()) return; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 9a60054a6169e..be45761552290 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2589,17 +2589,20 @@ static void BuildFlattenedTypeList(QualType BaseTy, continue; } if (const auto *RT = dyn_cast(T)) { - const RecordDecl *RD = RT->getDecl(); - if (RD->isUnion()) { + const CXXRecordDecl *RD = RT->getAsCXXRecordDecl(); + assert(RD && "HLSL record types should all be CXXRecordDecls!"); + + if (RD->isStandardLayout()) + RD = RD->getStandardLayoutBaseWithFields(); + + // For types that we shouldn't decompose (unions and non-aggregates), just + // add the type itself to the list. + if (RD->isUnion() || !RD->isAggregate()) { List.push_back(T); continue; } - const CXXRecordDecl *CXXD = dyn_cast(RD); llvm::SmallVector FieldTypes; - if (CXXD && CXXD->isStandardLayout()) - RD = CXXD->getStandardLayoutBaseWithFields(); - for (const auto *FD : RD->fields()) FieldTypes.push_back(FD->getType()); // Reverse the newly added sub-range. @@ -2608,9 +2611,9 @@ static void BuildFlattenedTypeList(QualType BaseTy, // If this wasn't a standard layout type we may also have some base // classes to deal with. - if (CXXD && !CXXD->isStandardLayout()) { + if (!RD->isStandardLayout()) { FieldTypes.clear(); - for (const auto &Base : CXXD->bases()) + for (const auto &Base : RD->bases()) FieldTypes.push_back(Base.getType()); std::reverse(FieldTypes.begin(), FieldTypes.end()); WorkList.insert(WorkList.end(), FieldTypes.begin(), FieldTypes.end()); @@ -3056,3 +3059,193 @@ void SemaHLSL::processExplicitBindingsOnDecl(VarDecl *VD) { } } } + +static bool CastInitializer(Sema &S, ASTContext &Ctx, Expr *E, + llvm::SmallVectorImpl &List, + llvm::SmallVectorImpl &DestTypes) { + if (List.size() >= DestTypes.size()) { + List.push_back(E); + // This is odd, but it isn't technically a failure due to conversion, we + // handle mismatched counts of arguments differently. + return true; + } + InitializedEntity Entity = InitializedEntity::InitializeParameter( + Ctx, DestTypes[List.size()], false); + ExprResult Res = S.PerformCopyInitialization(Entity, E->getBeginLoc(), E); + if (Res.isInvalid()) + return false; + Expr *Init = Res.get(); + List.push_back(Init); + return true; +} + +static bool BuildInitializerList(Sema &S, ASTContext &Ctx, Expr *E, + llvm::SmallVectorImpl &List, + llvm::SmallVectorImpl &DestTypes) { + // If this is an initialization list, traverse the sub initializers. + if (auto *Init = dyn_cast(E)) { + for (auto *SubInit : Init->inits()) + if (!BuildInitializerList(S, Ctx, SubInit, List, DestTypes)) + return false; + return true; + } + + // If this is a scalar type, just enqueue the expression. + QualType Ty = E->getType(); + + if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType())) + return CastInitializer(S, Ctx, E, List, DestTypes); + + if (auto *VecTy = Ty->getAs()) { + uint64_t Size = VecTy->getNumElements(); + + QualType SizeTy = Ctx.getSizeType(); + uint64_t SizeTySize = Ctx.getTypeSize(SizeTy); + for (uint64_t I = 0; I < Size; ++I) { + auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I), + SizeTy, SourceLocation()); + + ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr( + E, E->getBeginLoc(), Idx, E->getEndLoc()); + if (ElExpr.isInvalid()) + return false; + if (!CastInitializer(S, Ctx, ElExpr.get(), List, DestTypes)) + return false; + } + return true; + } + + if (auto *ArrTy = dyn_cast(Ty.getTypePtr())) { + uint64_t Size = ArrTy->getZExtSize(); + QualType SizeTy = Ctx.getSizeType(); + uint64_t SizeTySize = Ctx.getTypeSize(SizeTy); + for (uint64_t I = 0; I < Size; ++I) { + auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I), + SizeTy, SourceLocation()); + ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr( + E, E->getBeginLoc(), Idx, E->getEndLoc()); + if (ElExpr.isInvalid()) + return false; + if (!BuildInitializerList(S, Ctx, ElExpr.get(), List, DestTypes)) + return false; + } + return true; + } + + if (auto *RTy = Ty->getAs()) { + llvm::SmallVector RecordTypes; + RecordTypes.push_back(RTy); + while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) { + CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl(); + assert(D->getNumBases() == 1 && + "HLSL doesn't support multiple inheritance"); + RecordTypes.push_back(D->bases_begin()->getType()->getAs()); + } + while (!RecordTypes.empty()) { + const RecordType *RT = RecordTypes.back(); + RecordTypes.pop_back(); + for (auto *FD : RT->getDecl()->fields()) { + DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess()); + DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc()); + ExprResult Res = S.BuildFieldReferenceExpr( + E, false, E->getBeginLoc(), CXXScopeSpec(), FD, Found, NameInfo); + if (Res.isInvalid()) + return false; + if (!BuildInitializerList(S, Ctx, Res.get(), List, DestTypes)) + return false; + } + } + } + return true; +} + +static Expr *GenerateInitLists(ASTContext &Ctx, QualType Ty, + llvm::SmallVectorImpl::iterator &It) { + if (Ty->isScalarType() || (Ty->isRecordType() && !Ty->isAggregateType())) { + return *(It++); + } + llvm::SmallVector Inits; + assert(!isa(Ty) && "Matrix types not yet supported in HLSL"); + Ty = Ty.getDesugaredType(Ctx); + if (Ty->isVectorType() || Ty->isConstantArrayType()) { + QualType ElTy; + uint64_t Size = 0; + if (auto *ATy = Ty->getAs()) { + ElTy = ATy->getElementType(); + Size = ATy->getNumElements(); + } else { + auto *VTy = cast(Ty.getTypePtr()); + ElTy = VTy->getElementType(); + Size = VTy->getZExtSize(); + } + for (uint64_t I = 0; I < Size; ++I) + Inits.push_back(GenerateInitLists(Ctx, ElTy, It)); + } + if (auto *RTy = Ty->getAs()) { + llvm::SmallVector RecordTypes; + RecordTypes.push_back(RTy); + while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) { + CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl(); + assert(D->getNumBases() == 1 && + "HLSL doesn't support multiple inheritance"); + RecordTypes.push_back(D->bases_begin()->getType()->getAs()); + } + while (!RecordTypes.empty()) { + const RecordType *RT = RecordTypes.back(); + RecordTypes.pop_back(); + for (auto *FD : RT->getDecl()->fields()) { + Inits.push_back(GenerateInitLists(Ctx, FD->getType(), It)); + } + } + } + auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(), + Inits, Inits.back()->getEndLoc()); + NewInit->setType(Ty); + return NewInit; +} + +bool SemaHLSL::TransformInitList(const InitializedEntity &Entity, + const InitializationKind &Kind, + InitListExpr *Init) { + // If the initializer is a scalar, just return it. + if (Init->getType()->isScalarType()) + return true; + ASTContext &Ctx = SemaRef.getASTContext(); + llvm::SmallVector DestTypes; + // An initializer list might be attempting to initialize a reference or + // rvalue-reference. When checking the initializer we should look through the + // reference. + QualType InitTy = Entity.getType().getNonReferenceType(); + BuildFlattenedTypeList(InitTy, DestTypes); + + llvm::SmallVector ArgExprs; + for (unsigned I = 0; I < Init->getNumInits(); ++I) { + Expr *E = Init->getInit(I); + if (E->HasSideEffects(Ctx)) { + QualType Ty = E->getType(); + if (auto *RTy = Ty->getAs()) + E = new (Ctx) MaterializeTemporaryExpr(Ty, E, E->isLValue()); + E = new (Ctx) OpaqueValueExpr(E->getBeginLoc(), Ty, E->getValueKind(), + E->getObjectKind(), E); + Init->setInit(I, E); + } + if (!BuildInitializerList(SemaRef, Ctx, E, ArgExprs, DestTypes)) + return false; + } + + if (DestTypes.size() != ArgExprs.size()) { + int TooManyOrFew = ArgExprs.size() > DestTypes.size() ? 1 : 0; + SemaRef.Diag(Init->getBeginLoc(), diag::err_hlsl_incorrect_num_initializers) + << TooManyOrFew << InitTy << DestTypes.size() << ArgExprs.size(); + return false; + } + + auto It = ArgExprs.begin(); + // GenerateInitLists will always return an InitListExpr here, because the + // scalar case is handled above. + auto *NewInit = cast(GenerateInitLists(Ctx, InitTy, It)); + Init->resizeInits(Ctx, NewInit->getNumInits()); + for (unsigned I = 0; I < NewInit->getNumInits(); ++I) + Init->updateInit(Ctx, I, NewInit->getInit(I)); + return true; +} diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 18090eb1c9e9a..6a76e6d74a4b0 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Ownership.h" +#include "clang/Sema/SemaHLSL.h" #include "clang/Sema/SemaObjC.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/FoldingSet.h" @@ -4787,6 +4788,10 @@ static void TryListInitialization(Sema &S, bool TreatUnavailableAsInvalid) { QualType DestType = Entity.getType(); + if (S.getLangOpts().HLSL && + !S.HLSL().TransformInitList(Entity, Kind, InitList)) + return; + // C++ doesn't allow scalar initialization with more than one argument. // But C99 complex numbers are scalars and it makes sense there. if (S.getLangOpts().CPlusPlus && DestType->isScalarType() && diff --git a/clang/test/CodeGenHLSL/ArrayTemporary.hlsl b/clang/test/CodeGenHLSL/ArrayTemporary.hlsl index e5db7eac37a42..91a283554459d 100644 --- a/clang/test/CodeGenHLSL/ArrayTemporary.hlsl +++ b/clang/test/CodeGenHLSL/ArrayTemporary.hlsl @@ -1,3 +1,4 @@ + // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s void fn(float x[2]) { } @@ -27,7 +28,7 @@ void fn2(Obj O[4]) { } // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 32, i1 false) // CHECK: call void {{.*}}fn2{{.*}}(ptr noundef byval([4 x %struct.Obj]) align 4 [[Tmp]]) void call2() { - Obj Arr[4] = {}; + Obj Arr[4] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}}; fn2(Arr); } diff --git a/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl new file mode 100644 index 0000000000000..a0590162c7087 --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl @@ -0,0 +1,963 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s + +struct TwoFloats { + float X, Y; +}; + +struct TwoInts { + int Z, W; +}; + +struct Doggo { + int4 LegState; + int TailState; + float HairCount; + float4 EarDirection[2]; +}; + +struct AnimalBits { + int Legs[4]; + uint State; + int64_t Counter; + float4 LeftDir; + float4 RightDir; +}; + +struct Kitteh { + int4 Legs; + int TailState; + float HairCount; + float4 Claws[2]; +}; + +struct Zoo { + Doggo Dogs[2]; + Kitteh Cats[4]; +}; + +struct FourFloats : TwoFloats { + float Z, W; +}; + +struct SlicyBits { + int Z : 8; + int W : 8; +}; + +// Case 1: Extraneous braces get ignored in literal instantiation. +// CHECK-LABEL: define void @_Z5case1v( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_RESULT]], ptr align 4 @__const._Z5case1v.TF1, i32 8, i1 false) +// CHECK-NEXT: ret void +// +TwoFloats case1() { + TwoFloats TF1 = {{{1.0, 2}}}; + return TF1; +} + +// Case 2: Valid C/C++ initializer is handled appropriately. +// CHECK-LABEL: define void @_Z5case2v( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_RESULT]], ptr align 4 @__const._Z5case2v.TF2, i32 8, i1 false) +// CHECK-NEXT: ret void +// +TwoFloats case2() { + TwoFloats TF2 = {1, 2}; + return TF2; +} + +// Case 3: Simple initialization with conversion of an argument. +// CHECK-LABEL: define void @_Z5case3i( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], i32 noundef [[VAL:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP0]] to float +// CHECK-NEXT: store float [[CONV]], ptr [[X]], align 4 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: store float 2.000000e+00, ptr [[Y]], align 4 +// CHECK-NEXT: ret void +// +TwoFloats case3(int Val) { + TwoFloats TF3 = {Val, 2}; + return TF3; +} + +// Case 4: Initialization from a scalarized vector into a structure with element +// conversions. +// CHECK-LABEL: define void @_Z5case4Dv2_i( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], <2 x i32> noundef [[TWOVALS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TWOVALS_ADDR:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: store <2 x i32> [[TWOVALS]], ptr [[TWOVALS_ADDR]], align 8 +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[TWOVALS_ADDR]], align 8 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <2 x i32> [[TMP0]], i64 0 +// CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[VECEXT]] to float +// CHECK-NEXT: store float [[CONV]], ptr [[X]], align 4 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[TWOVALS_ADDR]], align 8 +// CHECK-NEXT: [[VECEXT1:%.*]] = extractelement <2 x i32> [[TMP1]], i64 1 +// CHECK-NEXT: [[CONV2:%.*]] = sitofp i32 [[VECEXT1]] to float +// CHECK-NEXT: store float [[CONV2]], ptr [[Y]], align 4 +// CHECK-NEXT: ret void +// +TwoFloats case4(int2 TwoVals) { + TwoFloats TF4 = {TwoVals}; + return TF4; +} + +// Case 5: Initialization from a scalarized vector of matching type. +// CHECK-LABEL: define void @_Z5case5Dv2_i( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOINTS:%.*]]) align 4 [[AGG_RESULT:%.*]], <2 x i32> noundef [[TWOVALS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TWOVALS_ADDR:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: store <2 x i32> [[TWOVALS]], ptr [[TWOVALS_ADDR]], align 8 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[TWOVALS_ADDR]], align 8 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <2 x i32> [[TMP0]], i64 0 +// CHECK-NEXT: store i32 [[VECEXT]], ptr [[Z]], align 4 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[TWOVALS_ADDR]], align 8 +// CHECK-NEXT: [[VECEXT1:%.*]] = extractelement <2 x i32> [[TMP1]], i64 1 +// CHECK-NEXT: store i32 [[VECEXT1]], ptr [[W]], align 4 +// CHECK-NEXT: ret void +// +TwoInts case5(int2 TwoVals) { + TwoInts TI1 = {TwoVals}; + return TI1; +} + +// Case 6: Initialization from a scalarized structure of different type with +// different element types. +// CHECK-LABEL: define void @_Z5case69TwoFloats( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOINTS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS:%.*]]) align 4 [[TF4:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF4]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[X]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32 +// CHECK-NEXT: store i32 [[CONV]], ptr [[Z]], align 4 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF4]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[Y]], align 4 +// CHECK-NEXT: [[CONV1:%.*]] = fptosi float [[TMP1]] to i32 +// CHECK-NEXT: store i32 [[CONV1]], ptr [[W]], align 4 +// CHECK-NEXT: ret void +// +TwoInts case6(TwoFloats TF4) { + TwoInts TI2 = {TF4}; + return TI2; +} + +// Case 7: Initialization of a complex structure, with bogus braces and element +// conversions from a collection of scalar values, and structures. +// CHECK-LABEL: define void @_Z5case77TwoIntsS_i9TwoFloatsS0_S0_S0_( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_DOGGO:%.*]]) align 16 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOINTS:%.*]]) align 4 [[TI1:%.*]], ptr noundef byval([[STRUCT_TWOINTS]]) align 4 [[TI2:%.*]], i32 noundef [[VAL:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS:%.*]]) align 4 [[TF1:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 4 [[TF2:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 4 [[TF3:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 4 [[TF4:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: [[LEGSTATE:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Z]], align 4 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x i32> poison, i32 [[TMP0]], i32 0 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[W]], align 4 +// CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x i32> [[VECINIT]], i32 [[TMP1]], i32 1 +// CHECK-NEXT: [[Z2:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI2]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[Z2]], align 4 +// CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x i32> [[VECINIT1]], i32 [[TMP2]], i32 2 +// CHECK-NEXT: [[W4:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI2]], i32 0, i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[W4]], align 4 +// CHECK-NEXT: [[VECINIT5:%.*]] = insertelement <4 x i32> [[VECINIT3]], i32 [[TMP3]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT5]], ptr [[LEGSTATE]], align 16 +// CHECK-NEXT: [[TAILSTATE:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP4]], ptr [[TAILSTATE]], align 16 +// CHECK-NEXT: [[HAIRCOUNT:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[AGG_RESULT]], i32 0, i32 2 +// CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[VAL_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP5]] to float +// CHECK-NEXT: store float [[CONV]], ptr [[HAIRCOUNT]], align 4 +// CHECK-NEXT: [[EARDIRECTION:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[AGG_RESULT]], i32 0, i32 3 +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP6:%.*]] = load float, ptr [[X]], align 4 +// CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <4 x float> poison, float [[TMP6]], i32 0 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP7:%.*]] = load float, ptr [[Y]], align 4 +// CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <4 x float> [[VECINIT6]], float [[TMP7]], i32 1 +// CHECK-NEXT: [[X8:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF2]], i32 0, i32 0 +// CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[X8]], align 4 +// CHECK-NEXT: [[VECINIT9:%.*]] = insertelement <4 x float> [[VECINIT7]], float [[TMP8]], i32 2 +// CHECK-NEXT: [[Y10:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF2]], i32 0, i32 1 +// CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[Y10]], align 4 +// CHECK-NEXT: [[VECINIT11:%.*]] = insertelement <4 x float> [[VECINIT9]], float [[TMP9]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT11]], ptr [[EARDIRECTION]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds <4 x float>, ptr [[EARDIRECTION]], i32 1 +// CHECK-NEXT: [[X12:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF3]], i32 0, i32 0 +// CHECK-NEXT: [[TMP10:%.*]] = load float, ptr [[X12]], align 4 +// CHECK-NEXT: [[VECINIT13:%.*]] = insertelement <4 x float> poison, float [[TMP10]], i32 0 +// CHECK-NEXT: [[Y14:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF3]], i32 0, i32 1 +// CHECK-NEXT: [[TMP11:%.*]] = load float, ptr [[Y14]], align 4 +// CHECK-NEXT: [[VECINIT15:%.*]] = insertelement <4 x float> [[VECINIT13]], float [[TMP11]], i32 1 +// CHECK-NEXT: [[X16:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF4]], i32 0, i32 0 +// CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[X16]], align 4 +// CHECK-NEXT: [[VECINIT17:%.*]] = insertelement <4 x float> [[VECINIT15]], float [[TMP12]], i32 2 +// CHECK-NEXT: [[Y18:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF4]], i32 0, i32 1 +// CHECK-NEXT: [[TMP13:%.*]] = load float, ptr [[Y18]], align 4 +// CHECK-NEXT: [[VECINIT19:%.*]] = insertelement <4 x float> [[VECINIT17]], float [[TMP13]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT19]], ptr [[ARRAYINIT_ELEMENT]], align 16 +// CHECK-NEXT: ret void +// +Doggo case7(TwoInts TI1, TwoInts TI2, int Val, TwoFloats TF1, TwoFloats TF2, + TwoFloats TF3, TwoFloats TF4) { + Doggo D1 = {TI1, TI2, {Val, Val}, {{TF1, TF2}, {TF3, TF4}}}; + return D1; +} + +// Case 8: Initialization of a structure from a different structure with +// significantly different element types and grouping. +// CHECK-LABEL: define void @_Z5case85Doggo( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_ANIMALBITS:%.*]]) align 16 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_DOGGO:%.*]]) align 16 [[D1:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[LEGS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[LEGSTATE:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[LEGSTATE]], align 16 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <4 x i32> [[TMP0]], i64 0 +// CHECK-NEXT: store i32 [[VECEXT]], ptr [[LEGS]], align 4 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[LEGS]], i32 1 +// CHECK-NEXT: [[LEGSTATE1:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[LEGSTATE1]], align 16 +// CHECK-NEXT: [[VECEXT2:%.*]] = extractelement <4 x i32> [[TMP1]], i64 1 +// CHECK-NEXT: store i32 [[VECEXT2]], ptr [[ARRAYINIT_ELEMENT]], align 4 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT3:%.*]] = getelementptr inbounds i32, ptr [[LEGS]], i32 2 +// CHECK-NEXT: [[LEGSTATE4:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[LEGSTATE4]], align 16 +// CHECK-NEXT: [[VECEXT5:%.*]] = extractelement <4 x i32> [[TMP2]], i64 2 +// CHECK-NEXT: store i32 [[VECEXT5]], ptr [[ARRAYINIT_ELEMENT3]], align 4 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT6:%.*]] = getelementptr inbounds i32, ptr [[LEGS]], i32 3 +// CHECK-NEXT: [[LEGSTATE7:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, ptr [[LEGSTATE7]], align 16 +// CHECK-NEXT: [[VECEXT8:%.*]] = extractelement <4 x i32> [[TMP3]], i64 3 +// CHECK-NEXT: store i32 [[VECEXT8]], ptr [[ARRAYINIT_ELEMENT6]], align 4 +// CHECK-NEXT: [[STATE:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[TAILSTATE:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TAILSTATE]], align 16 +// CHECK-NEXT: store i32 [[TMP4]], ptr [[STATE]], align 16 +// CHECK-NEXT: [[COUNTER:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[AGG_RESULT]], i32 0, i32 2 +// CHECK-NEXT: [[HAIRCOUNT:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[HAIRCOUNT]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP5]] to i64 +// CHECK-NEXT: store i64 [[CONV]], ptr [[COUNTER]], align 8 +// CHECK-NEXT: [[LEFTDIR:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[AGG_RESULT]], i32 0, i32 3 +// CHECK-NEXT: [[EARDIRECTION:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION]], i32 0, i32 0 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x float>, ptr [[ARRAYIDX]], align 16 +// CHECK-NEXT: [[VECEXT9:%.*]] = extractelement <4 x float> [[TMP6]], i64 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x float> poison, float [[VECEXT9]], i32 0 +// CHECK-NEXT: [[EARDIRECTION10:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION10]], i32 0, i32 0 +// CHECK-NEXT: [[TMP7:%.*]] = load <4 x float>, ptr [[ARRAYIDX11]], align 16 +// CHECK-NEXT: [[VECEXT12:%.*]] = extractelement <4 x float> [[TMP7]], i64 1 +// CHECK-NEXT: [[VECINIT13:%.*]] = insertelement <4 x float> [[VECINIT]], float [[VECEXT12]], i32 1 +// CHECK-NEXT: [[EARDIRECTION14:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION14]], i32 0, i32 0 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>, ptr [[ARRAYIDX15]], align 16 +// CHECK-NEXT: [[VECEXT16:%.*]] = extractelement <4 x float> [[TMP8]], i64 2 +// CHECK-NEXT: [[VECINIT17:%.*]] = insertelement <4 x float> [[VECINIT13]], float [[VECEXT16]], i32 2 +// CHECK-NEXT: [[EARDIRECTION18:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION18]], i32 0, i32 0 +// CHECK-NEXT: [[TMP9:%.*]] = load <4 x float>, ptr [[ARRAYIDX19]], align 16 +// CHECK-NEXT: [[VECEXT20:%.*]] = extractelement <4 x float> [[TMP9]], i64 3 +// CHECK-NEXT: [[VECINIT21:%.*]] = insertelement <4 x float> [[VECINIT17]], float [[VECEXT20]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT21]], ptr [[LEFTDIR]], align 16 +// CHECK-NEXT: [[RIGHTDIR:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[AGG_RESULT]], i32 0, i32 4 +// CHECK-NEXT: [[EARDIRECTION22:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION22]], i32 0, i32 1 +// CHECK-NEXT: [[TMP10:%.*]] = load <4 x float>, ptr [[ARRAYIDX23]], align 16 +// CHECK-NEXT: [[VECEXT24:%.*]] = extractelement <4 x float> [[TMP10]], i64 0 +// CHECK-NEXT: [[VECINIT25:%.*]] = insertelement <4 x float> poison, float [[VECEXT24]], i32 0 +// CHECK-NEXT: [[EARDIRECTION26:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX27:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION26]], i32 0, i32 1 +// CHECK-NEXT: [[TMP11:%.*]] = load <4 x float>, ptr [[ARRAYIDX27]], align 16 +// CHECK-NEXT: [[VECEXT28:%.*]] = extractelement <4 x float> [[TMP11]], i64 1 +// CHECK-NEXT: [[VECINIT29:%.*]] = insertelement <4 x float> [[VECINIT25]], float [[VECEXT28]], i32 1 +// CHECK-NEXT: [[EARDIRECTION30:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX31:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION30]], i32 0, i32 1 +// CHECK-NEXT: [[TMP12:%.*]] = load <4 x float>, ptr [[ARRAYIDX31]], align 16 +// CHECK-NEXT: [[VECEXT32:%.*]] = extractelement <4 x float> [[TMP12]], i64 2 +// CHECK-NEXT: [[VECINIT33:%.*]] = insertelement <4 x float> [[VECINIT29]], float [[VECEXT32]], i32 2 +// CHECK-NEXT: [[EARDIRECTION34:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION34]], i32 0, i32 1 +// CHECK-NEXT: [[TMP13:%.*]] = load <4 x float>, ptr [[ARRAYIDX35]], align 16 +// CHECK-NEXT: [[VECEXT36:%.*]] = extractelement <4 x float> [[TMP13]], i64 3 +// CHECK-NEXT: [[VECINIT37:%.*]] = insertelement <4 x float> [[VECINIT33]], float [[VECEXT36]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT37]], ptr [[RIGHTDIR]], align 16 +// CHECK-NEXT: ret void +// +AnimalBits case8(Doggo D1) { + AnimalBits A1 = {D1}; + return A1; +} + +// Case 9: Everything everywhere all at once... Initializing mismatched +// structures from different layouts, different component groupings, with no +// top-level bracing separation. +// CHECK-LABEL: define void @_Z5case95Doggo10AnimalBits( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_ZOO:%.*]]) align 16 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_DOGGO:%.*]]) align 16 [[D1:%.*]], ptr noundef byval([[STRUCT_ANIMALBITS:%.*]]) align 16 [[A1:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[DOGS:%.*]] = getelementptr inbounds nuw [[STRUCT_ZOO]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[LEGSTATE:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[DOGS]], i32 0, i32 0 +// CHECK-NEXT: [[LEGSTATE1:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[LEGSTATE1]], align 16 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <4 x i32> [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x i32> poison, i32 [[VECEXT]], i32 0 +// CHECK-NEXT: [[LEGSTATE2:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[LEGSTATE2]], align 16 +// CHECK-NEXT: [[VECEXT3:%.*]] = extractelement <4 x i32> [[TMP1]], i64 1 +// CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <4 x i32> [[VECINIT]], i32 [[VECEXT3]], i32 1 +// CHECK-NEXT: [[LEGSTATE5:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[LEGSTATE5]], align 16 +// CHECK-NEXT: [[VECEXT6:%.*]] = extractelement <4 x i32> [[TMP2]], i64 2 +// CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <4 x i32> [[VECINIT4]], i32 [[VECEXT6]], i32 2 +// CHECK-NEXT: [[LEGSTATE8:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, ptr [[LEGSTATE8]], align 16 +// CHECK-NEXT: [[VECEXT9:%.*]] = extractelement <4 x i32> [[TMP3]], i64 3 +// CHECK-NEXT: [[VECINIT10:%.*]] = insertelement <4 x i32> [[VECINIT7]], i32 [[VECEXT9]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT10]], ptr [[LEGSTATE]], align 16 +// CHECK-NEXT: [[TAILSTATE:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[DOGS]], i32 0, i32 1 +// CHECK-NEXT: [[TAILSTATE11:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TAILSTATE11]], align 16 +// CHECK-NEXT: store i32 [[TMP4]], ptr [[TAILSTATE]], align 16 +// CHECK-NEXT: [[HAIRCOUNT:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[DOGS]], i32 0, i32 2 +// CHECK-NEXT: [[HAIRCOUNT12:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[HAIRCOUNT12]], align 4 +// CHECK-NEXT: store float [[TMP5]], ptr [[HAIRCOUNT]], align 4 +// CHECK-NEXT: [[EARDIRECTION:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[DOGS]], i32 0, i32 3 +// CHECK-NEXT: [[EARDIRECTION13:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION13]], i32 0, i32 0 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x float>, ptr [[ARRAYIDX]], align 16 +// CHECK-NEXT: [[VECEXT14:%.*]] = extractelement <4 x float> [[TMP6]], i64 0 +// CHECK-NEXT: [[VECINIT15:%.*]] = insertelement <4 x float> poison, float [[VECEXT14]], i32 0 +// CHECK-NEXT: [[EARDIRECTION16:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION16]], i32 0, i32 0 +// CHECK-NEXT: [[TMP7:%.*]] = load <4 x float>, ptr [[ARRAYIDX17]], align 16 +// CHECK-NEXT: [[VECEXT18:%.*]] = extractelement <4 x float> [[TMP7]], i64 1 +// CHECK-NEXT: [[VECINIT19:%.*]] = insertelement <4 x float> [[VECINIT15]], float [[VECEXT18]], i32 1 +// CHECK-NEXT: [[EARDIRECTION20:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION20]], i32 0, i32 0 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>, ptr [[ARRAYIDX21]], align 16 +// CHECK-NEXT: [[VECEXT22:%.*]] = extractelement <4 x float> [[TMP8]], i64 2 +// CHECK-NEXT: [[VECINIT23:%.*]] = insertelement <4 x float> [[VECINIT19]], float [[VECEXT22]], i32 2 +// CHECK-NEXT: [[EARDIRECTION24:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION24]], i32 0, i32 0 +// CHECK-NEXT: [[TMP9:%.*]] = load <4 x float>, ptr [[ARRAYIDX25]], align 16 +// CHECK-NEXT: [[VECEXT26:%.*]] = extractelement <4 x float> [[TMP9]], i64 3 +// CHECK-NEXT: [[VECINIT27:%.*]] = insertelement <4 x float> [[VECINIT23]], float [[VECEXT26]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT27]], ptr [[EARDIRECTION]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds <4 x float>, ptr [[EARDIRECTION]], i32 1 +// CHECK-NEXT: [[EARDIRECTION28:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX29:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION28]], i32 0, i32 1 +// CHECK-NEXT: [[TMP10:%.*]] = load <4 x float>, ptr [[ARRAYIDX29]], align 16 +// CHECK-NEXT: [[VECEXT30:%.*]] = extractelement <4 x float> [[TMP10]], i64 0 +// CHECK-NEXT: [[VECINIT31:%.*]] = insertelement <4 x float> poison, float [[VECEXT30]], i32 0 +// CHECK-NEXT: [[EARDIRECTION32:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION32]], i32 0, i32 1 +// CHECK-NEXT: [[TMP11:%.*]] = load <4 x float>, ptr [[ARRAYIDX33]], align 16 +// CHECK-NEXT: [[VECEXT34:%.*]] = extractelement <4 x float> [[TMP11]], i64 1 +// CHECK-NEXT: [[VECINIT35:%.*]] = insertelement <4 x float> [[VECINIT31]], float [[VECEXT34]], i32 1 +// CHECK-NEXT: [[EARDIRECTION36:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX37:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION36]], i32 0, i32 1 +// CHECK-NEXT: [[TMP12:%.*]] = load <4 x float>, ptr [[ARRAYIDX37]], align 16 +// CHECK-NEXT: [[VECEXT38:%.*]] = extractelement <4 x float> [[TMP12]], i64 2 +// CHECK-NEXT: [[VECINIT39:%.*]] = insertelement <4 x float> [[VECINIT35]], float [[VECEXT38]], i32 2 +// CHECK-NEXT: [[EARDIRECTION40:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX41:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION40]], i32 0, i32 1 +// CHECK-NEXT: [[TMP13:%.*]] = load <4 x float>, ptr [[ARRAYIDX41]], align 16 +// CHECK-NEXT: [[VECEXT42:%.*]] = extractelement <4 x float> [[TMP13]], i64 3 +// CHECK-NEXT: [[VECINIT43:%.*]] = insertelement <4 x float> [[VECINIT39]], float [[VECEXT42]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT43]], ptr [[ARRAYINIT_ELEMENT]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT44:%.*]] = getelementptr inbounds [[STRUCT_DOGGO]], ptr [[DOGS]], i32 1 +// CHECK-NEXT: [[LEGSTATE45:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[ARRAYINIT_ELEMENT44]], i32 0, i32 0 +// CHECK-NEXT: [[LEGS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX46:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX46]], align 16 +// CHECK-NEXT: [[VECINIT47:%.*]] = insertelement <4 x i32> poison, i32 [[TMP14]], i32 0 +// CHECK-NEXT: [[LEGS48:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX49:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS48]], i32 0, i32 1 +// CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX49]], align 4 +// CHECK-NEXT: [[VECINIT50:%.*]] = insertelement <4 x i32> [[VECINIT47]], i32 [[TMP15]], i32 1 +// CHECK-NEXT: [[LEGS51:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX52:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS51]], i32 0, i32 2 +// CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARRAYIDX52]], align 8 +// CHECK-NEXT: [[VECINIT53:%.*]] = insertelement <4 x i32> [[VECINIT50]], i32 [[TMP16]], i32 2 +// CHECK-NEXT: [[LEGS54:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX55:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS54]], i32 0, i32 3 +// CHECK-NEXT: [[TMP17:%.*]] = load i32, ptr [[ARRAYIDX55]], align 4 +// CHECK-NEXT: [[VECINIT56:%.*]] = insertelement <4 x i32> [[VECINIT53]], i32 [[TMP17]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT56]], ptr [[LEGSTATE45]], align 16 +// CHECK-NEXT: [[TAILSTATE57:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[ARRAYINIT_ELEMENT44]], i32 0, i32 1 +// CHECK-NEXT: [[STATE:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[STATE]], align 16 +// CHECK-NEXT: store i32 [[TMP18]], ptr [[TAILSTATE57]], align 16 +// CHECK-NEXT: [[HAIRCOUNT58:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[ARRAYINIT_ELEMENT44]], i32 0, i32 2 +// CHECK-NEXT: [[COUNTER:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP19:%.*]] = load i64, ptr [[COUNTER]], align 8 +// CHECK-NEXT: [[CONV:%.*]] = sitofp i64 [[TMP19]] to float +// CHECK-NEXT: store float [[CONV]], ptr [[HAIRCOUNT58]], align 4 +// CHECK-NEXT: [[EARDIRECTION59:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[ARRAYINIT_ELEMENT44]], i32 0, i32 3 +// CHECK-NEXT: [[LEFTDIR:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP20:%.*]] = load <4 x float>, ptr [[LEFTDIR]], align 16 +// CHECK-NEXT: [[VECEXT60:%.*]] = extractelement <4 x float> [[TMP20]], i64 0 +// CHECK-NEXT: [[VECINIT61:%.*]] = insertelement <4 x float> poison, float [[VECEXT60]], i32 0 +// CHECK-NEXT: [[LEFTDIR62:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP21:%.*]] = load <4 x float>, ptr [[LEFTDIR62]], align 16 +// CHECK-NEXT: [[VECEXT63:%.*]] = extractelement <4 x float> [[TMP21]], i64 1 +// CHECK-NEXT: [[VECINIT64:%.*]] = insertelement <4 x float> [[VECINIT61]], float [[VECEXT63]], i32 1 +// CHECK-NEXT: [[LEFTDIR65:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP22:%.*]] = load <4 x float>, ptr [[LEFTDIR65]], align 16 +// CHECK-NEXT: [[VECEXT66:%.*]] = extractelement <4 x float> [[TMP22]], i64 2 +// CHECK-NEXT: [[VECINIT67:%.*]] = insertelement <4 x float> [[VECINIT64]], float [[VECEXT66]], i32 2 +// CHECK-NEXT: [[LEFTDIR68:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP23:%.*]] = load <4 x float>, ptr [[LEFTDIR68]], align 16 +// CHECK-NEXT: [[VECEXT69:%.*]] = extractelement <4 x float> [[TMP23]], i64 3 +// CHECK-NEXT: [[VECINIT70:%.*]] = insertelement <4 x float> [[VECINIT67]], float [[VECEXT69]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT70]], ptr [[EARDIRECTION59]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT71:%.*]] = getelementptr inbounds <4 x float>, ptr [[EARDIRECTION59]], i32 1 +// CHECK-NEXT: [[RIGHTDIR:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP24:%.*]] = load <4 x float>, ptr [[RIGHTDIR]], align 16 +// CHECK-NEXT: [[VECEXT72:%.*]] = extractelement <4 x float> [[TMP24]], i64 0 +// CHECK-NEXT: [[VECINIT73:%.*]] = insertelement <4 x float> poison, float [[VECEXT72]], i32 0 +// CHECK-NEXT: [[RIGHTDIR74:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP25:%.*]] = load <4 x float>, ptr [[RIGHTDIR74]], align 16 +// CHECK-NEXT: [[VECEXT75:%.*]] = extractelement <4 x float> [[TMP25]], i64 1 +// CHECK-NEXT: [[VECINIT76:%.*]] = insertelement <4 x float> [[VECINIT73]], float [[VECEXT75]], i32 1 +// CHECK-NEXT: [[RIGHTDIR77:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP26:%.*]] = load <4 x float>, ptr [[RIGHTDIR77]], align 16 +// CHECK-NEXT: [[VECEXT78:%.*]] = extractelement <4 x float> [[TMP26]], i64 2 +// CHECK-NEXT: [[VECINIT79:%.*]] = insertelement <4 x float> [[VECINIT76]], float [[VECEXT78]], i32 2 +// CHECK-NEXT: [[RIGHTDIR80:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP27:%.*]] = load <4 x float>, ptr [[RIGHTDIR80]], align 16 +// CHECK-NEXT: [[VECEXT81:%.*]] = extractelement <4 x float> [[TMP27]], i64 3 +// CHECK-NEXT: [[VECINIT82:%.*]] = insertelement <4 x float> [[VECINIT79]], float [[VECEXT81]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT82]], ptr [[ARRAYINIT_ELEMENT71]], align 16 +// CHECK-NEXT: [[CATS:%.*]] = getelementptr inbounds nuw [[STRUCT_ZOO]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[LEGS83:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH:%.*]], ptr [[CATS]], i32 0, i32 0 +// CHECK-NEXT: [[LEGSTATE84:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP28:%.*]] = load <4 x i32>, ptr [[LEGSTATE84]], align 16 +// CHECK-NEXT: [[VECEXT85:%.*]] = extractelement <4 x i32> [[TMP28]], i64 0 +// CHECK-NEXT: [[VECINIT86:%.*]] = insertelement <4 x i32> poison, i32 [[VECEXT85]], i32 0 +// CHECK-NEXT: [[LEGSTATE87:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP29:%.*]] = load <4 x i32>, ptr [[LEGSTATE87]], align 16 +// CHECK-NEXT: [[VECEXT88:%.*]] = extractelement <4 x i32> [[TMP29]], i64 1 +// CHECK-NEXT: [[VECINIT89:%.*]] = insertelement <4 x i32> [[VECINIT86]], i32 [[VECEXT88]], i32 1 +// CHECK-NEXT: [[LEGSTATE90:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr [[LEGSTATE90]], align 16 +// CHECK-NEXT: [[VECEXT91:%.*]] = extractelement <4 x i32> [[TMP30]], i64 2 +// CHECK-NEXT: [[VECINIT92:%.*]] = insertelement <4 x i32> [[VECINIT89]], i32 [[VECEXT91]], i32 2 +// CHECK-NEXT: [[LEGSTATE93:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP31:%.*]] = load <4 x i32>, ptr [[LEGSTATE93]], align 16 +// CHECK-NEXT: [[VECEXT94:%.*]] = extractelement <4 x i32> [[TMP31]], i64 3 +// CHECK-NEXT: [[VECINIT95:%.*]] = insertelement <4 x i32> [[VECINIT92]], i32 [[VECEXT94]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT95]], ptr [[LEGS83]], align 16 +// CHECK-NEXT: [[TAILSTATE96:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[CATS]], i32 0, i32 1 +// CHECK-NEXT: [[TAILSTATE97:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP32:%.*]] = load i32, ptr [[TAILSTATE97]], align 16 +// CHECK-NEXT: store i32 [[TMP32]], ptr [[TAILSTATE96]], align 16 +// CHECK-NEXT: [[HAIRCOUNT98:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[CATS]], i32 0, i32 2 +// CHECK-NEXT: [[HAIRCOUNT99:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP33:%.*]] = load float, ptr [[HAIRCOUNT99]], align 4 +// CHECK-NEXT: store float [[TMP33]], ptr [[HAIRCOUNT98]], align 4 +// CHECK-NEXT: [[CLAWS:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[CATS]], i32 0, i32 3 +// CHECK-NEXT: [[EARDIRECTION100:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX101:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION100]], i32 0, i32 0 +// CHECK-NEXT: [[TMP34:%.*]] = load <4 x float>, ptr [[ARRAYIDX101]], align 16 +// CHECK-NEXT: [[VECEXT102:%.*]] = extractelement <4 x float> [[TMP34]], i64 0 +// CHECK-NEXT: [[VECINIT103:%.*]] = insertelement <4 x float> poison, float [[VECEXT102]], i32 0 +// CHECK-NEXT: [[EARDIRECTION104:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX105:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION104]], i32 0, i32 0 +// CHECK-NEXT: [[TMP35:%.*]] = load <4 x float>, ptr [[ARRAYIDX105]], align 16 +// CHECK-NEXT: [[VECEXT106:%.*]] = extractelement <4 x float> [[TMP35]], i64 1 +// CHECK-NEXT: [[VECINIT107:%.*]] = insertelement <4 x float> [[VECINIT103]], float [[VECEXT106]], i32 1 +// CHECK-NEXT: [[EARDIRECTION108:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX109:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION108]], i32 0, i32 0 +// CHECK-NEXT: [[TMP36:%.*]] = load <4 x float>, ptr [[ARRAYIDX109]], align 16 +// CHECK-NEXT: [[VECEXT110:%.*]] = extractelement <4 x float> [[TMP36]], i64 2 +// CHECK-NEXT: [[VECINIT111:%.*]] = insertelement <4 x float> [[VECINIT107]], float [[VECEXT110]], i32 2 +// CHECK-NEXT: [[EARDIRECTION112:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX113:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION112]], i32 0, i32 0 +// CHECK-NEXT: [[TMP37:%.*]] = load <4 x float>, ptr [[ARRAYIDX113]], align 16 +// CHECK-NEXT: [[VECEXT114:%.*]] = extractelement <4 x float> [[TMP37]], i64 3 +// CHECK-NEXT: [[VECINIT115:%.*]] = insertelement <4 x float> [[VECINIT111]], float [[VECEXT114]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT115]], ptr [[CLAWS]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT116:%.*]] = getelementptr inbounds <4 x float>, ptr [[CLAWS]], i32 1 +// CHECK-NEXT: [[EARDIRECTION117:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX118:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION117]], i32 0, i32 1 +// CHECK-NEXT: [[TMP38:%.*]] = load <4 x float>, ptr [[ARRAYIDX118]], align 16 +// CHECK-NEXT: [[VECEXT119:%.*]] = extractelement <4 x float> [[TMP38]], i64 0 +// CHECK-NEXT: [[VECINIT120:%.*]] = insertelement <4 x float> poison, float [[VECEXT119]], i32 0 +// CHECK-NEXT: [[EARDIRECTION121:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX122:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION121]], i32 0, i32 1 +// CHECK-NEXT: [[TMP39:%.*]] = load <4 x float>, ptr [[ARRAYIDX122]], align 16 +// CHECK-NEXT: [[VECEXT123:%.*]] = extractelement <4 x float> [[TMP39]], i64 1 +// CHECK-NEXT: [[VECINIT124:%.*]] = insertelement <4 x float> [[VECINIT120]], float [[VECEXT123]], i32 1 +// CHECK-NEXT: [[EARDIRECTION125:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX126:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION125]], i32 0, i32 1 +// CHECK-NEXT: [[TMP40:%.*]] = load <4 x float>, ptr [[ARRAYIDX126]], align 16 +// CHECK-NEXT: [[VECEXT127:%.*]] = extractelement <4 x float> [[TMP40]], i64 2 +// CHECK-NEXT: [[VECINIT128:%.*]] = insertelement <4 x float> [[VECINIT124]], float [[VECEXT127]], i32 2 +// CHECK-NEXT: [[EARDIRECTION129:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX130:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION129]], i32 0, i32 1 +// CHECK-NEXT: [[TMP41:%.*]] = load <4 x float>, ptr [[ARRAYIDX130]], align 16 +// CHECK-NEXT: [[VECEXT131:%.*]] = extractelement <4 x float> [[TMP41]], i64 3 +// CHECK-NEXT: [[VECINIT132:%.*]] = insertelement <4 x float> [[VECINIT128]], float [[VECEXT131]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT132]], ptr [[ARRAYINIT_ELEMENT116]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT133:%.*]] = getelementptr inbounds [[STRUCT_KITTEH]], ptr [[CATS]], i32 1 +// CHECK-NEXT: [[LEGS134:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT133]], i32 0, i32 0 +// CHECK-NEXT: [[LEGS135:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX136:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS135]], i32 0, i32 0 +// CHECK-NEXT: [[TMP42:%.*]] = load i32, ptr [[ARRAYIDX136]], align 16 +// CHECK-NEXT: [[VECINIT137:%.*]] = insertelement <4 x i32> poison, i32 [[TMP42]], i32 0 +// CHECK-NEXT: [[LEGS138:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX139:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS138]], i32 0, i32 1 +// CHECK-NEXT: [[TMP43:%.*]] = load i32, ptr [[ARRAYIDX139]], align 4 +// CHECK-NEXT: [[VECINIT140:%.*]] = insertelement <4 x i32> [[VECINIT137]], i32 [[TMP43]], i32 1 +// CHECK-NEXT: [[LEGS141:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX142:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS141]], i32 0, i32 2 +// CHECK-NEXT: [[TMP44:%.*]] = load i32, ptr [[ARRAYIDX142]], align 8 +// CHECK-NEXT: [[VECINIT143:%.*]] = insertelement <4 x i32> [[VECINIT140]], i32 [[TMP44]], i32 2 +// CHECK-NEXT: [[LEGS144:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX145:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS144]], i32 0, i32 3 +// CHECK-NEXT: [[TMP45:%.*]] = load i32, ptr [[ARRAYIDX145]], align 4 +// CHECK-NEXT: [[VECINIT146:%.*]] = insertelement <4 x i32> [[VECINIT143]], i32 [[TMP45]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT146]], ptr [[LEGS134]], align 16 +// CHECK-NEXT: [[TAILSTATE147:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT133]], i32 0, i32 1 +// CHECK-NEXT: [[STATE148:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP46:%.*]] = load i32, ptr [[STATE148]], align 16 +// CHECK-NEXT: store i32 [[TMP46]], ptr [[TAILSTATE147]], align 16 +// CHECK-NEXT: [[HAIRCOUNT149:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT133]], i32 0, i32 2 +// CHECK-NEXT: [[COUNTER150:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP47:%.*]] = load i64, ptr [[COUNTER150]], align 8 +// CHECK-NEXT: [[CONV151:%.*]] = sitofp i64 [[TMP47]] to float +// CHECK-NEXT: store float [[CONV151]], ptr [[HAIRCOUNT149]], align 4 +// CHECK-NEXT: [[CLAWS152:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT133]], i32 0, i32 3 +// CHECK-NEXT: [[LEFTDIR153:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP48:%.*]] = load <4 x float>, ptr [[LEFTDIR153]], align 16 +// CHECK-NEXT: [[VECEXT154:%.*]] = extractelement <4 x float> [[TMP48]], i64 0 +// CHECK-NEXT: [[VECINIT155:%.*]] = insertelement <4 x float> poison, float [[VECEXT154]], i32 0 +// CHECK-NEXT: [[LEFTDIR156:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP49:%.*]] = load <4 x float>, ptr [[LEFTDIR156]], align 16 +// CHECK-NEXT: [[VECEXT157:%.*]] = extractelement <4 x float> [[TMP49]], i64 1 +// CHECK-NEXT: [[VECINIT158:%.*]] = insertelement <4 x float> [[VECINIT155]], float [[VECEXT157]], i32 1 +// CHECK-NEXT: [[LEFTDIR159:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP50:%.*]] = load <4 x float>, ptr [[LEFTDIR159]], align 16 +// CHECK-NEXT: [[VECEXT160:%.*]] = extractelement <4 x float> [[TMP50]], i64 2 +// CHECK-NEXT: [[VECINIT161:%.*]] = insertelement <4 x float> [[VECINIT158]], float [[VECEXT160]], i32 2 +// CHECK-NEXT: [[LEFTDIR162:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP51:%.*]] = load <4 x float>, ptr [[LEFTDIR162]], align 16 +// CHECK-NEXT: [[VECEXT163:%.*]] = extractelement <4 x float> [[TMP51]], i64 3 +// CHECK-NEXT: [[VECINIT164:%.*]] = insertelement <4 x float> [[VECINIT161]], float [[VECEXT163]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT164]], ptr [[CLAWS152]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT165:%.*]] = getelementptr inbounds <4 x float>, ptr [[CLAWS152]], i32 1 +// CHECK-NEXT: [[RIGHTDIR166:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP52:%.*]] = load <4 x float>, ptr [[RIGHTDIR166]], align 16 +// CHECK-NEXT: [[VECEXT167:%.*]] = extractelement <4 x float> [[TMP52]], i64 0 +// CHECK-NEXT: [[VECINIT168:%.*]] = insertelement <4 x float> poison, float [[VECEXT167]], i32 0 +// CHECK-NEXT: [[RIGHTDIR169:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP53:%.*]] = load <4 x float>, ptr [[RIGHTDIR169]], align 16 +// CHECK-NEXT: [[VECEXT170:%.*]] = extractelement <4 x float> [[TMP53]], i64 1 +// CHECK-NEXT: [[VECINIT171:%.*]] = insertelement <4 x float> [[VECINIT168]], float [[VECEXT170]], i32 1 +// CHECK-NEXT: [[RIGHTDIR172:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP54:%.*]] = load <4 x float>, ptr [[RIGHTDIR172]], align 16 +// CHECK-NEXT: [[VECEXT173:%.*]] = extractelement <4 x float> [[TMP54]], i64 2 +// CHECK-NEXT: [[VECINIT174:%.*]] = insertelement <4 x float> [[VECINIT171]], float [[VECEXT173]], i32 2 +// CHECK-NEXT: [[RIGHTDIR175:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP55:%.*]] = load <4 x float>, ptr [[RIGHTDIR175]], align 16 +// CHECK-NEXT: [[VECEXT176:%.*]] = extractelement <4 x float> [[TMP55]], i64 3 +// CHECK-NEXT: [[VECINIT177:%.*]] = insertelement <4 x float> [[VECINIT174]], float [[VECEXT176]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT177]], ptr [[ARRAYINIT_ELEMENT165]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT178:%.*]] = getelementptr inbounds [[STRUCT_KITTEH]], ptr [[CATS]], i32 2 +// CHECK-NEXT: [[LEGS179:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT178]], i32 0, i32 0 +// CHECK-NEXT: [[LEGSTATE180:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP56:%.*]] = load <4 x i32>, ptr [[LEGSTATE180]], align 16 +// CHECK-NEXT: [[VECEXT181:%.*]] = extractelement <4 x i32> [[TMP56]], i64 0 +// CHECK-NEXT: [[VECINIT182:%.*]] = insertelement <4 x i32> poison, i32 [[VECEXT181]], i32 0 +// CHECK-NEXT: [[LEGSTATE183:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP57:%.*]] = load <4 x i32>, ptr [[LEGSTATE183]], align 16 +// CHECK-NEXT: [[VECEXT184:%.*]] = extractelement <4 x i32> [[TMP57]], i64 1 +// CHECK-NEXT: [[VECINIT185:%.*]] = insertelement <4 x i32> [[VECINIT182]], i32 [[VECEXT184]], i32 1 +// CHECK-NEXT: [[LEGSTATE186:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP58:%.*]] = load <4 x i32>, ptr [[LEGSTATE186]], align 16 +// CHECK-NEXT: [[VECEXT187:%.*]] = extractelement <4 x i32> [[TMP58]], i64 2 +// CHECK-NEXT: [[VECINIT188:%.*]] = insertelement <4 x i32> [[VECINIT185]], i32 [[VECEXT187]], i32 2 +// CHECK-NEXT: [[LEGSTATE189:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP59:%.*]] = load <4 x i32>, ptr [[LEGSTATE189]], align 16 +// CHECK-NEXT: [[VECEXT190:%.*]] = extractelement <4 x i32> [[TMP59]], i64 3 +// CHECK-NEXT: [[VECINIT191:%.*]] = insertelement <4 x i32> [[VECINIT188]], i32 [[VECEXT190]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT191]], ptr [[LEGS179]], align 16 +// CHECK-NEXT: [[TAILSTATE192:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT178]], i32 0, i32 1 +// CHECK-NEXT: [[TAILSTATE193:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP60:%.*]] = load i32, ptr [[TAILSTATE193]], align 16 +// CHECK-NEXT: store i32 [[TMP60]], ptr [[TAILSTATE192]], align 16 +// CHECK-NEXT: [[HAIRCOUNT194:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT178]], i32 0, i32 2 +// CHECK-NEXT: [[HAIRCOUNT195:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP61:%.*]] = load float, ptr [[HAIRCOUNT195]], align 4 +// CHECK-NEXT: store float [[TMP61]], ptr [[HAIRCOUNT194]], align 4 +// CHECK-NEXT: [[CLAWS196:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT178]], i32 0, i32 3 +// CHECK-NEXT: [[EARDIRECTION197:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX198:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION197]], i32 0, i32 0 +// CHECK-NEXT: [[TMP62:%.*]] = load <4 x float>, ptr [[ARRAYIDX198]], align 16 +// CHECK-NEXT: [[VECEXT199:%.*]] = extractelement <4 x float> [[TMP62]], i64 0 +// CHECK-NEXT: [[VECINIT200:%.*]] = insertelement <4 x float> poison, float [[VECEXT199]], i32 0 +// CHECK-NEXT: [[EARDIRECTION201:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX202:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION201]], i32 0, i32 0 +// CHECK-NEXT: [[TMP63:%.*]] = load <4 x float>, ptr [[ARRAYIDX202]], align 16 +// CHECK-NEXT: [[VECEXT203:%.*]] = extractelement <4 x float> [[TMP63]], i64 1 +// CHECK-NEXT: [[VECINIT204:%.*]] = insertelement <4 x float> [[VECINIT200]], float [[VECEXT203]], i32 1 +// CHECK-NEXT: [[EARDIRECTION205:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX206:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION205]], i32 0, i32 0 +// CHECK-NEXT: [[TMP64:%.*]] = load <4 x float>, ptr [[ARRAYIDX206]], align 16 +// CHECK-NEXT: [[VECEXT207:%.*]] = extractelement <4 x float> [[TMP64]], i64 2 +// CHECK-NEXT: [[VECINIT208:%.*]] = insertelement <4 x float> [[VECINIT204]], float [[VECEXT207]], i32 2 +// CHECK-NEXT: [[EARDIRECTION209:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX210:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION209]], i32 0, i32 0 +// CHECK-NEXT: [[TMP65:%.*]] = load <4 x float>, ptr [[ARRAYIDX210]], align 16 +// CHECK-NEXT: [[VECEXT211:%.*]] = extractelement <4 x float> [[TMP65]], i64 3 +// CHECK-NEXT: [[VECINIT212:%.*]] = insertelement <4 x float> [[VECINIT208]], float [[VECEXT211]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT212]], ptr [[CLAWS196]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT213:%.*]] = getelementptr inbounds <4 x float>, ptr [[CLAWS196]], i32 1 +// CHECK-NEXT: [[EARDIRECTION214:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX215:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION214]], i32 0, i32 1 +// CHECK-NEXT: [[TMP66:%.*]] = load <4 x float>, ptr [[ARRAYIDX215]], align 16 +// CHECK-NEXT: [[VECEXT216:%.*]] = extractelement <4 x float> [[TMP66]], i64 0 +// CHECK-NEXT: [[VECINIT217:%.*]] = insertelement <4 x float> poison, float [[VECEXT216]], i32 0 +// CHECK-NEXT: [[EARDIRECTION218:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX219:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION218]], i32 0, i32 1 +// CHECK-NEXT: [[TMP67:%.*]] = load <4 x float>, ptr [[ARRAYIDX219]], align 16 +// CHECK-NEXT: [[VECEXT220:%.*]] = extractelement <4 x float> [[TMP67]], i64 1 +// CHECK-NEXT: [[VECINIT221:%.*]] = insertelement <4 x float> [[VECINIT217]], float [[VECEXT220]], i32 1 +// CHECK-NEXT: [[EARDIRECTION222:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX223:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION222]], i32 0, i32 1 +// CHECK-NEXT: [[TMP68:%.*]] = load <4 x float>, ptr [[ARRAYIDX223]], align 16 +// CHECK-NEXT: [[VECEXT224:%.*]] = extractelement <4 x float> [[TMP68]], i64 2 +// CHECK-NEXT: [[VECINIT225:%.*]] = insertelement <4 x float> [[VECINIT221]], float [[VECEXT224]], i32 2 +// CHECK-NEXT: [[EARDIRECTION226:%.*]] = getelementptr inbounds nuw [[STRUCT_DOGGO]], ptr [[D1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX227:%.*]] = getelementptr inbounds nuw [2 x <4 x float>], ptr [[EARDIRECTION226]], i32 0, i32 1 +// CHECK-NEXT: [[TMP69:%.*]] = load <4 x float>, ptr [[ARRAYIDX227]], align 16 +// CHECK-NEXT: [[VECEXT228:%.*]] = extractelement <4 x float> [[TMP69]], i64 3 +// CHECK-NEXT: [[VECINIT229:%.*]] = insertelement <4 x float> [[VECINIT225]], float [[VECEXT228]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT229]], ptr [[ARRAYINIT_ELEMENT213]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT230:%.*]] = getelementptr inbounds [[STRUCT_KITTEH]], ptr [[CATS]], i32 3 +// CHECK-NEXT: [[LEGS231:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT230]], i32 0, i32 0 +// CHECK-NEXT: [[LEGS232:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX233:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS232]], i32 0, i32 0 +// CHECK-NEXT: [[TMP70:%.*]] = load i32, ptr [[ARRAYIDX233]], align 16 +// CHECK-NEXT: [[VECINIT234:%.*]] = insertelement <4 x i32> poison, i32 [[TMP70]], i32 0 +// CHECK-NEXT: [[LEGS235:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX236:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS235]], i32 0, i32 1 +// CHECK-NEXT: [[TMP71:%.*]] = load i32, ptr [[ARRAYIDX236]], align 4 +// CHECK-NEXT: [[VECINIT237:%.*]] = insertelement <4 x i32> [[VECINIT234]], i32 [[TMP71]], i32 1 +// CHECK-NEXT: [[LEGS238:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX239:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS238]], i32 0, i32 2 +// CHECK-NEXT: [[TMP72:%.*]] = load i32, ptr [[ARRAYIDX239]], align 8 +// CHECK-NEXT: [[VECINIT240:%.*]] = insertelement <4 x i32> [[VECINIT237]], i32 [[TMP72]], i32 2 +// CHECK-NEXT: [[LEGS241:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 0 +// CHECK-NEXT: [[ARRAYIDX242:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[LEGS241]], i32 0, i32 3 +// CHECK-NEXT: [[TMP73:%.*]] = load i32, ptr [[ARRAYIDX242]], align 4 +// CHECK-NEXT: [[VECINIT243:%.*]] = insertelement <4 x i32> [[VECINIT240]], i32 [[TMP73]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT243]], ptr [[LEGS231]], align 16 +// CHECK-NEXT: [[TAILSTATE244:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT230]], i32 0, i32 1 +// CHECK-NEXT: [[STATE245:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP74:%.*]] = load i32, ptr [[STATE245]], align 16 +// CHECK-NEXT: store i32 [[TMP74]], ptr [[TAILSTATE244]], align 16 +// CHECK-NEXT: [[HAIRCOUNT246:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT230]], i32 0, i32 2 +// CHECK-NEXT: [[COUNTER247:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP75:%.*]] = load i64, ptr [[COUNTER247]], align 8 +// CHECK-NEXT: [[CONV248:%.*]] = sitofp i64 [[TMP75]] to float +// CHECK-NEXT: store float [[CONV248]], ptr [[HAIRCOUNT246]], align 4 +// CHECK-NEXT: [[CLAWS249:%.*]] = getelementptr inbounds nuw [[STRUCT_KITTEH]], ptr [[ARRAYINIT_ELEMENT230]], i32 0, i32 3 +// CHECK-NEXT: [[LEFTDIR250:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP76:%.*]] = load <4 x float>, ptr [[LEFTDIR250]], align 16 +// CHECK-NEXT: [[VECEXT251:%.*]] = extractelement <4 x float> [[TMP76]], i64 0 +// CHECK-NEXT: [[VECINIT252:%.*]] = insertelement <4 x float> poison, float [[VECEXT251]], i32 0 +// CHECK-NEXT: [[LEFTDIR253:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP77:%.*]] = load <4 x float>, ptr [[LEFTDIR253]], align 16 +// CHECK-NEXT: [[VECEXT254:%.*]] = extractelement <4 x float> [[TMP77]], i64 1 +// CHECK-NEXT: [[VECINIT255:%.*]] = insertelement <4 x float> [[VECINIT252]], float [[VECEXT254]], i32 1 +// CHECK-NEXT: [[LEFTDIR256:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP78:%.*]] = load <4 x float>, ptr [[LEFTDIR256]], align 16 +// CHECK-NEXT: [[VECEXT257:%.*]] = extractelement <4 x float> [[TMP78]], i64 2 +// CHECK-NEXT: [[VECINIT258:%.*]] = insertelement <4 x float> [[VECINIT255]], float [[VECEXT257]], i32 2 +// CHECK-NEXT: [[LEFTDIR259:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 3 +// CHECK-NEXT: [[TMP79:%.*]] = load <4 x float>, ptr [[LEFTDIR259]], align 16 +// CHECK-NEXT: [[VECEXT260:%.*]] = extractelement <4 x float> [[TMP79]], i64 3 +// CHECK-NEXT: [[VECINIT261:%.*]] = insertelement <4 x float> [[VECINIT258]], float [[VECEXT260]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT261]], ptr [[CLAWS249]], align 16 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT262:%.*]] = getelementptr inbounds <4 x float>, ptr [[CLAWS249]], i32 1 +// CHECK-NEXT: [[RIGHTDIR263:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP80:%.*]] = load <4 x float>, ptr [[RIGHTDIR263]], align 16 +// CHECK-NEXT: [[VECEXT264:%.*]] = extractelement <4 x float> [[TMP80]], i64 0 +// CHECK-NEXT: [[VECINIT265:%.*]] = insertelement <4 x float> poison, float [[VECEXT264]], i32 0 +// CHECK-NEXT: [[RIGHTDIR266:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP81:%.*]] = load <4 x float>, ptr [[RIGHTDIR266]], align 16 +// CHECK-NEXT: [[VECEXT267:%.*]] = extractelement <4 x float> [[TMP81]], i64 1 +// CHECK-NEXT: [[VECINIT268:%.*]] = insertelement <4 x float> [[VECINIT265]], float [[VECEXT267]], i32 1 +// CHECK-NEXT: [[RIGHTDIR269:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP82:%.*]] = load <4 x float>, ptr [[RIGHTDIR269]], align 16 +// CHECK-NEXT: [[VECEXT270:%.*]] = extractelement <4 x float> [[TMP82]], i64 2 +// CHECK-NEXT: [[VECINIT271:%.*]] = insertelement <4 x float> [[VECINIT268]], float [[VECEXT270]], i32 2 +// CHECK-NEXT: [[RIGHTDIR272:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[A1]], i32 0, i32 4 +// CHECK-NEXT: [[TMP83:%.*]] = load <4 x float>, ptr [[RIGHTDIR272]], align 16 +// CHECK-NEXT: [[VECEXT273:%.*]] = extractelement <4 x float> [[TMP83]], i64 3 +// CHECK-NEXT: [[VECINIT274:%.*]] = insertelement <4 x float> [[VECINIT271]], float [[VECEXT273]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT274]], ptr [[ARRAYINIT_ELEMENT262]], align 16 +// CHECK-NEXT: ret void +// +Zoo case9(Doggo D1, AnimalBits A1) { + Zoo Z1 = {D1, A1, D1, A1, D1, A1}; + return Z1; +} + +// Case 10: Initialize an object with a base class from two objects. +// CHECK-LABEL: define void @_Z6case109TwoFloatsS_( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS:%.*]]) align 4 [[TF1:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 4 [[TF2:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[X1]], align 4 +// CHECK-NEXT: store float [[TMP0]], ptr [[X]], align 4 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[Y2:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[Y2]], align 4 +// CHECK-NEXT: store float [[TMP1]], ptr [[Y]], align 4 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[X3:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF2]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[X3]], align 4 +// CHECK-NEXT: store float [[TMP2]], ptr [[Z]], align 4 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 2 +// CHECK-NEXT: [[Y4:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF2]], i32 0, i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[Y4]], align 4 +// CHECK-NEXT: store float [[TMP3]], ptr [[W]], align 4 +// CHECK-NEXT: ret void +// +FourFloats case10(TwoFloats TF1, TwoFloats TF2) { + FourFloats FF1 = {TF1, TF2}; + return FF1; +} + +// Case 11: Initialize an object with a base class from a vector splat. +// CHECK-LABEL: define void @_Z6case11f( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], float noundef nofpclass(nan inf) [[F:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[REF_TMP:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: [[REF_TMP1:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: [[REF_TMP4:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: [[REF_TMP7:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS:%.*]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CAST_SPLAT:%.*]] = insertelement <1 x float> poison, float [[TMP0]], i64 0 +// CHECK-NEXT: [[TMP1:%.*]] = shufflevector <1 x float> [[CAST_SPLAT]], <1 x float> poison, <4 x i32> zeroinitializer +// CHECK-NEXT: store <4 x float> [[TMP1]], ptr [[REF_TMP]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[REF_TMP]], align 16 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <4 x float> [[TMP2]], i64 0 +// CHECK-NEXT: store float [[VECEXT]], ptr [[X]], align 4 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CAST_SPLAT2:%.*]] = insertelement <1 x float> poison, float [[TMP3]], i64 0 +// CHECK-NEXT: [[TMP4:%.*]] = shufflevector <1 x float> [[CAST_SPLAT2]], <1 x float> poison, <4 x i32> zeroinitializer +// CHECK-NEXT: store <4 x float> [[TMP4]], ptr [[REF_TMP1]], align 16 +// CHECK-NEXT: [[TMP5:%.*]] = load <4 x float>, ptr [[REF_TMP1]], align 16 +// CHECK-NEXT: [[VECEXT3:%.*]] = extractelement <4 x float> [[TMP5]], i64 1 +// CHECK-NEXT: store float [[VECEXT3]], ptr [[Y]], align 4 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[TMP6:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CAST_SPLAT5:%.*]] = insertelement <1 x float> poison, float [[TMP6]], i64 0 +// CHECK-NEXT: [[TMP7:%.*]] = shufflevector <1 x float> [[CAST_SPLAT5]], <1 x float> poison, <4 x i32> zeroinitializer +// CHECK-NEXT: store <4 x float> [[TMP7]], ptr [[REF_TMP4]], align 16 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>, ptr [[REF_TMP4]], align 16 +// CHECK-NEXT: [[VECEXT6:%.*]] = extractelement <4 x float> [[TMP8]], i64 2 +// CHECK-NEXT: store float [[VECEXT6]], ptr [[Z]], align 4 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 2 +// CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CAST_SPLAT8:%.*]] = insertelement <1 x float> poison, float [[TMP9]], i64 0 +// CHECK-NEXT: [[TMP10:%.*]] = shufflevector <1 x float> [[CAST_SPLAT8]], <1 x float> poison, <4 x i32> zeroinitializer +// CHECK-NEXT: store <4 x float> [[TMP10]], ptr [[REF_TMP7]], align 16 +// CHECK-NEXT: [[TMP11:%.*]] = load <4 x float>, ptr [[REF_TMP7]], align 16 +// CHECK-NEXT: [[VECEXT9:%.*]] = extractelement <4 x float> [[TMP11]], i64 3 +// CHECK-NEXT: store float [[VECEXT9]], ptr [[W]], align 4 +// CHECK-NEXT: ret void +// +FourFloats case11(float F) { + FourFloats FF1 = {F.xxxx}; + return FF1; +} + +// Case 12: Initialize bitfield from two integers. +// CHECK-LABEL: define void @_Z6case12ii( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_SLICYBITS:%.*]]) align 4 [[AGG_RESULT:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[J_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4 +// CHECK-NEXT: store i32 [[J]], ptr [[J_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i16 +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255 +// CHECK-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -256 +// CHECK-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK-NEXT: store i16 [[BF_SET]], ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[J_ADDR]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i16 +// CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: [[BF_VALUE2:%.*]] = and i16 [[TMP3]], 255 +// CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_VALUE2]], 8 +// CHECK-NEXT: [[BF_CLEAR3:%.*]] = and i16 [[BF_LOAD1]], 255 +// CHECK-NEXT: [[BF_SET4:%.*]] = or i16 [[BF_CLEAR3]], [[BF_SHL]] +// CHECK-NEXT: store i16 [[BF_SET4]], ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: ret void +// +SlicyBits case12(int I, int J) { + SlicyBits SB = {I, J}; + return SB; +} + +// Case 13: Initialize bitfield from a struct of two ints. +// CHECK-LABEL: define void @_Z6case137TwoInts( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_SLICYBITS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOINTS:%.*]]) align 4 [[TI:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Z]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i16 +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255 +// CHECK-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -256 +// CHECK-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_VALUE]] +// CHECK-NEXT: store i16 [[BF_SET]], ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI]], i32 0, i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[W]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i16 +// CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: [[BF_VALUE2:%.*]] = and i16 [[TMP3]], 255 +// CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_VALUE2]], 8 +// CHECK-NEXT: [[BF_CLEAR3:%.*]] = and i16 [[BF_LOAD1]], 255 +// CHECK-NEXT: [[BF_SET4:%.*]] = or i16 [[BF_CLEAR3]], [[BF_SHL]] +// CHECK-NEXT: store i16 [[BF_SET4]], ptr [[AGG_RESULT]], align 4 +// CHECK-NEXT: ret void +// +SlicyBits case13(TwoInts TI) { + SlicyBits SB = {TI}; + return SB; +} + +// Case 14: Initialize struct of ints from struct with bitfields. +// CHECK-LABEL: define void @_Z6case149SlicyBits( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOINTS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_SLICYBITS:%.*]]) align 4 [[SB:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[SB]], align 4 +// CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 8 +// CHECK-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 +// CHECK-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 +// CHECK-NEXT: store i32 [[BF_CAST]], ptr [[Z]], align 4 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[SB]], align 4 +// CHECK-NEXT: [[BF_ASHR2:%.*]] = ashr i16 [[BF_LOAD1]], 8 +// CHECK-NEXT: [[BF_CAST3:%.*]] = sext i16 [[BF_ASHR2]] to i32 +// CHECK-NEXT: store i32 [[BF_CAST3]], ptr [[W]], align 4 +// CHECK-NEXT: ret void +// +TwoInts case14(SlicyBits SB) { + TwoInts TI = {SB}; + return TI; +} + +// Case 15: Initialize struct of floats from struct with bitfields. +// CHECK-LABEL: define void @_Z6case159SlicyBits( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_SLICYBITS:%.*]]) align 4 [[SB:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[SB]], align 4 +// CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 8 +// CHECK-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 +// CHECK-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 +// CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[BF_CAST]] to float +// CHECK-NEXT: store float [[CONV]], ptr [[X]], align 4 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[SB]], align 4 +// CHECK-NEXT: [[BF_ASHR2:%.*]] = ashr i16 [[BF_LOAD1]], 8 +// CHECK-NEXT: [[BF_CAST3:%.*]] = sext i16 [[BF_ASHR2]] to i32 +// CHECK-NEXT: [[CONV4:%.*]] = sitofp i32 [[BF_CAST3]] to float +// CHECK-NEXT: store float [[CONV4]], ptr [[Y]], align 4 +// CHECK-NEXT: ret void +// +TwoFloats case15(SlicyBits SB) { + TwoFloats TI = {SB}; + return TI; +} + +// Case 16: Side-effecting initialization list arguments. The important thing +// here is that case16 only has _one_ call to makeTwo. +// CHECK-LABEL: define void @_Z7makeTwoRf( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noalias noundef nonnull align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 4 +// CHECK-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[TMP0]], align 4 +// CHECK-NEXT: store float [[TMP1]], ptr [[X1]], align 4 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[X_ADDR]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[TMP2]], align 4 +// CHECK-NEXT: [[MUL:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP3]], 1.500000e+00 +// CHECK-NEXT: store float [[MUL]], ptr [[Y]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[X_ADDR]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-NEXT: [[MUL2:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP5]], 2.000000e+00 +// CHECK-NEXT: store float [[MUL2]], ptr [[TMP4]], align 4 +// CHECK-NEXT: ret void +// +TwoFloats makeTwo(inout float X) { + TwoFloats TF = {X, X*1.5}; + X *= 2; + return TF; +} + +// CHECK-LABEL: define void @_Z6case16v( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[X:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_TWOFLOATS:%.*]], align 4 +// CHECK-NEXT: [[TMP:%.*]] = alloca float, align 4 +// CHECK-NEXT: store float 0.000000e+00, ptr [[X]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[X]], align 4 +// CHECK-NEXT: store float [[TMP0]], ptr [[TMP]], align 4 +// CHECK-NEXT: call void @_Z7makeTwoRf(ptr dead_on_unwind writable sret([[STRUCT_TWOFLOATS]]) align 4 [[REF_TMP]], ptr noalias noundef nonnull align 4 dereferenceable(4) [[TMP]]) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[TMP]], align 4 +// CHECK-NEXT: store float [[TMP1]], ptr [[X]], align 4 +// CHECK-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-NEXT: store float 0.000000e+00, ptr [[X1]], align 4 +// CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[X2:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[REF_TMP]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[X2]], align 4 +// CHECK-NEXT: store float [[TMP2]], ptr [[Y]], align 4 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-NEXT: [[Y3:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[REF_TMP]], i32 0, i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[Y3]], align 4 +// CHECK-NEXT: store float [[TMP3]], ptr [[Z]], align 4 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 2 +// CHECK-NEXT: store float 3.000000e+00, ptr [[W]], align 4 +// CHECK-NEXT: ret void +// +FourFloats case16() { + float X = 0; + FourFloats FF = {0, makeTwo(X), 3}; + return FF; +} diff --git a/clang/test/SemaHLSL/ArrayTemporary.hlsl b/clang/test/SemaHLSL/ArrayTemporary.hlsl index 0266a198e7ec9..3d713a89adf3b 100644 --- a/clang/test/SemaHLSL/ArrayTemporary.hlsl +++ b/clang/test/SemaHLSL/ArrayTemporary.hlsl @@ -25,7 +25,7 @@ void fn2(Obj O[4]) { } // CHECK-NEXT: ImplicitCastExpr {{.*}} 'Obj[4]' void call2() { - Obj Arr[4] = {}; + Obj Arr[4] = {0, 0, 0, 0, 0, 0, 0, 0}; fn2(Arr); } diff --git a/clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl b/clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl index b7085bc69547b..9417249383469 100644 --- a/clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl +++ b/clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl @@ -43,7 +43,9 @@ export void cantCast4() { int2 A = {1,2}; R r = R(A); // expected-error@-1 {{no matching conversion for functional-style cast from 'int2' (aka 'vector') to 'R'}} - R r2 = {1, 2}; + R r2; + r2.A = 1; + r2.F = 2.0; int2 B = (int2)r2; // expected-error@-1 {{cannot convert 'R' to 'int2' (aka 'vector') without a conversion operator}} } diff --git a/clang/test/SemaHLSL/Language/InitListAST.hlsl b/clang/test/SemaHLSL/Language/InitListAST.hlsl new file mode 100644 index 0000000000000..d58582f9029fe --- /dev/null +++ b/clang/test/SemaHLSL/Language/InitListAST.hlsl @@ -0,0 +1,983 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -finclude-default-header -ast-dump -ast-dump-filter=case %s | FileCheck %s + +struct TwoFloats { + float X, Y; +}; + +struct TwoInts { + int Z, W; +}; + +struct Doggo { + int4 LegState; + int TailState; + float HairCount; + float4 EarDirection[2]; +}; + +struct AnimalBits { + int Legs[4]; + uint State; + int64_t Counter; + float4 LeftDir; + float4 RightDir; +}; + +struct Kitteh { + int4 Legs; + int TailState; + float HairCount; + float4 Claws[2]; +}; + +struct Zoo { + Doggo Dogs[2]; + Kitteh Cats[4]; +}; + +struct FourFloats : TwoFloats { + float Z, W; +}; + +struct SlicyBits { + int Z : 8; + int W : 8; +}; + +// Case 1: Extraneous braces get ignored in literal instantiation. +// CHECK-LABEL: Dumping case1 +// CHECK: VarDecl {{.*}} used TF1 'TwoFloats' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +// CHECK-NEXT: FloatingLiteral {{.*}} 'float' 1.000000e+00 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2 +TwoFloats case1() { + TwoFloats TF1 = {{{1.0, 2}}}; + return TF1; +} + +// Case 2: Valid C/C++ initializer is handled appropriately. +//CHECK-LABEL: Dumping case2 +//CHECK: VarDecl {{.*}} used TF2 'TwoFloats' nrvo cinit +//CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +//CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +//CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +//CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +//CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2 +TwoFloats case2() { + TwoFloats TF2 = {1, 2}; + return TF2; +} + +// Case 3: Simple initialization with conversion of an argument. +// CHECK-LABEL: Dumping case3 +// CHECK: VarDecl {{.*}} used TF3 'TwoFloats' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'Val' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2 +TwoFloats case3(int Val) { + TwoFloats TF3 = {Val, 2}; + return TF3; +} + +// Case 4: Initialization from a scalarized vector into a structure with element +// conversions. +// CHECK-LABEL: Dumping case4 +// CHECK: VarDecl {{.*}} used TF4 'TwoFloats' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}}'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: DeclRefExpr {{.*}} 'int2':'vector' lvalue ParmVar {{.*}} 'TwoVals' 'int2':'vector' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: DeclRefExpr {{.*}} 'int2':'vector' lvalue ParmVar {{.*}} 'TwoVals' 'int2':'vector' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +TwoFloats case4(int2 TwoVals) { + TwoFloats TF4 = {TwoVals}; + return TF4; +} + +// Case 5: Initialization from a scalarized vector of matching type. +// CHECK-LABEL: Dumping case5 +// CHECK: VarDecl {{.*}} used TI1 'TwoInts' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: DeclRefExpr {{.*}} 'int2':'vector' lvalue ParmVar {{.*}} 'TwoVals' 'int2':'vector' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: DeclRefExpr {{.*}} 'int2':'vector' lvalue ParmVar {{.*}} 'TwoVals' 'int2':'vector' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +TwoInts case5(int2 TwoVals) { + TwoInts TI1 = {TwoVals}; + return TI1; +} + +// Case 6: Initialization from a scalarized structure of different type with +// different element types. +// CHECK-LABEL: Dumping case6 +// CHECK: VarDecl {{.*}} used TI2 'TwoInts' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}}'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .X {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF4' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .Y {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF4' 'TwoFloats' +TwoInts case6(TwoFloats TF4) { + TwoInts TI2 = {TF4}; + return TI2; +} + +// Case 7: Initialization of a complex structure, with bogus braces and element +// conversions from a collection of scalar values, and structures. +// CHECK-LABEL: Dumping case7 +// CHECK: VarDecl {{.*}} used D1 'Doggo' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'Doggo' +// CHECK-NEXT: InitListExpr {{.*}} 'int4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .Z {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoInts' lvalue ParmVar {{.*}} 'TI1' 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .W {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoInts' lvalue ParmVar {{.*}} 'TI1' 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .Z {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoInts' lvalue ParmVar {{.*}} 'TI2' 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .W {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoInts' lvalue ParmVar {{.*}} 'TI2' 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'Val' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'Val' 'int' +// CHECK-NEXT: InitListExpr {{.*}} 'float4[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .X {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF1' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .Y {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF1' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .X {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF2' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .Y {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF2' 'TwoFloats' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .X {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF3' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .Y {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF3' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .X {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF4' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .Y {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF4' 'TwoFloats' +Doggo case7(TwoInts TI1, TwoInts TI2, int Val, TwoFloats TF1, TwoFloats TF2, + TwoFloats TF3, TwoFloats TF4) { + Doggo D1 = {TI1, TI2, {Val, Val}, {{TF1, TF2}, {TF3, TF4}}}; + return D1; +} + +// Case 8: Initialization of a structure from a different structure with +// significantly different element types and grouping. +// CHECK-LABEL: Dumping case8 +// CHECK: VarDecl {{.*}} used A1 'AnimalBits' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'AnimalBits' +// CHECK-NEXT: InitListExpr {{.*}} 'int[4]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .TailState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'long' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .HairCount {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +AnimalBits case8(Doggo D1) { + AnimalBits A1 = {D1}; + return A1; +} + +// Case 9: Everything everywhere all at once... Initializing mismatched +// structures from different layouts, different component groupings, with no +// top-level bracing separation. +// CHECK-LABEL: Dumping case9 +// CHECK: VarDecl {{.*}} used Z1 'Zoo' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'Zoo' +// CHECK-NEXT: InitListExpr {{.*}} 'Doggo[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'Doggo' +// CHECK-NEXT: InitListExpr {{.*}} 'int4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .TailState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .HairCount {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: InitListExpr {{.*}} 'float4[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'Doggo' +// CHECK-NEXT: InitListExpr {{.*}} 'int4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint':'unsigned int' +// CHECK-NEXT: MemberExpr {{.*}} 'uint':'unsigned int' lvalue .State {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t':'long' +// CHECK-NEXT: MemberExpr {{.*}} 'int64_t':'long' lvalue .Counter {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: InitListExpr {{.*}} 'float4[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'Kitteh[4]' +// CHECK-NEXT: InitListExpr {{.*}} 'Kitteh' +// CHECK-NEXT: InitListExpr {{.*}} 'int4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .TailState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .HairCount {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: InitListExpr {{.*}} 'float4[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'Kitteh' +// CHECK-NEXT: InitListExpr {{.*}} 'int4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint':'unsigned int' +// CHECK-NEXT: MemberExpr {{.*}} 'uint':'unsigned int' lvalue .State {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t':'long' +// CHECK-NEXT: MemberExpr {{.*}} 'int64_t':'long' lvalue .Counter {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: InitListExpr {{.*}} 'float4[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'Kitteh' +// CHECK-NEXT: InitListExpr {{.*}} 'int4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'int4':'vector' lvalue .LegState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .TailState {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .HairCount {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: InitListExpr {{.*}} 'float4[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float4':'vector' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float4 *' +// CHECK-NEXT: MemberExpr {{.*}} 'float4[2]' lvalue .EarDirection {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'Doggo' lvalue ParmVar {{.*}} 'D1' 'Doggo' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'Kitteh' +// CHECK-NEXT: InitListExpr {{.*}} 'int4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'int' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' +// CHECK-NEXT: MemberExpr {{.*}} 'int[4]' lvalue .Legs {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint':'unsigned int' +// CHECK-NEXT: MemberExpr {{.*}} 'uint':'unsigned int' lvalue .State {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t':'long' +// CHECK-NEXT: MemberExpr {{.*}} 'int64_t':'long' lvalue .Counter {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: InitListExpr {{.*}} 'float4[2]' +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .LeftDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +// CHECK-NEXT: InitListExpr {{.*}} 'float4':'vector' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' lvalue vectorcomponent +// CHECK-NEXT: MemberExpr {{.*}} 'float4':'vector' lvalue .RightDir {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'AnimalBits' lvalue ParmVar {{.*}} 'A1' 'AnimalBits' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +Zoo case9(Doggo D1, AnimalBits A1) { + Zoo Z1 = {D1, A1, D1, A1, D1, A1}; + return Z1; +} + +// Case 10: Initialize an object with a base class from two objects. +// CHECK-LABEL: Dumping case10 +// CHECK: | `-VarDecl {{.*}} used FF1 'FourFloats' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'FourFloats' +// CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .X {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF1' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .Y {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF1' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .X {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF2' 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .Y {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoFloats' lvalue ParmVar {{.*}} 'TF2' 'TwoFloats' +FourFloats case10(TwoFloats TF1, TwoFloats TF2) { + FourFloats FF1 = {TF1, TF2}; + return FF1; +} + +// Case 11: Initialize an object with a base class from a vector splat. +// CHECK-LABEL: Dumping case11 +// CHECK: VarDecl {{.*}} used FF1 'FourFloats' nrvo cinit +// CHECK-NEXT: ExprWithCleanups {{.*}} 'FourFloats' +// CHECK-NEXT: InitListExpr {{.*}} 'FourFloats' +// CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' xvalue vectorcomponent +// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'vector' xvalue +// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'vector' xxxx +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'F' 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' xvalue vectorcomponent +// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'vector' xvalue +// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'vector' xxxx +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'F' 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 1 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' xvalue vectorcomponent +// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'vector' xvalue +// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'vector' xxxx +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'F' 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ArraySubscriptExpr {{.*}} 'float' xvalue vectorcomponent +// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'vector' xvalue +// CHECK-NEXT: ExtVectorElementExpr {{.*}} 'vector' xxxx +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'vector' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'F' 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'unsigned long' 3 +FourFloats case11(float F) { + FourFloats FF1 = {F.xxxx}; + return FF1; +} + +// Case 12: Initialize bitfield from two integers. +// CHECK-LABEL: Dumping case12 +// CHECK: VarDecl {{.*}} used SB 'SlicyBits' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'SlicyBits' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'I' 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'J' 'int' +SlicyBits case12(int I, int J) { + SlicyBits SB = {I, J}; + return SB; +} + +// Case 13: Initialize bitfield from a struct of two ints. +// CHECK-LABEL: Dumping case13 +// CHECK: VarDecl {{.*}} used SB 'SlicyBits' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'SlicyBits' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .Z {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoInts' lvalue ParmVar {{.*}} 'TI' 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue .W {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'TwoInts' lvalue ParmVar {{.*}} 'TI' 'TwoInts' +SlicyBits case13(TwoInts TI) { + SlicyBits SB = {TI}; + return SB; +} + +// Case 14: Initialize struct of ints from struct with bitfields. +// CHECK-LABEL: Dumping case14 +// CHECK: VarDecl {{.*}} used TI 'TwoInts' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'TwoInts' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue bitfield .Z {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'SlicyBits' lvalue ParmVar {{.*}} 'SB' 'SlicyBits' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue bitfield .W {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'SlicyBits' lvalue ParmVar {{.*}} 'SB' 'SlicyBits' +TwoInts case14(SlicyBits SB) { + TwoInts TI = {SB}; + return TI; +} + +// Case 15: Initialize struct of floats from struct with bitfields. +// CHECK-LABEL: Dumping case15 +// CHECK: VarDecl {{.*}} used TI 'TwoFloats' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue bitfield .Z {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'SlicyBits' lvalue ParmVar {{.*}} 'SB' 'SlicyBits' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: MemberExpr {{.*}} 'int' lvalue bitfield .W {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} 'SlicyBits' lvalue ParmVar {{.*}} 'SB' 'SlicyBits' +TwoFloats case15(SlicyBits SB) { + TwoFloats TI = {SB}; + return TI; +} + +// Case 16: Side-effecting initialization list arguments. The important thing +// here is that case16 only has _one_ call to makeTwo. +TwoFloats makeTwo(inout float X) { + TwoFloats TF = {X, X*1.5}; + X *= 2; + return TF; +} + +// CHECK-LABEL: Dumping case16 +// CHECK: VarDecl {{.*}} used FF 'FourFloats' nrvo cinit +// CHECK-NEXT: InitListExpr {{.*}} 'FourFloats' +// CHECK-NEXT: InitListExpr {{.*}} 'TwoFloats' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: MemberExpr {{.*}} 'float' xvalue .X {{.*}} +// CHECK-NEXT: OpaqueValueExpr [[OVEArg:0x[0-9A-Fa-f]+]] {{.*}} 'TwoFloats' xvalue +// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'TwoFloats' xvalue +// CHECK-NEXT: CallExpr {{.*}} 'TwoFloats' + +// I don't care about the call here, just skip ahead to the next argument, and +// verify that we match the same OpaqueValueExpr. + +// CHECK: MemberExpr {{.*}} 'float' xvalue .Y {{.*}} +// CHECK-NEXT: OpaqueValueExpr [[OVEArg]] {{.*}} 'TwoFloats' xvalue +// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'TwoFloats' xvalue +// CHECK-NEXT: CallExpr {{.*}} 'TwoFloats' +FourFloats case16() { + float X = 0; + FourFloats FF = {0, makeTwo(X), 3}; + return FF; +} diff --git a/clang/test/SemaHLSL/Language/InitLists.hlsl b/clang/test/SemaHLSL/Language/InitLists.hlsl new file mode 100644 index 0000000000000..3607dfd8aedbc --- /dev/null +++ b/clang/test/SemaHLSL/Language/InitLists.hlsl @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -finclude-default-header -verify -Wdouble-promotion -Wconversion %s + +struct TwoFloats { + float X, Y; +}; + +struct TwoInts { + int Z, W; +}; + +struct Doggo { + int4 LegState; + int TailState; + float HairCount; + float4 EarDirection[2]; +}; + +struct AnimalBits { + int Legs[4]; + uint State; + int64_t Counter; + float4 LeftDir; + float4 RightDir; +}; + +struct Kitteh { + int4 Legs; + int TailState; + float HairCount; + float4 Claws[2]; +}; + +struct Zoo { + Doggo Dogs[2]; + Kitteh Cats[4]; +}; + +struct FourFloats : TwoFloats { + float Z, W; +}; + +struct SlicyBits { + int Z : 8; + int W : 8; +}; + +struct ContainsResource { // #ContainsResource + int X; + RWBuffer B; +}; + +struct ContainsResourceInverted { + RWBuffer B; + int X; +}; + +void fn() { + TwoFloats TF1 = {{{1.0, 2}}}; + TwoFloats TF2 = {1,2}; + int Val = 1; + TwoFloats TF3 = {Val, 2}; // expected-warning{{implicit conversion from 'int' to 'float' may lose precision}} + int2 TwoVals = 1.xx; + int2 Something = 1.xxx; // expected-warning{{implicit conversion truncates vector: 'vector' (vector of 3 'int' values) to 'vector' (vector of 2 'int' values)}} + TwoFloats TF4 = {TwoVals}; // expected-warning{{implicit conversion from 'int' to 'float' may lose precision}} expected-warning{{implicit conversion from 'int' to 'float' may lose precision}} + + TwoInts TI1 = {TwoVals}; + TwoInts TI2 = {TF4}; // expected-warning{{implicit conversion turns floating-point number into integer: 'float' to 'int'}} expected-warning{{implicit conversion turns floating-point number into integer: 'float' to 'int'}} + + Doggo D1 = {TI1, TI2, {Val, Val}, {{TF1, TF2}, {TF3, TF4}}}; // expected-warning{{implicit conversion from 'int' to 'float' may lose precision}} + AnimalBits A1 = {D1}; // expected-warning{{implicit conversion turns floating-point number into integer: 'float' to 'long'}} expected-warning{{implicit conversion changes signedness: 'int' to 'unsigned int'}} + + Zoo Z1 = {D1, A1, D1, A1, D1, A1}; // #insanity + + // expected-warning@#insanity{{implicit conversion from 'int64_t' (aka 'long') to 'float' may lose precision}} + // expected-warning@#insanity{{implicit conversion changes signedness: 'uint' (aka 'unsigned int') to 'int'}} + // expected-warning@#insanity{{implicit conversion from 'int64_t' (aka 'long') to 'float' may lose precision}} + // expected-warning@#insanity{{implicit conversion changes signedness: 'uint' (aka 'unsigned int') to 'int'}} + // expected-warning@#insanity{{implicit conversion from 'int64_t' (aka 'long') to 'float' may lose precision}} + // expected-warning@#insanity{{implicit conversion changes signedness: 'uint' (aka 'unsigned int') to 'int'}} +} + +void fn2() { + TwoFloats TF2 = {1,2}; + FourFloats FF1 = {TF2, TF2}; + FourFloats FF2 = {1,2,3,4}; + FourFloats FF3 = {1.xxx, 2}; + + SlicyBits SB1 = {1,2}; + TwoInts TI1 = {SB1}; + SlicyBits SB2 = {TI1}; +} + +void Errs() { + TwoFloats F1 = {}; // expected-error{{too few initializers in list for type 'TwoFloats' (expected 2 but found 0)}} + TwoFloats F2 = {1}; // expected-error{{too few initializers in list for type 'TwoFloats' (expected 2 but found 1)}} + TwoFloats F3 = {1,2,3}; // expected-error{{too many initializers in list for type 'TwoFloats' (expected 2 but found 3)}} + + int2 Something = {1.xxx}; // expected-error{{too many initializers in list for type 'int2' (aka 'vector') (expected 2 but found 3)}} +} + +struct R { + int A; + union { // #anon + float F; + int4 G; + }; +}; + +// expected-note@#anon{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to}} +// expected-note@#anon{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to}} + +void Err2(RWBuffer B) { + ContainsResource RS1 = {1, B}; + ContainsResource RS2 = (1.xx); // expected-error{{no viable conversion from 'vector' (vector of 2 'int' values) to 'ContainsResource'}} + ContainsResource RS3 = {B, 1}; // expected-error{{no viable conversion from 'RWBuffer' (aka 'RWBuffer>') to 'int'}} + ContainsResourceInverted IR = {RS1}; // expected-error{{no viable conversion from 'int' to 'hlsl::RWBuffer>'}} + + R r = {1,2}; // expected-error{{no viable conversion from 'int' to 'R::(anonymous union at}} +} + +// expected-note@#ContainsResource{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'vector' (vector of 2 'int' values) to 'const ContainsResource &' for 1st argument}} +// expected-note@#ContainsResource{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'vector' (vector of 2 'int' values) to 'ContainsResource &&' for 1st argument}} + +// These notes refer to the RWBuffer constructors that do not have source locations +// expected-note@*{{candidate constructor (the implicit copy constructor) not viable}} +// expected-note@*{{candidate constructor (the implicit move constructor) not viable}}