Declares __cpu_model as dso local
authorHaibo Huang <hhb@google.com>
Wed, 12 Dec 2018 22:04:12 +0000 (22:04 +0000)
committerHaibo Huang <hhb@google.com>
Wed, 12 Dec 2018 22:04:12 +0000 (22:04 +0000)
__builtin_cpu_supports and __builtin_cpu_is use information in __cpu_model to decide cpu features. Before this change, __cpu_model was not declared as dso local. The generated code looks up the address in GOT when reading __cpu_model. This makes it impossible to use these functions in ifunc, because at that time GOT entries have not been relocated. This change makes it dso local.

Differential Revision: https://reviews.llvm.org/D53850

llvm-svn: 348978

clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/builtin-cpu-is.c
clang/test/CodeGen/builtin-cpu-supports.c

index e587d04..a0a5c28 100644 (file)
@@ -9465,6 +9465,7 @@ Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
 
   // Grab the global __cpu_model.
   llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
+  cast<llvm::GlobalValue>(CpuModel)->setDSOLocal(true);
 
   // Calculate the index needed to access the correct field based on the
   // range. Also adjust the expected value.
@@ -9537,6 +9538,7 @@ llvm::Value *CodeGenFunction::EmitX86CpuSupports(uint64_t FeaturesMask) {
 
     // Grab the global __cpu_model.
     llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
+    cast<llvm::GlobalValue>(CpuModel)->setDSOLocal(true);
 
     // Grab the first (0th) element from the field __cpu_features off of the
     // global in the struct STy.
@@ -9556,6 +9558,8 @@ llvm::Value *CodeGenFunction::EmitX86CpuSupports(uint64_t FeaturesMask) {
   if (Features2 != 0) {
     llvm::Constant *CpuFeatures2 = CGM.CreateRuntimeVariable(Int32Ty,
                                                              "__cpu_features2");
+    cast<llvm::GlobalValue>(CpuFeatures2)->setDSOLocal(true);
+
     Value *Features =
         Builder.CreateAlignedLoad(CpuFeatures2, CharUnits::fromQuantity(4));
 
@@ -9573,6 +9577,7 @@ Value *CodeGenFunction::EmitX86CpuInit() {
   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
                                                     /*Variadic*/ false);
   llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init");
+  cast<llvm::GlobalValue>(Func)->setDSOLocal(true);
   return Builder.CreateCall(Func);
 }
 
index f2a5f54..bff3544 100644 (file)
@@ -4,6 +4,8 @@
 // global, the bit grab, and the icmp correct.
 extern void a(const char *);
 
+// CHECK: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+
 void intel() {
   if (__builtin_cpu_is("intel"))
     a("intel");
index d384efb..761f00c 100644 (file)
@@ -4,6 +4,9 @@
 // global, the bit grab, and the icmp correct.
 extern void a(const char *);
 
+// CHECK: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+// CHECK: @__cpu_features2 = external dso_local global i32
+
 int main() {
   __builtin_cpu_init();
 
@@ -25,3 +28,5 @@ int main() {
 
   return 0;
 }
+
+// CHECK: declare dso_local void @__cpu_indicator_init()