diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 1e3ac2e31870f..8250247a0204a 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -301,39 +301,6 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, return true; } -bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context, - const FieldDecl *FD) { - if (FD->isZeroLengthBitField()) - return true; - - if (FD->isUnnamedBitField()) - return false; - - return isEmptyRecordForLayout(Context, FD->getType()); -} - -bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) { - const auto *RD = T->getAsRecordDecl(); - if (!RD) - return false; - - // If this is a C++ record, check the bases first. - if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { - if (CXXRD->isDynamicClass()) - return false; - - for (const auto &I : CXXRD->bases()) - if (!isEmptyRecordForLayout(Context, I.getType())) - return false; - } - - for (const auto *I : RD->fields()) - if (!isEmptyFieldForLayout(Context, I)) - return false; - - return true; -} - const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) { const auto *RD = T->getAsRecordDecl(); if (!RD) diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h index d9d79c6a55ddb..f0276be8cb97f 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.h +++ b/clang/lib/CodeGen/ABIInfoImpl.h @@ -120,16 +120,6 @@ bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays, bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr = false); -/// isEmptyFieldForLayout - Return true iff the field is "empty", that is, -/// either a zero-width bit-field or an \ref isEmptyRecordForLayout. -bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD); - -/// isEmptyRecordForLayout - Return true iff a structure contains only empty -/// base classes (per \ref isEmptyRecordForLayout) and fields (per -/// \ref isEmptyFieldForLayout). Note, C++ record fields are considered empty -/// if the [[no_unique_address]] attribute would have made them empty. -bool isEmptyRecordForLayout(const ASTContext &Context, QualType T); - /// isSingleElementStruct - Determine if a structure is a "single /// element struct", i.e. it has exactly one non-empty field or /// exactly one field which is itself a single element diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 62f5d2f789326..b292efea94861 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "ABIInfoImpl.h" #include "CGBlocks.h" #include "CGCXXABI.h" #include "CGDebugInfo.h" @@ -927,7 +926,7 @@ namespace { } void addMemcpyableField(FieldDecl *F) { - if (isEmptyFieldForLayout(CGF.getContext(), F)) + if (F->isZeroSize(CGF.getContext())) return; if (!FirstField) addInitialField(F); @@ -1884,7 +1883,7 @@ namespace { const CXXDestructorDecl *DD) : Context(Context), EHStack(EHStack), DD(DD), StartIndex(std::nullopt) {} void PushCleanupForField(const FieldDecl *Field) { - if (isEmptyFieldForLayout(Context, Field)) + if (Field->isZeroSize(Context)) return; unsigned FieldIndex = Field->getFieldIndex(); if (FieldHasTrivialDestructorBody(Context, Field)) { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 05f26d0bfc9df..a0c23bc21faf7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5283,7 +5283,7 @@ static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base, /// The resulting address doesn't necessarily have the right type. static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base, const FieldDecl *field, bool IsInBounds) { - if (isEmptyFieldForLayout(CGF.getContext(), field)) + if (field->isZeroSize(CGF.getContext())) return emitAddrOfZeroSizeField(CGF, base, field, IsInBounds); const RecordDecl *rec = field->getParent(); diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 6407afc3d9447..9dc74d5b78ea9 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "ABIInfoImpl.h" #include "CGCXXABI.h" #include "CGObjCRuntime.h" #include "CGRecordLayout.h" @@ -758,7 +757,7 @@ bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) { // Zero-sized fields are not emitted, but their initializers may still // prevent emission of this struct as a constant. - if (isEmptyFieldForLayout(CGM.getContext(), Field)) { + if (Field->isZeroSize(CGM.getContext())) { if (Init && Init->HasSideEffects(CGM.getContext())) return false; continue; @@ -893,8 +892,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, continue; // Don't emit anonymous bitfields or zero-sized fields. - if (Field->isUnnamedBitField() || - isEmptyFieldForLayout(CGM.getContext(), *Field)) + if (Field->isUnnamedBitField() || Field->isZeroSize(CGM.getContext())) continue; // Emit the value of the initializer. @@ -2642,10 +2640,8 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, const auto *base = I.getType()->castAsCXXRecordDecl(); // Ignore empty bases. - if (isEmptyRecordForLayout(CGM.getContext(), I.getType()) || - CGM.getContext() - .getASTRecordLayout(base) - .getNonVirtualSize() + if (base->isEmpty() || + CGM.getContext().getASTRecordLayout(base).getNonVirtualSize() .isZero()) continue; @@ -2659,8 +2655,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, for (const auto *Field : record->fields()) { // Fill in non-bitfields. (Bitfields always use a zero pattern, which we // will fill in later.) - if (!Field->isBitField() && - !isEmptyFieldForLayout(CGM.getContext(), Field)) { + if (!Field->isBitField() && !Field->isZeroSize(CGM.getContext())) { unsigned fieldIndex = layout.getLLVMFieldNo(Field); elements[fieldIndex] = CGM.EmitNullConstant(Field->getType()); } @@ -2680,7 +2675,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, for (const auto &I : CXXR->vbases()) { const auto *base = I.getType()->castAsCXXRecordDecl(); // Ignore empty bases. - if (isEmptyRecordForLayout(CGM.getContext(), I.getType())) + if (base->isEmpty()) continue; unsigned fieldIndex = layout.getVirtualBaseIndex(base); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 5ceaaf30b8d24..75d7718562654 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "CGOpenMPRuntime.h" -#include "ABIInfoImpl.h" #include "CGCXXABI.h" #include "CGCleanup.h" #include "CGDebugInfo.h" @@ -8472,15 +8471,12 @@ class MappableExprsHandler { for (const auto &I : RD->bases()) { if (I.isVirtual()) continue; - - QualType BaseTy = I.getType(); - const auto *Base = BaseTy->getAsCXXRecordDecl(); + const auto *Base = I.getType()->getAsCXXRecordDecl(); // Ignore empty bases. - if (isEmptyRecordForLayout(CGF.getContext(), BaseTy) || - CGF.getContext() - .getASTRecordLayout(Base) - .getNonVirtualSize() - .isZero()) + if (Base->isEmpty() || CGF.getContext() + .getASTRecordLayout(Base) + .getNonVirtualSize() + .isZero()) continue; unsigned FieldIndex = RL.getNonVirtualBaseLLVMFieldNo(Base); @@ -8488,12 +8484,10 @@ class MappableExprsHandler { } // Fill in virtual bases. for (const auto &I : RD->vbases()) { - QualType BaseTy = I.getType(); + const auto *Base = I.getType()->getAsCXXRecordDecl(); // Ignore empty bases. - if (isEmptyRecordForLayout(CGF.getContext(), BaseTy)) + if (Base->isEmpty()) continue; - - const auto *Base = BaseTy->getAsCXXRecordDecl(); unsigned FieldIndex = RL.getVirtualBaseIndex(Base); if (RecordLayout[FieldIndex]) continue; @@ -8504,8 +8498,7 @@ class MappableExprsHandler { for (const auto *Field : RD->fields()) { // Fill in non-bitfields. (Bitfields always use a zero pattern, which we // will fill in later.) - if (!Field->isBitField() && - !isEmptyFieldForLayout(CGF.getContext(), Field)) { + if (!Field->isBitField() && !Field->isZeroSize(CGF.getContext())) { unsigned FieldIndex = RL.getLLVMFieldNo(Field); RecordLayout[FieldIndex] = Field; } diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index e9205c68c2812..5580cee1f49f6 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -10,9 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "ABIInfoImpl.h" -#include "CGCXXABI.h" #include "CGRecordLayout.h" +#include "CGCXXABI.h" #include "CodeGenTypes.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" @@ -385,7 +384,7 @@ void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) { Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd); assert((Field == FieldEnd || !Field->isBitField()) && "Failed to accumulate all the bitfields"); - } else if (isEmptyFieldForLayout(Context, *Field)) { + } else if (Field->isZeroSize(Context)) { // Empty fields have no storage. ++Field; } else { @@ -634,7 +633,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType, // non-reusable tail padding. CharUnits LimitOffset; for (auto Probe = Field; Probe != FieldEnd; ++Probe) - if (!isEmptyFieldForLayout(Context, *Probe)) { + if (!Probe->isZeroSize(Context)) { // A member with storage sets the limit. assert((getFieldBitOffset(*Probe) % CharBits) == 0 && "Next storage is not byte-aligned"); @@ -732,7 +731,7 @@ void CGRecordLowering::accumulateBases() { // Bases can be zero-sized even if not technically empty if they // contain only a trailing array member. const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); - if (!isEmptyRecordForLayout(Context, Base.getType()) && + if (!BaseDecl->isEmpty() && !Context.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero()) Members.push_back(MemberInfo(Layout.getBaseClassOffset(BaseDecl), MemberInfo::Base, getStorageType(BaseDecl), BaseDecl)); @@ -880,7 +879,7 @@ CGRecordLowering::calculateTailClippingOffset(bool isNonVirtualBaseType) const { if (!isNonVirtualBaseType && isOverlappingVBaseABI()) for (const auto &Base : RD->vbases()) { const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); - if (isEmptyRecordForLayout(Context, Base.getType())) + if (BaseDecl->isEmpty()) continue; // If the vbase is a primary virtual base of some base, then it doesn't // get its own storage location but instead lives inside of that base. @@ -896,7 +895,7 @@ CGRecordLowering::calculateTailClippingOffset(bool isNonVirtualBaseType) const { void CGRecordLowering::accumulateVBases() { for (const auto &Base : RD->vbases()) { const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); - if (isEmptyRecordForLayout(Context, Base.getType())) + if (BaseDecl->isEmpty()) continue; CharUnits Offset = Layout.getVBaseClassOffset(BaseDecl); // If the vbase is a primary virtual base of some base, then it doesn't @@ -1157,7 +1156,7 @@ CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty) { const FieldDecl *FD = *it; // Ignore zero-sized fields. - if (isEmptyFieldForLayout(getContext(), FD)) + if (FD->isZeroSize(getContext())) continue; // For non-bit-fields, just check that the LLVM struct offset matches the diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index cd08f3ec397a0..d9eabf2c76989 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -15,7 +15,6 @@ //===----------------------------------------------------------------------===// #include "CodeGenTBAA.h" -#include "ABIInfoImpl.h" #include "CGCXXABI.h" #include "CGRecordLayout.h" #include "CodeGenTypes.h" @@ -448,7 +447,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, unsigned idx = 0; for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i, ++idx) { - if (isEmptyFieldForLayout(Context, *i)) + if ((*i)->isZeroSize(Context)) continue; uint64_t Offset = diff --git a/clang/test/CodeGen/2009-06-14-anonymous-union-init.c b/clang/test/CodeGen/2009-06-14-anonymous-union-init.c index a4375d7868f01..3f4493deea79e 100644 --- a/clang/test/CodeGen/2009-06-14-anonymous-union-init.c +++ b/clang/test/CodeGen/2009-06-14-anonymous-union-init.c @@ -1,19 +1,8 @@ -// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefixes=CHECK,EMPTY -// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s --check-prefixes=CHECK,EMPTY-MSVC +// RUN: %clang_cc1 -emit-llvm < %s | grep "zeroinitializer, i16 16877" // PR4390 struct sysfs_dirent { - union { struct sysfs_elem_dir { int x; } s_dir; }; + union { struct sysfs_elem_dir {} s_dir; }; unsigned short s_mode; }; struct sysfs_dirent sysfs_root = { {}, 16877 }; -// CHECK: @sysfs_root = {{.*}}global { %union.anon, i16, [2 x i8] } { %union.anon zeroinitializer, i16 16877, [2 x i8] zeroinitializer } - -struct Foo { - union { struct empty {} x; }; - unsigned short s_mode; -}; -struct Foo foo = { {}, 16877 }; - -// EMPTY: @foo = {{.*}}global %struct.Foo { i16 16877 } -// EMPTY-MSVC: @foo = {{.*}}global %struct.Foo { [4 x i8] zeroinitializer, i16 16877 } diff --git a/clang/test/CodeGen/X86/x86_64-vaarg.c b/clang/test/CodeGen/X86/x86_64-vaarg.c index 450dfe5d15020..19802eedb02b7 100644 --- a/clang/test/CodeGen/X86/x86_64-vaarg.c +++ b/clang/test/CodeGen/X86/x86_64-vaarg.c @@ -56,8 +56,7 @@ typedef struct { // CHECK: vaarg.end: // CHECK-NEXT: [[VAARG_ADDR:%.*]] = phi ptr [ [[TMP1]], [[VAARG_IN_REG]] ], [ [[OVERFLOW_ARG_AREA]], [[VAARG_IN_MEM]] ] // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[VAARG_ADDR]], i64 8, i1 false) -// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_S1]], ptr [[RETVAL]], i32 0, i32 0 -// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[COERCE_DIVE]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[RETVAL]], align 8 // CHECK-NEXT: ret double [[TMP3]] // s1 f(int z, ...) { diff --git a/clang/test/CodeGen/paren-list-agg-init.cpp b/clang/test/CodeGen/paren-list-agg-init.cpp index 235352382332a..5c1c598dcd466 100644 --- a/clang/test/CodeGen/paren-list-agg-init.cpp +++ b/clang/test/CodeGen/paren-list-agg-init.cpp @@ -48,13 +48,14 @@ struct E { ~E() {}; }; +// CHECK-DAG: [[STRUCT_F:%.*]] = type { i8 } struct F { F (int i = 1); F (const F &f) = delete; F (F &&f) = default; }; -// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [4 x i8] }> +// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [[STRUCT_F]], [3 x i8] }> struct G { int a; F f; @@ -77,12 +78,12 @@ namespace gh61145 { ~Vec(); }; - // CHECK-DAG: [[STRUCT_S1:%.*]] = type { i8 } + // CHECK-DAG: [[STRUCT_S1:%.*]] = type { [[STRUCT_VEC]] } struct S1 { Vec v; }; - // CHECK-DAG: [[STRUCT_S2:%.*]] = type { i8, i8 } + // CHECK-DAG: [[STRUCT_S2:%.*]] = type { [[STRUCT_VEC]], i8 } struct S2 { Vec v; char c; @@ -376,7 +377,7 @@ void foo18() { // CHECK-NEXT: [[G:%.*g.*]] = alloca [[STRUCT_G]], align 4 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_G]], ptr [[G]], i32 0, i32 0 // CHECK-NEXT: store i32 2, ptr [[A]], align 4 -// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds i8, ptr [[G]], i64 4 +// CHECK-NEXT: [[F:%.*f.*]] = getelementptr inbounds nuw [[STRUCT_G]], ptr [[G]], i32 0, i32 1 // CHECk-NEXT: call void @{{.*F.*}}(ptr noundef nonnull align 1 dereferenceable(1)) [[F]], ie32 noundef 1) // CHECK: ret void void foo19() { @@ -391,8 +392,9 @@ namespace gh61145 { // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S1]], align 1 // a.k.a. Vec::Vec() // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds nuw [[STRUCT_S1]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0 // a.k.a. Vec::Vec(Vec&&) - // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) // a.k.a. S1::~S1() // CHECK-NEXT: call void @_ZN7gh611452S1D1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) // a.k.a.Vec::~Vec() @@ -411,8 +413,9 @@ namespace gh61145 { // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S2]], align 1 // a.k.a. Vec::Vec() // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds nuw [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0 // a.k.a. Vec::Vec(Vec&&) - // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) + // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]]) // CHECK-NEXT: [[C:%.*c.*]] = getelementptr inbounds nuw [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 // CHECK-NEXT: store i8 0, ptr [[C]], align 1 // a.k.a. S2::~S2() diff --git a/clang/test/CodeGen/union-init2.c b/clang/test/CodeGen/union-init2.c index ee35e78a4f301..6e039e7e27d53 100644 --- a/clang/test/CodeGen/union-init2.c +++ b/clang/test/CodeGen/union-init2.c @@ -13,7 +13,7 @@ union z { }; union z y = {}; -// CHECK: @foo = {{.*}}global %union.Foo undef, align 1 +// CHECK: @foo = {{.*}}global %union.Foo zeroinitializer, align 1 // CHECK-CXX: @foo = {{.*}}global %union.Foo undef, align 1 union Foo { struct Empty {} val; diff --git a/clang/test/CodeGen/voidptr-vaarg.c b/clang/test/CodeGen/voidptr-vaarg.c index a0211642bd82f..9551418fe9258 100644 --- a/clang/test/CodeGen/voidptr-vaarg.c +++ b/clang/test/CodeGen/voidptr-vaarg.c @@ -245,8 +245,7 @@ typedef struct { // CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 // CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[RETVAL]], ptr align 4 [[ARGP_CUR]], i32 4, i1 false) -// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_EMPTY_INT_T]], ptr [[RETVAL]], i32 0, i32 0 -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[COERCE_DIVE]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[RETVAL]], align 4 // CHECK-NEXT: ret i32 [[TMP0]] // empty_int_t empty_int(__builtin_va_list list) { diff --git a/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp b/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp index 3efb8c449c8fa..8922591f8e6f1 100644 --- a/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp +++ b/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp @@ -19,8 +19,8 @@ struct S { }; // CHECK: store i32 0, ptr @arr -// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr @arr, i64 4), ptr noundef @.str) +// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds nuw (%struct.S, ptr @arr, i32 0, i32 1), ptr noundef @.str) // CHECK: store i32 1, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 1) -// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 1), i64 4), ptr noundef @.str.1) +// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds nuw (%struct.S, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 1), i32 0, i32 1), ptr noundef @.str.1) // CHECK: store i32 2, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 2) -// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 2), i64 4), ptr noundef @.str.2) +// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds nuw (%struct.S, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 2), i32 0, i32 1), ptr noundef @.str.2) diff --git a/clang/test/CodeGenCXX/bitfield-access-empty.cpp b/clang/test/CodeGenCXX/bitfield-access-empty.cpp index d1ae12e202cda..928b466267409 100644 --- a/clang/test/CodeGenCXX/bitfield-access-empty.cpp +++ b/clang/test/CodeGenCXX/bitfield-access-empty.cpp @@ -84,8 +84,8 @@ struct P3 { unsigned b : 16; } p3; // CHECK-LABEL: LLVMType:%struct.P3 = -// LAYOUT-SAME: type { i16, [2 x i8], i16, [2 x i8] } -// LAYOUT-DWN32-SAME: type <{ i16, i8, i16 }> +// LAYOUT-SAME: type { i16, %struct.Empty, i16, [2 x i8] } +// LAYOUT-DWN32-SAME: type <{ i16, %struct.Empty, i16 }> // CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P3 = // CHECK: BitFields:[ // LAYOUT-NEXT: diff --git a/clang/test/CodeGenCXX/class-layout.cpp b/clang/test/CodeGenCXX/class-layout.cpp index 90617d25b254e..84b0f887876ac 100644 --- a/clang/test/CodeGenCXX/class-layout.cpp +++ b/clang/test/CodeGenCXX/class-layout.cpp @@ -83,7 +83,7 @@ namespace Test6 { namespace Test7 { #pragma pack (1) class A {}; - // CHECK: %"class.Test7::B" = type <{ ptr, i8 }> + // CHECK: %"class.Test7::B" = type <{ ptr, %"class.Test7::A" }> class B { virtual ~B(); A a; diff --git a/clang/test/CodeGenCXX/compound-literals.cpp b/clang/test/CodeGenCXX/compound-literals.cpp index 1b4a1d4445123..fcec2d19e2def 100644 --- a/clang/test/CodeGenCXX/compound-literals.cpp +++ b/clang/test/CodeGenCXX/compound-literals.cpp @@ -20,7 +20,7 @@ int f() { // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, ptr [[LVALUE]], i32 0, i32 0 // CHECK-NEXT: store i32 17, ptr [[I]] - // CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 4 + // CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1 // CHECK-NEXT: call noundef ptr @_ZN1XC1EPKc({{.*}}[[X]] // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0 // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32, ptr diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp index 61cffd1023b88..9875740c09b41 100644 --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -513,7 +513,8 @@ namespace test11 { // CHECK-LABEL: define{{.*}} void @_ZN6test111CC2Ev( // CHECK: [[THIS:%.*]] = load ptr, ptr {{%.*}} // Construct single. - // CHECK-NEXT: call void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[THIS]]) + // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds nuw [[C:%.*]], ptr [[THIS]], i32 0, i32 0 + // CHECK-NEXT: call void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[SINGLE]]) // Construct array. // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[C:%.*]], ptr [[THIS]], i32 0, i32 1 // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0 @@ -559,8 +560,8 @@ namespace test11 { // CHECK: br label // Finally, the cleanup for single. - // CHECK98: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]]) - // CHECK11: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]]) + // CHECK98: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[SINGLE]]) + // CHECK11: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[SINGLE]]) // CHECK: br label // CHECK: resume diff --git a/clang/test/CodeGenCXX/lambda-deterministic-captures.cpp b/clang/test/CodeGenCXX/lambda-deterministic-captures.cpp index ab44f43720832..ef3847d0c1e93 100644 --- a/clang/test/CodeGenCXX/lambda-deterministic-captures.cpp +++ b/clang/test/CodeGenCXX/lambda-deterministic-captures.cpp @@ -16,7 +16,8 @@ void foo() { } // CHECK: define{{.*}} void @_Z3foov -// CHECK: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 1 +// CHECK: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 +// CHECK-NEXT: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 1 // CHECK-NEXT: store float 0.000 // CHECK-NEXT: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 2 // CHECK-NEXT: store float 1.000 @@ -26,6 +27,7 @@ void foo() { // The lambda body. Reverse iteration when the captures aren't deterministic // causes these to be laid out differently in the lambda. // CHECK: define internal void +// CHECK: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 1 // CHECK: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 2 // CHECK: getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 3 diff --git a/clang/test/CodeGenCXX/partial-destruction.cpp b/clang/test/CodeGenCXX/partial-destruction.cpp index 548a9f154be9e..5412e1ddd6274 100644 --- a/clang/test/CodeGenCXX/partial-destruction.cpp +++ b/clang/test/CodeGenCXX/partial-destruction.cpp @@ -107,12 +107,13 @@ namespace test1 { // CHECK: [[V:%.*]] = alloca [[B:%.*]], align 4 // CHECK-NEXT: alloca ptr // CHECK-NEXT: alloca i32 - // CHECK-NEXT: call void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[V]], i32 noundef 5) - // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds i8, ptr [[V]], i64 1 + // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[B]], ptr [[V]], i32 0, i32 0 + // CHECK-NEXT: call void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[X]], i32 noundef 5) + // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[B]], ptr [[V]], i32 0, i32 1 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[Y]], i32 noundef 6) - // CHECK: [[Z:%.*]] = getelementptr inbounds i8, ptr [[V]], i64 2 + // CHECK: [[Z:%.*]] = getelementptr inbounds nuw [[B]], ptr [[V]], i32 0, i32 2 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[Z]], i32 noundef 7) - // CHECK: [[W:%.*]] = getelementptr inbounds nuw [[B]], ptr [[V]], i32 0, i32 1 + // CHECK: [[W:%.*]] = getelementptr inbounds nuw [[B]], ptr [[V]], i32 0, i32 3 // CHECK-NEXT: store i32 8, ptr [[W]], align 4 // CHECK-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[V]]) // CHECK-NEXT: ret void @@ -123,9 +124,9 @@ namespace test1 { // CHECK: landingpad { ptr, i32 } // CHECK-NEXT: cleanup // CHECKv03: invoke void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[Y]]) - // CHECKv03: invoke void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[V]]) + // CHECKv03: invoke void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[X]]) // CHECKv11: call void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[Y]]) - // CHECKv11: call void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[V]]) + // CHECKv11: call void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[X]]) } namespace test2 { diff --git a/clang/test/CodeGenCXX/pod-member-memcpys.cpp b/clang/test/CodeGenCXX/pod-member-memcpys.cpp index 8efec6184a3da..16d3d45a8179b 100644 --- a/clang/test/CodeGenCXX/pod-member-memcpys.cpp +++ b/clang/test/CodeGenCXX/pod-member-memcpys.cpp @@ -1,8 +1,6 @@ // RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-apple-darwin10 -emit-llvm -std=c++03 -fexceptions -fcxx-exceptions -o - %s | FileCheck %s // RUN: %clang_cc1 -no-enable-noundef-analysis -triple i386-apple-darwin10 -emit-llvm -std=c++03 -o - %s | FileCheck --check-prefix=CHECK-2 %s -struct Empty {}; - struct POD { int w, x, y, z; }; @@ -108,20 +106,6 @@ struct __attribute__((packed)) PackedMembers { int w, x, y, z; }; -struct WithEmptyField { - int a; - Empty e; - NonPOD np; - int b; -}; - -struct WithEmptyNUAField { - int a; - [[no_unique_address]] Empty e; - NonPOD np; - int b; -}; - // COPY-ASSIGNMENT OPERATORS: // Assignment operators are output in the order they're encountered. @@ -137,8 +121,6 @@ CALL_AO(VolatileMember) CALL_AO(BitfieldMember) CALL_AO(InnerClassMember) CALL_AO(PackedMembers) -CALL_AO(WithEmptyField) -CALL_AO(WithEmptyNUAField) // Basic copy-assignment: // CHECK-LABEL: define linkonce_odr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN5BasicaSERKS_(ptr {{[^,]*}} %this, ptr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %0) @@ -203,18 +185,6 @@ CALL_AO(WithEmptyNUAField) // CHECK: call void @llvm.memcpy.p0.p0.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 16, i1 {{.*}}) // CHECK: ret ptr -// WithEmptyField copy-assignment: -// CHECK-LABEL: define linkonce_odr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN14WithEmptyFieldaSERKS_ -// CHECK: call void @llvm.memcpy.p0.p0.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 4, i1 {{.*}}) -// CHECK: call nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN6NonPODaSERKS_ -// CHECK: ret ptr - -// WithEmptyNUAField copy-assignment: -// CHECK-LABEL: define linkonce_odr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN17WithEmptyNUAFieldaSERKS_ -// CHECK: call void @llvm.memcpy.p0.p0.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 4, i1 {{.*}}) -// CHECK: call nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN6NonPODaSERKS_ -// CHECK: ret ptr - // COPY-CONSTRUCTORS: // Clang outputs copy-constructors in the reverse of the order that @@ -310,15 +280,3 @@ CALL_CC(Basic) // CHECK: call void @_ZN6NonPODC1ERKS_ // CHECK: call void @llvm.memcpy.p0.p0.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) // CHECK: ret void - -CALL_CC(WithEmptyField) -// WithEmptyField copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN14WithEmptyFieldC2ERKS_ -// CHECK: call void @llvm.memcpy.p0.p0.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 4, i1 {{.*}}) -// CHECK: call void @_ZN6NonPODC1ERKS_ - -CALL_CC(WithEmptyNUAField) -// WithEmptyNUAField copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN17WithEmptyNUAFieldC2ERKS_(ptr {{[^,]*}} %this, ptr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %0) -// CHECK: call void @llvm.memcpy.p0.p0.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 4, i1 {{.*}}) -// CHECK: call void @_ZN6NonPODC1ERKS_ diff --git a/clang/test/CodeGenCXX/pr18962.cpp b/clang/test/CodeGenCXX/pr18962.cpp index 9ac87003c94c5..b564a7b9a73af 100644 --- a/clang/test/CodeGenCXX/pr18962.cpp +++ b/clang/test/CodeGenCXX/pr18962.cpp @@ -23,6 +23,7 @@ D p3; // We end up using an opaque type for 'append' to avoid circular references. // CHECK: %class.A = type { ptr } -// CHECK: %class.C = type <{ ptr, [4 x i8] }> +// CHECK: %class.C = type <{ ptr, %class.B, [3 x i8] }> +// CHECK: %class.B = type { i8 } // CHECK: %class.D = type { %class.C.base, [3 x i8] } -// CHECK: %class.C.base = type <{ ptr, i8 }> +// CHECK: %class.C.base = type <{ ptr, %class.B }> diff --git a/clang/test/CodeGenCXX/references.cpp b/clang/test/CodeGenCXX/references.cpp index b84cb788d161c..0fca5e76659c2 100644 --- a/clang/test/CodeGenCXX/references.cpp +++ b/clang/test/CodeGenCXX/references.cpp @@ -191,6 +191,7 @@ namespace N2 { // CHECK-LABEL: define{{.*}} void @_ZN2N21fEi // CHECK: call void @_ZN2N24getPEv + // CHECK: getelementptr inbounds // CHECK: store i32 17 // CHECK: call void @_ZN2N21PD1Ev void f(int i) { @@ -219,7 +220,8 @@ namespace N2 { // CHECK-LABEL: define{{.*}} void @_ZN2N21gEi // CHECK: call void @_ZN2N24getZEv - // CHECK: {{getelementptr inbounds.*i64 16}} + // CHECK: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK: {{getelementptr inbounds.*i32 0, i32 0}} // CHECK: store i32 19 // CHECK: call void @_ZN2N21ZD1Ev // CHECK: ret void diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp index 44978dd403ad9..36ab0e89f7d50 100644 --- a/clang/test/CodeGenCXX/temporaries.cpp +++ b/clang/test/CodeGenCXX/temporaries.cpp @@ -714,7 +714,7 @@ namespace MultipleExtension { // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev, {{.*}} @[[TEMPA]] // CHECK: store {{.*}} @[[TEMPA]], {{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], - // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i64 8)) + // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds nuw ({{.*}} @[[TEMPE]], i32 0, i32 1)) // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]]) // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev, {{.*}} @[[TEMPD]] @@ -728,7 +728,7 @@ namespace MultipleExtension { // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev, {{.*}} @[[TEMPA]] // CHECK: store {{.*}} @[[TEMPA]], {{.*}} @[[E:_ZN17MultipleExtension2e2E]] - // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i64 8)) + // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds nuw ({{.*}} @[[E]], i32 0, i32 1)) // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]]) // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev, {{.*}} @[[TEMPD]] @@ -743,11 +743,11 @@ namespace MultipleExtension { // CHECK: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0 // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]]) // CHECK: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]] - // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i64 8 + // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1 // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]]) // CHECK: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2 // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]]) - // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i64 4 + // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1 // CHECK: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]] // CHECK: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]] @@ -758,11 +758,11 @@ namespace MultipleExtension { // CHECK: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0 // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]]) // CHECK: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]] - // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i64 8 + // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1 // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]]) // CHECK: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2 // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]]) - // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i64 4 + // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1 // CHECK: store {{.*}} %[[TEMPD2_C]], ptr %[[TEMPE2_C]] g(); diff --git a/clang/test/CodeGenObjCXX/lambda-to-block.mm b/clang/test/CodeGenObjCXX/lambda-to-block.mm index a8657ca711f7c..b1e1338c6ac1e 100644 --- a/clang/test/CodeGenObjCXX/lambda-to-block.mm +++ b/clang/test/CodeGenObjCXX/lambda-to-block.mm @@ -2,10 +2,11 @@ // Shouldn't crash! -// CHECK: %[[CLASS_ANON:.*]] = type { i8 } -// CHECK: %[[CLASS_ANON_0:.*]] = type { i8 } -// CHECK: %[[CLASS_ANON_1:.*]] = type { i8 } -// CHECK: %[[CLASS_ANON_2:.*]] = type { i8 } +// CHECK: %[[CLASS_ANON:.*]] = type { %[[STRUCT_COPYABLE:.*]] } +// CHECK: %[[STRUCT_COPYABLE]] = type { i8 } +// CHECK: %[[CLASS_ANON_0:.*]] = type { %[[STRUCT_COPYABLE]] } +// CHECK: %[[CLASS_ANON_1:.*]] = type { %[[STRUCT_COPYABLE]] } +// CHECK: %[[CLASS_ANON_2:.*]] = type { %[[STRUCT_COPYABLE]] } // CHECK: @[[BLOCK_DESC0:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 33, ptr @[[COPY_HELPER0:.*__copy_helper_block_.*]], ptr @__destroy_helper_block{{.*}}, {{.*}}}, align 8 // CHECK: @[[BLOCK_DESC1:.*]] = internal constant { i64, i64, ptr, ptr, ptr, ptr } { i64 0, i64 33, ptr @[[COPY_HELPER1:.*__copy_helper_block_.*]], ptr @__destroy_helper_block{{.*}}, {{.*}}}, align 8 diff --git a/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp index 6ba2464874ac3..3ab52dc9c6e29 100644 --- a/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp +++ b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp @@ -2,6 +2,8 @@ // RUN: | FileCheck %s // REQUIRES: goodKeys +// XFAIL: * + // g::h and i can be memcpy'd, check the assignment gets Key Instructions metadata. struct e { diff --git a/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp index ec28cde3b4c4e..242ae8008fb34 100644 --- a/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp +++ b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp @@ -2,6 +2,8 @@ // RUN: | FileCheck %s // REQUIRES: goodKeys +// XFAIL: * + // g::h can be memcpy'd (in this case emitted as load/stored), check the // assignment gets Key Instructions metadata. diff --git a/clang/test/DebugInfo/KeyInstructions/return-va-arg.c b/clang/test/DebugInfo/KeyInstructions/return-va-arg.c index 7bfca47418918..ede121c981dd3 100644 --- a/clang/test/DebugInfo/KeyInstructions/return-va-arg.c +++ b/clang/test/DebugInfo/KeyInstructions/return-va-arg.c @@ -5,6 +5,8 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -gno-column-info -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \ // RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank +// XFAIL: * + typedef struct { struct{} a; double b; diff --git a/clang/test/OpenMP/amdgcn_sret_ctor.cpp b/clang/test/OpenMP/amdgcn_sret_ctor.cpp index fc6f7c15eb5e6..81d0cce5190e7 100644 --- a/clang/test/OpenMP/amdgcn_sret_ctor.cpp +++ b/clang/test/OpenMP/amdgcn_sret_ctor.cpp @@ -19,8 +19,9 @@ E::E() noexcept : foo(s()) {} // CHECK-NEXT: [[THIS_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[THIS_ADDR]] to ptr // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[THIS1_ASCAST:%.*]] = addrspacecast ptr [[THIS1]] to ptr addrspace(5) -// CHECK-NEXT: call void @_Z1sv(ptr addrspace(5) dead_on_unwind writable sret([[STRUCT_S:%.*]]) align 1 [[THIS1_ASCAST]]) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: [[FOO:%.*]] = getelementptr inbounds nuw [[STRUCT_E:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: [[FOO_ASCAST:%.*]] = addrspacecast ptr [[FOO]] to ptr addrspace(5) +// CHECK-NEXT: call void @_Z1sv(ptr addrspace(5) dead_on_unwind writable sret([[STRUCT_S:%.*]]) align 1 [[FOO_ASCAST]]) #[[ATTR2:[0-9]+]] // CHECK-NEXT: ret void // // diff --git a/clang/test/OpenMP/irbuilder_for_iterator.cpp b/clang/test/OpenMP/irbuilder_for_iterator.cpp index ec1c3af744b49..e1e8ff66cd8aa 100644 --- a/clang/test/OpenMP/irbuilder_for_iterator.cpp +++ b/clang/test/OpenMP/irbuilder_for_iterator.cpp @@ -48,48 +48,49 @@ extern "C" void workshareloop_iterator(float *a, float *b, float *c) { // CHECK-NEXT: call void @_ZN10MyIteratorC1Ej(ptr noundef nonnull align 1 dereferenceable(1) [[IT]], i32 noundef 7) // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[AGG_CAPTURED]], i32 0, i32 0 // CHECK-NEXT: store ptr [[IT]], ptr [[TMP0]], align 8 -// CHECK-NEXT: call void @_ZN10MyIteratorC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_CAPTURED1]], ptr noundef nonnull align 1 dereferenceable(1) [[IT]]) +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0]], ptr [[AGG_CAPTURED1]], i32 0, i32 0 +// CHECK-NEXT: call void @_ZN10MyIteratorC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]], ptr noundef nonnull align 1 dereferenceable(1) [[IT]]) // CHECK-NEXT: call void @__captured_stmt(ptr [[DOTCOUNT_ADDR]], ptr [[AGG_CAPTURED]]) // CHECK-NEXT: [[DOTCOUNT:%.*]] = load i64, ptr [[DOTCOUNT_ADDR]], align 8 // CHECK-NEXT: br label [[OMP_LOOP_PREHEADER:%.*]] // CHECK: omp_loop.preheader: // CHECK-NEXT: store i64 0, ptr [[P_LOWERBOUND]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[DOTCOUNT]], 1 -// CHECK-NEXT: store i64 [[TMP1]], ptr [[P_UPPERBOUND]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[DOTCOUNT]], 1 +// CHECK-NEXT: store i64 [[TMP2]], ptr [[P_UPPERBOUND]], align 8 // CHECK-NEXT: store i64 1, ptr [[P_STRIDE]], align 8 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) // CHECK-NEXT: call void @__kmpc_for_static_init_8u(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], i32 34, ptr [[P_LASTITER]], ptr [[P_LOWERBOUND]], ptr [[P_UPPERBOUND]], ptr [[P_STRIDE]], i64 1, i64 0) -// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[P_LOWERBOUND]], align 8 -// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[P_UPPERBOUND]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = sub i64 [[TMP3]], [[TMP2]] -// CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP4]], 1 +// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[P_LOWERBOUND]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr [[P_UPPERBOUND]], align 8 +// CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[TMP4]], [[TMP3]] +// CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], 1 // CHECK-NEXT: br label [[OMP_LOOP_HEADER:%.*]] // CHECK: omp_loop.header: // CHECK-NEXT: [[OMP_LOOP_IV:%.*]] = phi i64 [ 0, [[OMP_LOOP_PREHEADER]] ], [ [[OMP_LOOP_NEXT:%.*]], [[OMP_LOOP_INC:%.*]] ] // CHECK-NEXT: br label [[OMP_LOOP_COND:%.*]] // CHECK: omp_loop.cond: -// CHECK-NEXT: [[OMP_LOOP_CMP:%.*]] = icmp ult i64 [[OMP_LOOP_IV]], [[TMP5]] +// CHECK-NEXT: [[OMP_LOOP_CMP:%.*]] = icmp ult i64 [[OMP_LOOP_IV]], [[TMP6]] // CHECK-NEXT: br i1 [[OMP_LOOP_CMP]], label [[OMP_LOOP_BODY:%.*]], label [[OMP_LOOP_EXIT:%.*]] // CHECK: omp_loop.body: -// CHECK-NEXT: [[TMP6:%.*]] = add i64 [[OMP_LOOP_IV]], [[TMP2]] -// CHECK-NEXT: call void @__captured_stmt.1(ptr [[IT]], i64 [[TMP6]], ptr [[AGG_CAPTURED1]]) +// CHECK-NEXT: [[TMP7:%.*]] = add i64 [[OMP_LOOP_IV]], [[TMP3]] +// CHECK-NEXT: call void @__captured_stmt.1(ptr [[IT]], i64 [[TMP7]], ptr [[AGG_CAPTURED1]]) // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZNK10MyIteratordeEv(ptr noundef nonnull align 1 dereferenceable(1) [[IT]]) // CHECK-NEXT: store i32 [[CALL]], ptr [[I]], align 4 -// CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[B_ADDR]], align 8 -// CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4 -// CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP8]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP7]], i64 [[IDXPROM]] -// CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -// CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[C_ADDR]], align 8 -// CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4 -// CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP11]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM2]] -// CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 -// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP9]], [[TMP12]] -// CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4 -// CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP14]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[TMP8:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[I]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP8]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX]], align 4 +// CHECK-NEXT: [[TMP11:%.*]] = load ptr, ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[I]], align 4 +// CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP12]] to i64 +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP10]], [[TMP13]] +// CHECK-NEXT: [[TMP14:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4 +// CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP15]] to i64 +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM4]] // CHECK-NEXT: store float [[MUL]], ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: @@ -154,11 +155,12 @@ extern "C" void workshareloop_iterator(float *a, float *b, float *c) { // CHECK-NEXT: store i64 [[LOGICAL]], ptr [[LOGICAL_ADDR]], align 8 // CHECK-NEXT: store ptr [[__CONTEXT]], ptr [[__CONTEXT_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__CONTEXT_ADDR]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[LOGICAL_ADDR]], align 8 -// CHECK-NEXT: [[MUL:%.*]] = mul i64 1, [[TMP1]] +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[LOGICAL_ADDR]], align 8 +// CHECK-NEXT: [[MUL:%.*]] = mul i64 1, [[TMP2]] // CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[MUL]] to i32 -// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP0]], i32 noundef [[CONV]]) -// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOOPVAR_ADDR]], align 8 -// CHECK-NEXT: [[CALL:%.*]] = call noundef nonnull align 1 dereferenceable(1) ptr @_ZN10MyIteratoraSERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[TMP2]], ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) +// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]], i32 noundef [[CONV]]) +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LOOPVAR_ADDR]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call noundef nonnull align 1 dereferenceable(1) ptr @_ZN10MyIteratoraSERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[TMP3]], ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) // CHECK-NEXT: ret void // diff --git a/clang/test/OpenMP/irbuilder_for_rangefor.cpp b/clang/test/OpenMP/irbuilder_for_rangefor.cpp index 86a043e638bc3..635382f737f18 100644 --- a/clang/test/OpenMP/irbuilder_for_rangefor.cpp +++ b/clang/test/OpenMP/irbuilder_for_rangefor.cpp @@ -66,46 +66,47 @@ extern "C" void workshareloop_rangefor(float *a, float *b, float *c) { // CHECK-NEXT: store ptr [[__BEGIN2]], ptr [[TMP2]], align 8 // CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON]], ptr [[AGG_CAPTURED]], i32 0, i32 1 // CHECK-NEXT: store ptr [[__END2]], ptr [[TMP3]], align 8 -// CHECK-NEXT: call void @_ZN10MyIteratorC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_CAPTURED1]], ptr noundef nonnull align 1 dereferenceable(1) [[__BEGIN2]]) +// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0]], ptr [[AGG_CAPTURED1]], i32 0, i32 0 +// CHECK-NEXT: call void @_ZN10MyIteratorC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[TMP4]], ptr noundef nonnull align 1 dereferenceable(1) [[__BEGIN2]]) // CHECK-NEXT: call void @__captured_stmt(ptr [[DOTCOUNT_ADDR]], ptr [[AGG_CAPTURED]]) // CHECK-NEXT: [[DOTCOUNT:%.*]] = load i64, ptr [[DOTCOUNT_ADDR]], align 8 // CHECK-NEXT: br label [[OMP_LOOP_PREHEADER:%.*]] // CHECK: omp_loop.preheader: // CHECK-NEXT: store i64 0, ptr [[P_LOWERBOUND]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = sub i64 [[DOTCOUNT]], 1 -// CHECK-NEXT: store i64 [[TMP4]], ptr [[P_UPPERBOUND]], align 8 +// CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[DOTCOUNT]], 1 +// CHECK-NEXT: store i64 [[TMP5]], ptr [[P_UPPERBOUND]], align 8 // CHECK-NEXT: store i64 1, ptr [[P_STRIDE]], align 8 // CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) // CHECK-NEXT: call void @__kmpc_for_static_init_8u(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], i32 34, ptr [[P_LASTITER]], ptr [[P_LOWERBOUND]], ptr [[P_UPPERBOUND]], ptr [[P_STRIDE]], i64 1, i64 0) -// CHECK-NEXT: [[TMP5:%.*]] = load i64, ptr [[P_LOWERBOUND]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = load i64, ptr [[P_UPPERBOUND]], align 8 -// CHECK-NEXT: [[TMP7:%.*]] = sub i64 [[TMP6]], [[TMP5]] -// CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP7]], 1 +// CHECK-NEXT: [[TMP6:%.*]] = load i64, ptr [[P_LOWERBOUND]], align 8 +// CHECK-NEXT: [[TMP7:%.*]] = load i64, ptr [[P_UPPERBOUND]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = sub i64 [[TMP7]], [[TMP6]] +// CHECK-NEXT: [[TMP9:%.*]] = add i64 [[TMP8]], 1 // CHECK-NEXT: br label [[OMP_LOOP_HEADER:%.*]] // CHECK: omp_loop.header: // CHECK-NEXT: [[OMP_LOOP_IV:%.*]] = phi i64 [ 0, [[OMP_LOOP_PREHEADER]] ], [ [[OMP_LOOP_NEXT:%.*]], [[OMP_LOOP_INC:%.*]] ] // CHECK-NEXT: br label [[OMP_LOOP_COND:%.*]] // CHECK: omp_loop.cond: -// CHECK-NEXT: [[OMP_LOOP_CMP:%.*]] = icmp ult i64 [[OMP_LOOP_IV]], [[TMP8]] +// CHECK-NEXT: [[OMP_LOOP_CMP:%.*]] = icmp ult i64 [[OMP_LOOP_IV]], [[TMP9]] // CHECK-NEXT: br i1 [[OMP_LOOP_CMP]], label [[OMP_LOOP_BODY:%.*]], label [[OMP_LOOP_EXIT:%.*]] // CHECK: omp_loop.body: -// CHECK-NEXT: [[TMP9:%.*]] = add i64 [[OMP_LOOP_IV]], [[TMP5]] -// CHECK-NEXT: call void @__captured_stmt.1(ptr [[I]], i64 [[TMP9]], ptr [[AGG_CAPTURED1]]) -// CHECK-NEXT: [[TMP10:%.*]] = load ptr, ptr [[B_ADDR]], align 8 -// CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4 -// CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP11]] to i64 -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP10]], i64 [[IDXPROM]] -// CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -// CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[C_ADDR]], align 8 -// CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[I]], align 4 -// CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP14]] to i64 -// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP13]], i64 [[IDXPROM2]] -// CHECK-NEXT: [[TMP15:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 -// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP12]], [[TMP15]] -// CHECK-NEXT: [[TMP16:%.*]] = load ptr, ptr [[A_ADDR]], align 8 -// CHECK-NEXT: [[TMP17:%.*]] = load i32, ptr [[I]], align 4 -// CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP17]] to i64 -// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP16]], i64 [[IDXPROM4]] +// CHECK-NEXT: [[TMP10:%.*]] = add i64 [[OMP_LOOP_IV]], [[TMP6]] +// CHECK-NEXT: call void @__captured_stmt.1(ptr [[I]], i64 [[TMP10]], ptr [[AGG_CAPTURED1]]) +// CHECK-NEXT: [[TMP11:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[I]], align 4 +// CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[TMP12]] to i64 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP11]], i64 [[IDXPROM]] +// CHECK-NEXT: [[TMP13:%.*]] = load float, ptr [[ARRAYIDX]], align 4 +// CHECK-NEXT: [[TMP14:%.*]] = load ptr, ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[I]], align 4 +// CHECK-NEXT: [[IDXPROM2:%.*]] = zext i32 [[TMP15]] to i64 +// CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw float, ptr [[TMP14]], i64 [[IDXPROM2]] +// CHECK-NEXT: [[TMP16:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP13]], [[TMP16]] +// CHECK-NEXT: [[TMP17:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4 +// CHECK-NEXT: [[IDXPROM4:%.*]] = zext i32 [[TMP18]] to i64 +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds nuw float, ptr [[TMP17]], i64 [[IDXPROM4]] // CHECK-NEXT: store float [[MUL]], ptr [[ARRAYIDX5]], align 4 // CHECK-NEXT: br label [[OMP_LOOP_INC]] // CHECK: omp_loop.inc: @@ -172,12 +173,13 @@ extern "C" void workshareloop_rangefor(float *a, float *b, float *c) { // CHECK-NEXT: store i64 [[LOGICAL]], ptr [[LOGICAL_ADDR]], align 8 // CHECK-NEXT: store ptr [[__CONTEXT]], ptr [[__CONTEXT_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__CONTEXT_ADDR]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[LOGICAL_ADDR]], align 8 -// CHECK-NEXT: [[MUL:%.*]] = mul i64 1, [[TMP1]] +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_ANON_0:%.*]], ptr [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[LOGICAL_ADDR]], align 8 +// CHECK-NEXT: [[MUL:%.*]] = mul i64 1, [[TMP2]] // CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[MUL]] to i32 -// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP0]], i32 noundef [[CONV]]) +// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]], i32 noundef [[CONV]]) // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZNK10MyIteratordeEv(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) -// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOOPVAR_ADDR]], align 8 -// CHECK-NEXT: store i32 [[CALL]], ptr [[TMP2]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LOOPVAR_ADDR]], align 8 +// CHECK-NEXT: store i32 [[CALL]], ptr [[TMP3]], align 4 // CHECK-NEXT: ret void // diff --git a/clang/test/OpenMP/task_member_call_codegen.cpp b/clang/test/OpenMP/task_member_call_codegen.cpp index a6ae29c1f9f6d..8f7d2d15d0e26 100644 --- a/clang/test/OpenMP/task_member_call_codegen.cpp +++ b/clang/test/OpenMP/task_member_call_codegen.cpp @@ -32,8 +32,9 @@ void c() { // CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) // CHECK1-NEXT: [[TMP1:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @[[GLOB1]], i32 [[TMP0]], i32 1, i64 48, i64 1, ptr @.omp_task_entry.) // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T_WITH_PRIVATES:%.*]], ptr [[TMP1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 40 -// CHECK1-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_omp_task(ptr @[[GLOB1]], i32 [[TMP0]], ptr [[TMP1]]) +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], ptr [[TMP1]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[STRUCT__KMP_PRIVATES_T:%.*]], ptr [[TMP3]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_omp_task(ptr @[[GLOB1]], i32 [[TMP0]], ptr [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -45,8 +46,9 @@ void c() { // CHECK1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK1-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 -// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8 -// CHECK1-NEXT: store ptr [[TMP2]], ptr [[TMP3]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT__KMP_PRIVATES_T:%.*]], ptr [[TMP2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTADDR1]], align 8 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP4]], align 8 // CHECK1-NEXT: ret void // // @@ -70,7 +72,7 @@ void c() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T:%.*]], ptr [[TMP4]], i32 0, i32 2 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T]], ptr [[TMP4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8 -// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 40 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], ptr [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) @@ -98,9 +100,10 @@ void c() { // CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3:[0-9]+]]) // CHECK3-NEXT: [[TMP0:%.*]] = call ptr @__kmpc_omp_task_alloc(ptr @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]], i32 1, i64 48, i64 1, ptr @.omp_task_entry.) // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T_WITH_PRIVATES:%.*]], ptr [[TMP0]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 40 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], ptr [[TMP0]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT__KMP_PRIVATES_T:%.*]], ptr [[TMP2]], i32 0, i32 0 // CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) -// CHECK3-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_omp_task(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM1]], ptr [[TMP0]]) +// CHECK3-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_omp_task(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM1]], ptr [[TMP0]]) // CHECK3-NEXT: ret void // // @@ -112,8 +115,9 @@ void c() { // CHECK3-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK3-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8 // CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 -// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8 -// CHECK3-NEXT: store ptr [[TMP2]], ptr [[TMP3]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[STRUCT__KMP_PRIVATES_T:%.*]], ptr [[TMP2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTADDR1]], align 8 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP4]], align 8 // CHECK3-NEXT: ret void // // @@ -137,7 +141,7 @@ void c() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T:%.*]], ptr [[TMP4]], i32 0, i32 2 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T]], ptr [[TMP4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8 -// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 40 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], ptr [[TMP3]], i32 0, i32 1 // CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) // CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) // CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 96a715a2cb0f0..0289d19a44c49 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -914,12 +914,8 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { // If DWARF address space value is other than None, add it. The IR // verifier checks that DWARF address space only exists for pointer // or reference types. - if (auto AS = DTy->getDWARFAddressSpace()) { - // TODO: Drop address_class once the debugger adopts address_space - for (auto ASTag : - {dwarf::DW_AT_address_class, dwarf::DW_AT_LLVM_address_space}) - addUInt(Buffer, ASTag, dwarf::DW_FORM_data4, *AS); - } + if (auto AS = DTy->getDWARFAddressSpace()) + addUInt(Buffer, dwarf::DW_AT_LLVM_address_space, dwarf::DW_FORM_data4, *AS); // Add template alias template parameters. if (Tag == dwarf::DW_TAG_template_alias) diff --git a/llvm/test/DebugInfo/AMDGPU/heterogeneous-dwarf-diop-diexpression-address-spaces.ll b/llvm/test/DebugInfo/AMDGPU/heterogeneous-dwarf-diop-diexpression-address-spaces.ll index d9d143d4823b9..05d3583197f77 100644 --- a/llvm/test/DebugInfo/AMDGPU/heterogeneous-dwarf-diop-diexpression-address-spaces.ll +++ b/llvm/test/DebugInfo/AMDGPU/heterogeneous-dwarf-diop-diexpression-address-spaces.ll @@ -123,7 +123,6 @@ attributes #0 = { "frame-pointer"="all" } ; CHECK: [[PTR_AS_3]]: DW_TAG_pointer_type ; CHECK-NEXT: DW_AT_type -; CHECK-NEXT: DW_AT_address_class (0x00000003) ; CHECK-NEXT: DW_AT_LLVM_address_space (0x00000003 "DW_ASPACE_LLVM_AMDGPU_local") ; CHECK: [[PTR_AS_NONE]]: DW_TAG_pointer_type @@ -132,7 +131,6 @@ attributes #0 = { "frame-pointer"="all" } ; CHECK: [[PTR_AS_5]]: DW_TAG_pointer_type ; CHECK-NEXT: DW_AT_type -; CHECK-NEXT: DW_AT_address_class (0x00000005) ; CHECK-NEXT: DW_AT_LLVM_address_space (0x00000005 "DW_ASPACE_LLVM_AMDGPU_private_lane") !llvm.dbg.cu = !{!0} diff --git a/llvm/test/DebugInfo/AMDGPU/pointer-address-space.ll b/llvm/test/DebugInfo/AMDGPU/pointer-address-space.ll index 60df8365e321e..3e8e80e442e5b 100644 --- a/llvm/test/DebugInfo/AMDGPU/pointer-address-space.ll +++ b/llvm/test/DebugInfo/AMDGPU/pointer-address-space.ll @@ -50,13 +50,11 @@ ; CHECK: 0x[[LOCAL]]: DW_TAG_pointer_type ; CHECK-NEXT: DW_AT_type -; CHECK-NEXT: DW_AT_address_class [DW_FORM_data4] (0x00000002) ; CHECK-NEXT: DW_AT_LLVM_address_space [DW_FORM_data4] (0x00000002 "DW_ASPACE_LLVM_AMDGPU_region") ; CHECK-NEXT: DW_AT_LLVM_memory_space [DW_FORM_data4] (DW_MSPACE_LLVM_group) ; CHECK: 0x[[PRIVATE]]: DW_TAG_pointer_type ; CHECK-NEXT: DW_AT_type -; CHECK-NEXT: DW_AT_address_class [DW_FORM_data4] (0x00000001) ; CHECK-NEXT: DW_AT_LLVM_address_space [DW_FORM_data4] (0x00000001 "DW_ASPACE_LLVM_AMDGPU_generic") ; CHECK-NEXT: DW_AT_LLVM_memory_space [DW_FORM_data4] (DW_MSPACE_LLVM_private) diff --git a/llvm/test/DebugInfo/Generic/address_space_rvalue.ll b/llvm/test/DebugInfo/Generic/address_space_rvalue.ll index 38798c11b5667..b16ac7e6ce987 100644 --- a/llvm/test/DebugInfo/Generic/address_space_rvalue.ll +++ b/llvm/test/DebugInfo/Generic/address_space_rvalue.ll @@ -6,7 +6,8 @@ ; CHECK: DW_TAG_rvalue_reference_type ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_address_class (0x00000001) +; CHECK-NOT: DW_AT_address_class +; CHECK: DW_AT_LLVM_address_space (0x00000001) @y = global ptr null, align 8, !dbg !0