diff options
-rw-r--r-- | include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | include/clang/Driver/Options.td | 1 | ||||
-rw-r--r-- | include/clang/Frontend/CodeGenOptions.def | 1 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 42 | ||||
-rw-r--r-- | lib/CodeGen/CGValue.h | 15 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.cpp | 85 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.h | 55 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 1 | ||||
-rw-r--r-- | test/CodeGen/tbaa.cpp | 217 |
13 files changed, 11 insertions, 437 deletions
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index e4dd34509e..ab2d5dc4fb 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -161,8 +161,6 @@ def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfie HelpText<"Use register sized accesses to bit-fields, when possible.">; def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">; -def struct_path_tbaa : Flag<["-"], "struct-path-tbaa">, - HelpText<"Turn on struct-path aware Type Based Alias Analysis">; def masm_verbose : Flag<["-"], "masm-verbose">, HelpText<"Generate verbose assembly output">; def mcode_model : Separate<["-"], "mcode-model">, diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 112feb77b1..dd5062c078 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -587,7 +587,6 @@ def fno_spell_checking : Flag<["-"], "fno-spell-checking">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable spell-checking">; def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>; def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>; -def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>; def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>; def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>; def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>, diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 1c0b9fa99e..4b6754d5dc 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -86,7 +86,6 @@ VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified. VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified. CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. -CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero ///< offset in AddressSanitizer. diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 2f5186d1f4..9bfaacbbd6 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1044,8 +1044,7 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) { llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) { return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), lvalue.getAlignment().getQuantity(), - lvalue.getType(), lvalue.getTBAAInfo(), - lvalue.getTBAABaseType(), lvalue.getTBAAOffset()); + lvalue.getType(), lvalue.getTBAAInfo()); } static bool hasBooleanRepresentation(QualType Ty) { @@ -1107,9 +1106,7 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo, - QualType TBAABaseType, - uint64_t TBAAOffset) { + llvm::MDNode *TBAAInfo) { // For better performance, handle vector loads differently. if (Ty->isVectorType()) { llvm::Value *V; @@ -1161,11 +1158,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, Load->setVolatile(true); if (Alignment) Load->setAlignment(Alignment); - if (TBAAInfo) { - llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, - TBAAOffset); - CGM.DecorateInstruction(Load, TBAAPath); - } + if (TBAAInfo) + CGM.DecorateInstruction(Load, TBAAInfo); if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) || (SanOpts->Enum && Ty->getAs<EnumType>())) { @@ -1223,8 +1217,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo, - bool isInit, QualType TBAABaseType, - uint64_t TBAAOffset) { + bool isInit) { // Handle vectors differently to get better performance. if (Ty->isVectorType()) { @@ -1275,19 +1268,15 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile); if (Alignment) Store->setAlignment(Alignment); - if (TBAAInfo) { - llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, - TBAAOffset); - CGM.DecorateInstruction(Store, TBAAPath); - } + if (TBAAInfo) + CGM.DecorateInstruction(Store, TBAAInfo); } void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit) { EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), lvalue.getAlignment().getQuantity(), lvalue.getType(), - lvalue.getTBAAInfo(), isInit, lvalue.getTBAABaseType(), - lvalue.getTBAAOffset()); + lvalue.getTBAAInfo(), isInit); } /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this @@ -2505,12 +2494,9 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, llvm::Value *addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); - bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; if (rec->isUnion()) { // For unions, there is no pointer adjustment. assert(!type->isReferenceType() && "union has reference member"); - // TODO: handle path-aware TBAA for union. - TBAAPath = false; } else { // For structs, we GEP to the field that the record layout suggests. unsigned idx = CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field); @@ -2522,8 +2508,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, if (cvr & Qualifiers::Volatile) load->setVolatile(true); load->setAlignment(alignment.getQuantity()); - // Loading the reference will disable path-aware TBAA. - TBAAPath = false; if (CGM.shouldUseTBAA()) { llvm::MDNode *tbaa; if (mayAlias) @@ -2557,16 +2541,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, LValue LV = MakeAddrLValue(addr, type, alignment); LV.getQuals().addCVRQualifiers(cvr); - if (TBAAPath) { - const ASTRecordLayout &Layout = - getContext().getASTRecordLayout(field->getParent()); - // Set the base type to be the base type of the base LValue and - // update offset to be relative to the base type. - LV.setTBAABaseType(base.getTBAABaseType()); - LV.setTBAAOffset(base.getTBAAOffset() + - Layout.getFieldOffset(field->getFieldIndex()) / - getContext().getCharWidth()); - } // __weak attribute on a field is ignored. if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak) diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index b625b866c0..0657fdca36 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -157,11 +157,6 @@ class LValue { Expr *BaseIvarExp; - /// Used by struct-path-aware TBAA. - QualType TBAABaseType; - /// Offset relative to the base type. - uint64_t TBAAOffset; - /// TBAAInfo - TBAA information to attach to dereferences of this LValue. llvm::MDNode *TBAAInfo; @@ -180,10 +175,6 @@ private: this->ImpreciseLifetime = false; this->ThreadLocalRef = false; this->BaseIvarExp = 0; - - // Initialize fields for TBAA. - this->TBAABaseType = Type; - this->TBAAOffset = 0; this->TBAAInfo = TBAAInfo; } @@ -241,12 +232,6 @@ public: Expr *getBaseIvarExp() const { return BaseIvarExp; } void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } - QualType getTBAABaseType() const { return TBAABaseType; } - void setTBAABaseType(QualType T) { TBAABaseType = T; } - - uint64_t getTBAAOffset() const { return TBAAOffset; } - void setTBAAOffset(uint64_t O) { TBAAOffset = O; } - llvm::MDNode *getTBAAInfo() const { return TBAAInfo; } void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 645d5ff237..f76022fb97 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2211,9 +2211,7 @@ public: /// the LLVM value representation. llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo = 0, - QualType TBAABaseTy = QualType(), - uint64_t TBAAOffset = 0); + llvm::MDNode *TBAAInfo = 0); /// EmitLoadOfScalar - Load a scalar value from an address, taking /// care to appropriately convert from the memory representation to @@ -2226,9 +2224,7 @@ public: /// the LLVM value representation. void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo = 0, bool isInit = false, - QualType TBAABaseTy = QualType(), - uint64_t TBAAOffset = 0); + llvm::MDNode *TBAAInfo = 0, bool isInit=false); /// EmitStoreOfScalar - Store a scalar value to an address, taking /// care to appropriately convert from the memory representation to diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index c518a5554e..6d85a8835b 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -227,20 +227,6 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { return TBAA->getTBAAStructInfo(QTy); } -llvm::MDNode *CodeGenModule::getTBAAStructTypeInfo(QualType QTy) { - if (!TBAA) - return 0; - return TBAA->getTBAAStructTypeInfo(QTy); -} - -llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy, - llvm::MDNode *AccessN, - uint64_t O) { - if (!TBAA) - return 0; - return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O); -} - void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, llvm::MDNode *TBAAInfo) { Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 5b2153e5ff..fcd48302ae 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -501,11 +501,6 @@ public: llvm::MDNode *getTBAAInfo(QualType QTy); llvm::MDNode *getTBAAInfoForVTablePtr(); llvm::MDNode *getTBAAStructInfo(QualType QTy); - /// Return the MDNode in the type DAG for the given struct type. - llvm::MDNode *getTBAAStructTypeInfo(QualType QTy); - /// Return the path-aware tag for given base type, access node and offset. - llvm::MDNode *getTBAAStructTagInfo(QualType BaseTy, llvm::MDNode *AccessN, - uint64_t O); bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index 7e4d34ab89..cfa141ea9a 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -21,7 +21,6 @@ #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" #include "clang/Frontend/CodeGenOptions.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -226,87 +225,3 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) { // For now, handle any other kind of type conservatively. return StructMetadataCache[Ty] = NULL; } - -/// Check if the given type can be handled by path-aware TBAA. -static bool isTBAAPathStruct(QualType QTy) { - if (const RecordType *TTy = QTy->getAs<RecordType>()) { - const RecordDecl *RD = TTy->getDecl()->getDefinition(); - // RD can be struct, union, class, interface or enum. - // For now, we only handle struct. - if (RD->isStruct() && !RD->hasFlexibleArrayMember()) - return true; - } - return false; -} - -llvm::MDNode * -CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { - const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); - assert(isTBAAPathStruct(QTy)); - - if (llvm::MDNode *N = StructTypeMetadataCache[Ty]) - return N; - - if (const RecordType *TTy = QTy->getAs<RecordType>()) { - const RecordDecl *RD = TTy->getDecl()->getDefinition(); - - const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - SmallVector <std::pair<uint64_t, llvm::MDNode*>, 4> Fields; - // To reduce the size of MDNode for a given struct type, we only output - // once for all the fields with the same scalar types. - // Offsets for scalar fields in the type DAG are not used. - llvm::SmallSet <llvm::MDNode*, 4> ScalarFieldTypes; - unsigned idx = 0; - for (RecordDecl::field_iterator i = RD->field_begin(), - e = RD->field_end(); i != e; ++i, ++idx) { - QualType FieldQTy = i->getType(); - llvm::MDNode *FieldNode; - if (isTBAAPathStruct(FieldQTy)) - FieldNode = getTBAAStructTypeInfo(FieldQTy); - else { - FieldNode = getTBAAInfo(FieldQTy); - // Ignore this field if the type already exists. - if (ScalarFieldTypes.count(FieldNode)) - continue; - ScalarFieldTypes.insert(FieldNode); - } - if (!FieldNode) - return StructTypeMetadataCache[Ty] = NULL; - Fields.push_back(std::make_pair( - Layout.getFieldOffset(idx) / Context.getCharWidth(), FieldNode)); - } - - // TODO: This is using the RTTI name. Is there a better way to get - // a unique string for a type? - SmallString<256> OutName; - llvm::raw_svector_ostream Out(OutName); - MContext.mangleCXXRTTIName(QualType(Ty, 0), Out); - Out.flush(); - // Create the struct type node with a vector of pairs (offset, type). - return StructTypeMetadataCache[Ty] = - MDHelper.createTBAAStructTypeNode(OutName, Fields); - } - - return StructMetadataCache[Ty] = NULL; -} - -llvm::MDNode * -CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode, - uint64_t Offset) { - if (!CodeGenOpts.StructPathTBAA) - return AccessNode; - - const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr(); - TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset); - if (llvm::MDNode *N = StructTagMetadataCache[PathTag]) - return N; - - llvm::MDNode *BNode = 0; - if (isTBAAPathStruct(BaseQTy)) - BNode = getTBAAStructTypeInfo(BaseQTy); - if (!BNode) - return StructTagMetadataCache[PathTag] = AccessNode; - - return StructTagMetadataCache[PathTag] = - MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset); -} diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h index 9ddc3aa970..4c6e045fce 100644 --- a/lib/CodeGen/CodeGenTBAA.h +++ b/lib/CodeGen/CodeGenTBAA.h @@ -35,14 +35,6 @@ namespace clang { namespace CodeGen { class CGRecordLayout; - struct TBAAPathTag { - TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O) - : BaseT(B), AccessN(A), Offset(O) {} - const Type *BaseT; - const llvm::MDNode *AccessN; - uint64_t Offset; - }; - /// CodeGenTBAA - This class organizes the cross-module state that is used /// while lowering AST types to LLVM types. class CodeGenTBAA { @@ -54,13 +46,8 @@ class CodeGenTBAA { // MDHelper - Helper for creating metadata. llvm::MDBuilder MDHelper; - /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing - /// them. + /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them. llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; - /// This maps clang::Types to a struct node in the type DAG. - llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache; - /// This maps TBAAPathTags to a tag node. - llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache; /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing /// them for struct assignments. @@ -102,49 +89,9 @@ public: /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of /// the given type. llvm::MDNode *getTBAAStructInfo(QualType QTy); - - /// Get the MDNode in the type DAG for given struct type QType. - llvm::MDNode *getTBAAStructTypeInfo(QualType QType); - /// Get the tag MDNode for a given base type, the actual sclar access MDNode - /// and offset into the base type. - llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType, - llvm::MDNode *AccessNode, uint64_t Offset); }; } // end namespace CodeGen } // end namespace clang -namespace llvm { - -template<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> { - static clang::CodeGen::TBAAPathTag getEmptyKey() { - return clang::CodeGen::TBAAPathTag( - DenseMapInfo<const clang::Type *>::getEmptyKey(), - DenseMapInfo<const MDNode *>::getEmptyKey(), - DenseMapInfo<uint64_t>::getEmptyKey()); - } - - static clang::CodeGen::TBAAPathTag getTombstoneKey() { - return clang::CodeGen::TBAAPathTag( - DenseMapInfo<const clang::Type *>::getTombstoneKey(), - DenseMapInfo<const MDNode *>::getTombstoneKey(), - DenseMapInfo<uint64_t>::getTombstoneKey()); - } - - static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) { - return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^ - DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^ - DenseMapInfo<uint64_t>::getHashValue(Val.Offset); - } - - static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS, - const clang::CodeGen::TBAAPathTag &RHS) { - return LHS.BaseT == RHS.BaseT && - LHS.AccessN == RHS.AccessN && - LHS.Offset == RHS.Offset; - } -}; - -} // end namespace llvm - #endif diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 77a72ba33a..83c140d2b3 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2105,8 +2105,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_strict_aliasing, getToolChain().IsStrictAliasingDefault())) CmdArgs.push_back("-relaxed-aliasing"); - if (Args.hasArg(options::OPT_fstruct_path_tbaa)) - CmdArgs.push_back("-struct-path-tbaa"); if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums, false)) CmdArgs.push_back("-fstrict-enums"); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 41f941729a..611e784814 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -324,7 +324,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.UseRegisterSizedBitfieldAccess = Args.hasArg( OPT_fuse_register_sized_bitfield_access); Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing); - Opts.StructPathTBAA = Args.hasArg(OPT_struct_path_tbaa); Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags); Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants); Opts.NoCommon = Args.hasArg(OPT_fno_common); diff --git a/test/CodeGen/tbaa.cpp b/test/CodeGen/tbaa.cpp deleted file mode 100644 index c30e4a331d..0000000000 --- a/test/CodeGen/tbaa.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// RUN: %clang_cc1 -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH -// Test TBAA metadata generated by front-end. - -#include <stdint.h> -typedef struct -{ - uint16_t f16; - uint32_t f32; - uint16_t f16_2; - uint32_t f32_2; -} StructA; -typedef struct -{ - uint16_t f16; - StructA a; - uint32_t f32; -} StructB; -typedef struct -{ - uint16_t f16; - StructB b; - uint32_t f32; -} StructC; -typedef struct -{ - uint16_t f16; - StructB b; - uint32_t f32; - uint8_t f8; -} StructD; - -typedef struct -{ - uint16_t f16; - uint32_t f32; -} StructS; -typedef struct -{ - uint16_t f16; - uint32_t f32; -} StructS2; - -uint32_t g(uint32_t *s, StructA *A, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !5 - *s = 1; - A->f32 = 4; - return *s; -} - -uint32_t g2(uint32_t *s, StructA *A, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !8 - *s = 1; - A->f16 = 4; - return *s; -} - -uint32_t g3(StructA *A, StructB *B, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9 - A->f32 = 1; - B->a.f32 = 4; - return A->f32; -} - -uint32_t g4(StructA *A, StructB *B, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !11 - A->f32 = 1; - B->a.f16 = 4; - return A->f32; -} - -uint32_t g5(StructA *A, StructB *B, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !12 - A->f32 = 1; - B->f32 = 4; - return A->f32; -} - -uint32_t g6(StructA *A, StructB *B, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !13 - A->f32 = 1; - B->a.f32_2 = 4; - return A->f32; -} - -uint32_t g7(StructA *A, StructS *S, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !14 - A->f32 = 1; - S->f32 = 4; - return A->f32; -} - -uint32_t g8(StructA *A, StructS *S, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !16 - A->f32 = 1; - S->f16 = 4; - return A->f32; -} - -uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !17 - S->f32 = 1; - S2->f32 = 4; - return S->f32; -} - -uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14 -// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !19 - S->f32 = 1; - S2->f16 = 4; - return S->f32; -} - -uint32_t g11(StructC *C, StructD *D, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !20 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !22 - C->b.a.f32 = 1; - D->b.a.f32 = 4; - return C->b.a.f32; -} - -uint32_t g12(StructC *C, StructD *D, uint64_t count) { -// CHECK: define i32 @{{.*}}( -// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 -// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 -// TODO: differentiate the two accesses. -// PATH: define i32 @{{.*}}( -// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !9 -// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9 - StructB *b1 = &(C->b); - StructB *b2 = &(D->b); - // b1, b2 have different context. - b1->a.f32 = 1; - b2->a.f32 = 4; - return b1->a.f32; -} - -// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2} -// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"} -// CHECK: !4 = metadata !{metadata !"int", metadata !1} -// CHECK: !5 = metadata !{metadata !"short", metadata !1} - -// PATH: !1 = metadata !{metadata !"omnipotent char", metadata !2} -// PATH: !4 = metadata !{metadata !"int", metadata !1} -// PATH: !5 = metadata !{metadata !6, metadata !4, i64 4} -// PATH: !6 = metadata !{metadata !"_ZTS7StructA", i64 0, metadata !7, i64 4, metadata !4} -// PATH: !7 = metadata !{metadata !"short", metadata !1} -// PATH: !8 = metadata !{metadata !6, metadata !7, i64 0} -// PATH: !9 = metadata !{metadata !10, metadata !4, i64 8} -// PATH: !10 = metadata !{metadata !"_ZTS7StructB", i64 0, metadata !7, i64 4, metadata !6, i64 20, metadata !4} -// PATH: !11 = metadata !{metadata !10, metadata !7, i64 4} -// PATH: !12 = metadata !{metadata !10, metadata !4, i64 20} -// PATH: !13 = metadata !{metadata !10, metadata !4, i64 16} -// PATH: !14 = metadata !{metadata !15, metadata !4, i64 4} -// PATH: !15 = metadata !{metadata !"_ZTS7StructS", i64 0, metadata !7, i64 4, metadata !4} -// PATH: !16 = metadata !{metadata !15, metadata !7, i64 0} -// PATH: !17 = metadata !{metadata !18, metadata !4, i64 4} -// PATH: !18 = metadata !{metadata !"_ZTS8StructS2", i64 0, metadata !7, i64 4, metadata !4} -// PATH: !19 = metadata !{metadata !18, metadata !7, i64 0} -// PATH: !20 = metadata !{metadata !21, metadata !4, i64 12} -// PATH: !21 = metadata !{metadata !"_ZTS7StructC", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4} -// PATH: !22 = metadata !{metadata !23, metadata !4, i64 12} -// PATH: !23 = metadata !{metadata !"_ZTS7StructD", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4, i64 32, metadata !1} |