[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-05-01 Thread Evgenii Stepanov via Phabricator via cfe-commits
eugenis closed this revision.
eugenis added a comment.

r301225


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-21 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc accepted this revision.
pcc added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-21 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis added a comment.

PTAL


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-21 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis updated this revision to Diff 96263.

Repository:
  rL LLVM

https://reviews.llvm.org/D32064

Files:
  lib/CodeGen/BackendUtil.cpp
  test/CodeGen/asan-globals-gc.cpp


Index: test/CodeGen/asan-globals-gc.cpp
===
--- /dev/null
+++ test/CodeGen/asan-globals-gc.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple 
x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple 
x86_64-windows-msvc -fdata-sections %s | FileCheck %s --check-prefix=WITH-GC
+
+int global;
+
+// WITH-GC-NOT: call void @__asan_register_globals
+// WITHOUT-GC: call void @__asan_register_globals
Index: lib/CodeGen/BackendUtil.cpp
===
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -129,16 +129,20 @@
 // that we add to the PassManagerBuilder.
 class PassManagerBuilderWrapper : public PassManagerBuilder {
 public:
-  PassManagerBuilderWrapper(const CodeGenOptions ,
+  PassManagerBuilderWrapper(const Triple ,
+const CodeGenOptions ,
 const LangOptions )
-  : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {}
+  : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts),
+LangOpts(LangOpts) {}
+  const Triple () const { return TargetTriple; }
   const CodeGenOptions () const { return CGOpts; }
   const LangOptions () const { return LangOpts; }
+
 private:
+  const Triple 
   const CodeGenOptions 
   const LangOptions 
 };
-
 }
 
 static void addObjCARCAPElimPass(const PassManagerBuilder , 
PassManagerBase ) {
@@ -185,16 +189,36 @@
   PM.add(createSanitizerCoverageModulePass(Opts));
 }
 
+// Check if ASan should use GC-friendly instrumentation for globals.
+// First of all, there is no point if -fdata-sections is off (expect for MachO,
+// where this is not a factor). Also, on ELF this feature requires an assembler
+// extension that only works with -integrated-as at the moment.
+static bool asanUseGlobalsGC(const Triple , const CodeGenOptions ) {
+  switch (T.getObjectFormat()) {
+  case Triple::MachO:
+return true;
+  case Triple::COFF:
+return CGOpts.DataSections;
+  case Triple::ELF:
+return CGOpts.DataSections && !CGOpts.DisableIntegratedAS;
+  default:
+return false;
+  }
+}
+
 static void addAddressSanitizerPasses(const PassManagerBuilder ,
   legacy::PassManagerBase ) {
   const PassManagerBuilderWrapper  =
   static_cast(Builder);
+  const Triple  = BuilderWrapper.getTargetTriple();
   const CodeGenOptions  = BuilderWrapper.getCGOpts();
   bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address);
   bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope;
+  bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts);
   PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover,
 UseAfterScope));
