Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -224,6 +224,8 @@ HelpText<"Use register sized accesses to bit-fields, when possible.">; def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">; +def force_tbaa : Flag<["-"], "force-tbaa">, + HelpText<"Force Type Based Alias Analysis">; def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, HelpText<"Turn off struct-path aware Type Based Alias Analysis">; def masm_verbose : Flag<["-"], "masm-verbose">, Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1391,6 +1391,8 @@ HelpText<"Do not emit macro debug information">; def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group, Flags<[DriverOption, CoreOption]>; +def fforce_tbaa : Flag<["-"], "fforce-tbaa">, Group, + Flags<[DriverOption, CoreOption]>; def fstrict_enums : Flag<["-"], "fstrict-enums">, Group, Flags<[CC1Option]>, HelpText<"Enable optimizations based on the strict definition of an enum's " "value range">; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -137,6 +137,7 @@ CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. +CODEGENOPT(ForceTBAA , 1, 0) ///< Set if use of TBAA is forced. CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -129,10 +129,9 @@ if (LangOpts.CUDA) createCUDARuntime(); - // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. - if (LangOpts.Sanitize.has(SanitizerKind::Thread) || - (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) - TBAA.reset(new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(), + // Enable TBAA unless it's suppressed. + if (!CodeGenTBAA::isSuppressed(CodeGenOpts, LangOpts)) + TBAA.reset(new CodeGenTBAA(Context, VMContext, CodeGenOpts, LangOpts, getCXXABI().getMangleContext())); // If debug info or coverage generation is enabled, create the CGDebugInfo Index: lib/CodeGen/CodeGenTBAA.h =================================================================== --- lib/CodeGen/CodeGenTBAA.h +++ lib/CodeGen/CodeGenTBAA.h @@ -116,6 +116,16 @@ /// Get the scalar tag MDNode for a given scalar type. llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode); + + /// Return true if TBAA info shall not be emitted for regular types. + static bool isSuppressedForRegularTypes(const CodeGenOptions &CodeGenOpts); + bool isSuppressedForRegularTypes() const { + return isSuppressedForRegularTypes(CodeGenOpts); + } + + /// Return true if TBAA info shall not be emitted. + static bool isSuppressed(const CodeGenOptions &CodeGenOpts, + const LangOptions &LangOpts); }; } // end namespace CodeGen Index: lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -90,8 +90,7 @@ llvm::MDNode * CodeGenTBAA::getTBAAInfo(QualType QTy) { - // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. - if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) + if(isSuppressedForRegularTypes()) return nullptr; // If the type has the may_alias attribute (even on a typedef), it is @@ -327,3 +326,19 @@ return ScalarTagMetadataCache[AccessNode] = MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); } + +bool +CodeGenTBAA::isSuppressedForRegularTypes(const CodeGenOptions &CodeGenOpts) { + if (CodeGenOpts.ForceTBAA) + return false; + return CodeGenOpts.RelaxedAliasing || CodeGenOpts.OptimizationLevel == 0; +} + +bool CodeGenTBAA::isSuppressed(const CodeGenOptions &CodeGenOpts, + const LangOptions &LangOpts) { + // ThreadSanitizer needs TBAA info for virtual table accesses even at -O0; + // see r155430. + if (LangOpts.Sanitize.has(SanitizerKind::Thread)) + return false; + return isSuppressedForRegularTypes(CodeGenOpts); +} Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -2379,6 +2379,8 @@ // We turn strict aliasing off by default if we're in CL mode, since MSVC // doesn't do any TBAA. bool TBAAOnByDefault = !getToolChain().getDriver().IsCLMode(); + if (Args.hasArg(options::OPT_fforce_tbaa)) + CmdArgs.push_back("-force-tbaa"); if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption, options::OPT_fno_strict_aliasing, TBAAOnByDefault)) CmdArgs.push_back("-relaxed-aliasing"); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -544,6 +544,7 @@ Opts.UseRegisterSizedBitfieldAccess = Args.hasArg( OPT_fuse_register_sized_bitfield_access); Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing); + Opts.ForceTBAA = Args.hasArg(OPT_force_tbaa); Opts.StructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa); Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags); Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants); Index: test/CodeGen/tbaa-for-vptr.cpp =================================================================== --- test/CodeGen/tbaa-for-vptr.cpp +++ test/CodeGen/tbaa-for-vptr.cpp @@ -1,9 +1,10 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -fsanitize=thread %s | FileCheck %s // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O1 %s | FileCheck %s -// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O1 -relaxed-aliasing -fsanitize=thread %s | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O1 -relaxed-aliasing -fsanitize=thread %s | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O1 -relaxed-aliasing -force-tbaa %s | FileCheck %s // // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s --check-prefix=NOTBAA -// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O2 -relaxed-aliasing %s | FileCheck %s --check-prefix=NOTBAA +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O2 -relaxed-aliasing %s | FileCheck %s --check-prefix=NOTBAA // // Check that we generate TBAA for vtable pointer loads and stores. // When -fsanitize=thread is used TBAA should be generated at all opt levels Index: test/CodeGen/tbaa.cpp =================================================================== --- test/CodeGen/tbaa.cpp +++ test/CodeGen/tbaa.cpp @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH // RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes -force-tbaa %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes -force-tbaa %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH // Test TBAA metadata generated by front-end. // // NO-TBAA-NOT: !tbaa Index: test/Driver/force-tbaa.c =================================================================== --- test/Driver/force-tbaa.c +++ test/Driver/force-tbaa.c @@ -0,0 +1,10 @@ +// RUN: %clang -fno-strict-aliasing -fforce-tbaa -### %s 2>&1 | FileCheck -check-prefix=CHECK-WITH-FORCE-TBAA %s +// RUN: %clang -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-WITHOUT-FORCE-TBAA %s + +// CHECK-WITH-FORCE-TBAA: -cc1 +// CHECK-WITH-FORCE-TBAA: -force-tbaa +// CHECK-WITH-FORCE-TBAA: -relaxed-aliasing + +// CHECK-WITHOUT-FORCE-TBAA: -cc1 +// CHECK-WITHOUT-FORCE-TBAA-NOT: -force-tbaa +// CHECK-WITHOUT-FORCE-TBAA: -relaxed-aliasing