From 709e015cf170dd056806001b22f7da2c3e9154a7 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 15 Nov 2012 11:40:00 +0000 Subject: Make GlobalOpt be conservative with TLS variables (PR14309) For global variables that get the same value stored into them everywhere, GlobalOpt will replace them with a constant. The problem is that a thread-local GlobalVariable looks like one value (the address of the TLS var), but is different between threads. This patch introduces Constant::isThreadDependent() which returns true for thread-local variables and constants which depend on them (e.g. a GEP into a thread-local array), and teaches GlobalOpt not to track such values. llvm-svn: 168037 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'llvm/lib/Transforms') diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 678189b3d6c..591278fa62c 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -225,6 +225,7 @@ static bool AnalyzeGlobal(const Value *V, GlobalStatus &GS, // Don't hack on volatile stores. if (SI->isVolatile()) return true; + GS.Ordering = StrongerOrdering(GS.Ordering, SI->getOrdering()); // If this is a direct store to the global (i.e., the global is a scalar @@ -234,6 +235,14 @@ static bool AnalyzeGlobal(const Value *V, GlobalStatus &GS, if (const GlobalVariable *GV = dyn_cast( SI->getOperand(1))) { Value *StoredVal = SI->getOperand(0); + + if (Constant *C = dyn_cast(StoredVal)) { + if (C->isThreadDependent()) { + // The stored value changes between threads; don't track it. + return true; + } + } + if (StoredVal == GV->getInitializer()) { if (GS.StoredType < GlobalStatus::isInitializerStored) GS.StoredType = GlobalStatus::isInitializerStored; -- cgit v1.2.3