-  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/false, Recover));
+  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/ false, Recover,
+  UseGlobalsGC));
 }
 
 static void addKernelAddressSanitizerPasses(const PassManagerBuilder ,
@@ -434,16 +458,16 @@
   if (CodeGenOpts.DisableLLVMPasses)
 return;
 
-  PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
-
   // Figure out TargetLibraryInfo.  This needs to be added to MPM and FPM
   // manually (and not via PMBuilder), since some passes (eg. InstrProfiling)
   // are inserted before PMBuilder ones - they'd get the default-constructed
   // TLI with an unknown target otherwise.
   Triple TargetTriple(TheModule->getTargetTriple());
   std::unique_ptr TLII(
   createTLII(TargetTriple, CodeGenOpts));
 
+  PassManagerBuilderWrapper PMBuilder(TargetTriple, CodeGenOpts, LangOpts);
+
   // At O0 and O1 we only run the always inliner which is more efficient. At
   // higher optimization levels we run the normal inliner.
   if (CodeGenOpts.OptimizationLevel <= 1) {


Index: test/CodeGen/asan-globals-gc.cpp
===
--- /dev/null
+++ test/CodeGen/asan-globals-gc.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc -fdata-sections %s | FileCheck %s --check-prefix=WITH-GC
+
+int global;
+
+// WITH-GC-NOT: call void @__asan_register_globals
+// WITHOUT-GC: call void @__asan_register_globals
Index: lib/CodeGen/BackendUtil.cpp
===
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -129,16 +129,20 @@
 // that we add to the PassManagerBuilder.
 class PassManagerBuilderWrapper 

[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-21 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc added a comment.

I think the only functional change here is for COFF, so you can add a CodeGen 
test that checks that metadata globals are created only if `-fdata-sections` is 
passed.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-21 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis added a comment.

what kind of test?


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-21 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc added a comment.

Please add a test case.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-21 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis updated this revision to Diff 96227.
eugenis added a comment.

Reverted back to using pass constructor argument.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064

Files:
  lib/CodeGen/BackendUtil.cpp


Index: lib/CodeGen/BackendUtil.cpp
===
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -129,16 +129,20 @@
 // that we add to the PassManagerBuilder.
 class PassManagerBuilderWrapper : public PassManagerBuilder {
 public:
-  PassManagerBuilderWrapper(const CodeGenOptions ,
+  PassManagerBuilderWrapper(const Triple ,
+const CodeGenOptions ,
 const LangOptions )
-  : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {}
+  : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts),
+LangOpts(LangOpts) {}
+  const Triple () const { return TargetTriple; }
   const CodeGenOptions () const { return CGOpts; }
   const LangOptions () const { return LangOpts; }
+
 private:
+  const Triple 
   const CodeGenOptions 
   const LangOptions 
 };
-
 }
 
 static void addObjCARCAPElimPass(const PassManagerBuilder , 
PassManagerBase ) {
@@ -185,16 +189,36 @@
   PM.add(createSanitizerCoverageModulePass(Opts));
 }
 
+// Check if ASan should use GC-friendly instrumentation for globals.
+// First of all, there is no point if -fdata-sections is off (expect for MachO,
+// where this is not a factor). Also, on ELF this feature requires an assembler
+// extension that only works with -integrated-as at the moment.
+static bool asanUseGlobalsGC(const Triple , const CodeGenOptions ) {
+  switch (T.getObjectFormat()) {
+  case Triple::MachO:
+return true;
+  case Triple::COFF:
+return CGOpts.DataSections;
+  case Triple::ELF:
+return CGOpts.DataSections && !CGOpts.DisableIntegratedAS;
+  default:
+return false;
+  }
+}
+
 static void addAddressSanitizerPasses(const PassManagerBuilder ,
   legacy::PassManagerBase ) {
   const PassManagerBuilderWrapper  =
   static_cast(Builder);
+  const Triple  = BuilderWrapper.getTargetTriple();
   const CodeGenOptions  = BuilderWrapper.getCGOpts();
   bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address);
   bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope;
+  bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts);
   PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover,
 UseAfterScope));
-  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/false, Recover));
+  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/ false, Recover,
+  UseGlobalsGC));
 }
 
 static void addKernelAddressSanitizerPasses(const PassManagerBuilder ,
@@ -434,16 +458,16 @@
   if (CodeGenOpts.DisableLLVMPasses)
 return;
 
-  PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
-
   // Figure out TargetLibraryInfo.  This needs to be added to MPM and FPM
   // manually (and not via PMBuilder), since some passes (eg. InstrProfiling)
   // are inserted before PMBuilder ones - they'd get the default-constructed
   // TLI with an unknown target otherwise.
   Triple TargetTriple(TheModule->getTargetTriple());
   std::unique_ptr TLII(
   createTLII(TargetTriple, CodeGenOpts));
 
+  PassManagerBuilderWrapper PMBuilder(TargetTriple, CodeGenOpts, LangOpts);
+
   // At O0 and O1 we only run the always inliner which is more efficient. At
   // higher optimization levels we run the normal inliner.
   if (CodeGenOpts.OptimizationLevel <= 1) {


Index: lib/CodeGen/BackendUtil.cpp
===
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -129,16 +129,20 @@
 // that we add to the PassManagerBuilder.
 class PassManagerBuilderWrapper : public PassManagerBuilder {
 public:
-  PassManagerBuilderWrapper(const CodeGenOptions ,
+  PassManagerBuilderWrapper(const Triple ,
+const CodeGenOptions ,
 const LangOptions )
-  : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {}
+  : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts),
+LangOpts(LangOpts) {}
+  const Triple () const { return TargetTriple; }
   const CodeGenOptions () const { return CGOpts; }
   const LangOptions () const { return LangOpts; }
+
 private:
+  const Triple 
   const CodeGenOptions 
   const LangOptions 
 };
-
 }
 
 static void addObjCARCAPElimPass(const PassManagerBuilder , PassManagerBase ) {
@@ -185,16 +189,36 @@
   PM.add(createSanitizerCoverageModulePass(Opts));
 }
 
+// Check if ASan should use GC-friendly instrumentation for globals.
+// First of all, there is no point if -fdata-sections is off (expect for MachO,
+// where this is not a factor). Also, on ELF this feature requires an assembler
+// extension that only works with 

[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-19 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc added a comment.

I won't stand in the way here if others feel strongly that the flag should be 
passed via a constructor. It will just mean more work to be done if/when this 
flag is ever changed to be passed via some other mechanism, but that's a 
relatively minor detail.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-19 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis added a comment.

The ultimate solution would be a function attribute - if we want this thing to 
work correctly with LTO. But it sounds a bit like overkill, plus none of the 
settings it depends on (integrated-as, data-sections) work with LTO anway: the 
former is ignored and the second does not make sense.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-19 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a subscriber: chandlerc.
rnk added a comment.

In https://reviews.llvm.org/D32064#728683, @pcc wrote:

> In https://reviews.llvm.org/D32064#728629, @rnk wrote:
>
> > In https://reviews.llvm.org/D32064#726861, @pcc wrote:
> >
> > > I think it would be better to move this logic to the driver and have it 
> > > pass in an `-mllvm` flag. The sanitizer passes should really be taking no 
> > > arguments in the constructor like the other passes, so I don't want us to 
> > > add another argument here.
> >
> >
> > That seems like the opposite of the direction we've been moving, though. 
> > cl::opt flags can't appear twice, and this means one process can't do two 
> > asan compilations in two LLVMContexts in parallel with different settings.
>
>
> Yes, but adding an argument is also the wrong direction. This information 
> should really be passed either via the module (e.g. module flags or 
> attributes) or the TargetMachine. If we aren't going to do that, we might as 
> well pass it via `-mllvm`, as it is simpler.


I'm really just echoing what I thought was conventional wisdom. I think 
avoiding new `cl::opt`s is something that @chandlerc cares more about. It's 
been said on llvm-dev that `cl::opt` should mostly be for debugging. We should 
be able to ship a production compiler that effectively compiles every cl::opt 
to its default value.

I don't see why constructor parameters are the wrong direction. It's already 
how ASan instrumentation takes every other global pass option. Only tsan uses 
-mllvm flags created by clang. If we aren't going to make ASan consistent, we 
should standardize on what we already have.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-18 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis added a comment.

Ping.
I don't really have a preference.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc added a comment.

In https://reviews.llvm.org/D32064#728629, @rnk wrote:

> In https://reviews.llvm.org/D32064#726861, @pcc wrote:
>
> > I think it would be better to move this logic to the driver and have it 
> > pass in an `-mllvm` flag. The sanitizer passes should really be taking no 
> > arguments in the constructor like the other passes, so I don't want us to 
> > add another argument here.
>
>
> That seems like the opposite of the direction we've been moving, though. 
> cl::opt flags can't appear twice, and this means one process can't do two 
> asan compilations in two LLVMContexts in parallel with different settings.


Yes, but adding an argument is also the wrong direction. This information 
should really be passed either via the module (e.g. module flags or attributes) 
or the TargetMachine. If we aren't going to do that, we might as well pass it 
via `-mllvm`, as it is simpler.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: lib/Driver/SanitizerArgs.cpp:636
+  case llvm::Triple::COFF:
+return DataSections;
+  case llvm::Triple::ELF:

eugenis wrote:
> rnk wrote:
> > We can return true for COFF here. By adding a comdat during asan 
> > instrumentation, we effectively implement -fdata-sections ourselves. If the 
> > user really wanted -fno-data-sections for some reason, they're out of luck 
> > right now.
> What do you mean by "out of luck", will it break compilation?
> Because the point of this change is not to enable data-sections unless asked 
> by the user. Data sections greatly inflate ELF object file size (not sure how 
> big is the effect on COFF) and we should not do that by default.
By "out of luck", I was thinking about users who might do crazy things like 
take label differences between globals and assume that they are laid out 
consecutively in the original source file order. I wasn't thinking about object 
file size.

The size increase for COFF is probably comparable, so I guess I agree, this is 
reasonable behavior. I think Chromium explicitly passes `/Gw`, which is 
equivalent to `-fdata-sections`. We basically don't support non-integrated as 
on Windows at this point. We've extended the assembler a number of times 
already.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis added inline comments.



Comment at: lib/Driver/SanitizerArgs.cpp:636
+  case llvm::Triple::COFF:
+return DataSections;
+  case llvm::Triple::ELF:

rnk wrote:
> We can return true for COFF here. By adding a comdat during asan 
> instrumentation, we effectively implement -fdata-sections ourselves. If the 
> user really wanted -fno-data-sections for some reason, they're out of luck 
> right now.
What do you mean by "out of luck", will it break compilation?
Because the point of this change is not to enable data-sections unless asked by 
the user. Data sections greatly inflate ELF object file size (not sure how big 
is the effect on COFF) and we should not do that by default.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

In https://reviews.llvm.org/D32064#726861, @pcc wrote:

> I think it would be better to move this logic to the driver and have it pass 
> in an `-mllvm` flag. The sanitizer passes should really be taking no 
> arguments in the constructor like the other passes, so I don't want us to add 
> another argument here.


That seems like the opposite of the direction we've been moving, though. 
cl::opt flags can't appear twice, and this means one process can't do two asan 
compilations in two LLVMContexts in parallel with different settings.




Comment at: lib/Driver/SanitizerArgs.cpp:636
+  case llvm::Triple::COFF:
+return DataSections;
+  case llvm::Triple::ELF:

We can return true for COFF here. By adding a comdat during asan 
instrumentation, we effectively implement -fdata-sections ourselves. If the 
user really wanted -fno-data-sections for some reason, they're out of luck 
right now.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-13 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis updated this revision to Diff 95254.
eugenis retitled this revision from "[asan] Disable ASan global-GC depending on 
the target and CGOpts" to "[asan] Disable ASan global-GC depending on the 
target and compiler flags".

Repository:
  rL LLVM

https://reviews.llvm.org/D32064

Files:
  lib/Driver/SanitizerArgs.cpp
  test/Driver/asan-gc.c


Index: test/Driver/asan-gc.c
===
--- /dev/null
+++ test/Driver/asan-gc.c
@@ -0,0 +1,14 @@
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | 
FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fdata-sections %s 
-### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-data-sections 
-fdata-sections %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-integrated-as 
-fdata-sections %s -### 2>&1 | FileCheck %s --check-prefix=WITHOUT-GC
+
+// RUN: %clang -target x86_64-apple-macosx10.11.0 -fsanitize=address %s -### 
2>&1 | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang -target x86_64-apple-macosx10.11.0 -fsanitize=address 
-fno-integrated-as %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+
+// RUN: %clang -target x86_64-pc-windows-msvc19.0.24215 -fsanitize=address %s 
-### 2>&1 | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang -target x86_64-pc-windows-msvc19.0.24215 -fsanitize=address 
-fdata-sections %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+
+
+// WITHOUT-GC: "-mllvm" "-asan-globals-live-support=0"
+// WITH-GC-NOT: -asan-globals-live-support=0
Index: lib/Driver/SanitizerArgs.cpp
===
--- lib/Driver/SanitizerArgs.cpp
+++ lib/Driver/SanitizerArgs.cpp
@@ -618,6 +618,29 @@
   CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
 }
 
+// Check if ASan should use GC-friendly instrumentation for globals.
+// First of all, there is no point if -fdata-sections is off (expect for MachO,
+// where this is not a factor). Also, on ELF this feature requires an assembler
+// extension that only works with -integrated-as at the moment.
+static bool useAsanGlobalsGC(const ToolChain ,
+ const llvm::opt::ArgList ) {
+  bool IntegratedAs = TC.useIntegratedAs();
+  bool DataSections =
+  Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
+   tools::isUseSeparateSections(TC.getTriple()));
+
+  switch (TC.getTriple().getObjectFormat()) {
+  case llvm::Triple::MachO:
+return true;
+  case llvm::Triple::COFF:
+return DataSections;
+  case llvm::Triple::ELF:
+return DataSections && IntegratedAs;
+  default:
+return false;
+  }
+}
+
 void SanitizerArgs::addArgs(const ToolChain , const llvm::opt::ArgList 
,
 llvm::opt::ArgStringList ,
 types::ID InputType) const {
@@ -745,6 +768,11 @@
Sanitizers.Mask & CFIClasses)
 << "-fvisibility=";
   }
+
+  if (Sanitizers.has(Address) && !useAsanGlobalsGC(TC, Args)) {
+CmdArgs.push_back("-mllvm");
+CmdArgs.push_back("-asan-globals-live-support=0");
+  }
 }
 
 SanitizerMask parseArgValues(const Driver , const llvm::opt::Arg *A,


Index: test/Driver/asan-gc.c
===
--- /dev/null
+++ test/Driver/asan-gc.c
@@ -0,0 +1,14 @@
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fdata-sections %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-data-sections -fdata-sections %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-integrated-as -fdata-sections %s -### 2>&1 | FileCheck %s --check-prefix=WITHOUT-GC
+
+// RUN: %clang -target x86_64-apple-macosx10.11.0 -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang -target x86_64-apple-macosx10.11.0 -fsanitize=address -fno-integrated-as %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+
+// RUN: %clang -target x86_64-pc-windows-msvc19.0.24215 -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang -target x86_64-pc-windows-msvc19.0.24215 -fsanitize=address -fdata-sections %s -### 2>&1 | FileCheck %s --check-prefix=WITH-GC
+
+
+// WITHOUT-GC: "-mllvm" "-asan-globals-live-support=0"
+// WITH-GC-NOT: -asan-globals-live-support=0
Index: lib/Driver/SanitizerArgs.cpp
===
--- lib/Driver/SanitizerArgs.cpp
+++ lib/Driver/SanitizerArgs.cpp
@@ -618,6 +618,29 @@
   CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
 }
 
+// Check if ASan should use