[clang] 850d53a - LTO: Decide upfront whether to use opaque/non-opaque pointer types
Matthias Braun via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 1 18:07:46 PDT 2022
Author: Matthias Braun
Date: 2022-06-01T18:05:53-07:00
New Revision: 850d53a197f9ffbf5708b7bd795056335e81e9b7
URL: https://github.com/llvm/llvm-project/commit/850d53a197f9ffbf5708b7bd795056335e81e9b7
DIFF: https://github.com/llvm/llvm-project/commit/850d53a197f9ffbf5708b7bd795056335e81e9b7.diff
LOG: LTO: Decide upfront whether to use opaque/non-opaque pointer types
LTO code may end up mixing bitcode files from various sources varying in
their use of opaque pointer types. The current strategy to decide
between opaque / typed pointers upon the first bitcode file loaded does
not work here, since we could be loading a non-opaque bitcode file first
and would then be unable to load any files with opaque pointer types
later.
So for LTO this:
- Adds an `lto::Config::OpaquePointer` option and enforces an upfront
decision between the two modes.
- Adds `-opaque-pointers`/`-no-opaque-pointers` options to the gold
plugin; disabled by default.
- `--opaque-pointers`/`--no-opaque-pointers` options with
`-plugin-opt=-opaque-pointers`/`-plugin-opt=-no-opaque-pointers`
aliases to lld; disabled by default.
- Adds an `-lto-opaque-pointers` option to the `llvm-lto2` tool.
- Changes the clang driver to pass `-plugin-opt=-opaque-pointers` to
the linker in LTO modes when clang was configured with opaque
pointers enabled by default.
This fixes https://github.com/llvm/llvm-project/issues/55377
Differential Revision: https://reviews.llvm.org/D125847
Added:
clang/test/Driver/lto-no-opaque-pointers.c
clang/test/Driver/lto-opaque-pointers.c
llvm/test/LTO/X86/Inputs/opaque-pointers.ll
llvm/test/LTO/X86/mix-opaque-typed.ll
Modified:
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/test/CodeGen/thinlto-inline-asm2.c
clang/test/Driver/arm-float-abi-lto.c
clang/test/Driver/memtag_lto.c
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/LTO.cpp
lld/ELF/Options.td
lld/test/ELF/lto/discard-value-names.ll
lld/test/ELF/lto/ltopasses-basic.ll
lld/test/ELF/lto/type-merge.ll
lld/test/ELF/lto/type-merge2.ll
lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
llvm/docs/OpaquePointers.rst
llvm/include/llvm/LTO/Config.h
llvm/test/Analysis/StackSafetyAnalysis/ipa-alias.ll
llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
llvm/test/LTO/Resolution/X86/alias-alias.ll
llvm/test/LTO/Resolution/X86/comdat.ll
llvm/test/LTO/Resolution/X86/ifunc2.ll
llvm/test/LTO/Resolution/X86/local-def-dllimport.ll
llvm/test/LTO/X86/cfi_jt_aliases.ll
llvm/test/LTO/X86/type-mapping-bug4.ll
llvm/test/ThinLTO/X86/Inputs/import-constant.ll
llvm/test/ThinLTO/X86/cfi-devirt.ll
llvm/test/ThinLTO/X86/cfi-unsat.ll
llvm/test/ThinLTO/X86/devirt-after-icp.ll
llvm/test/ThinLTO/X86/devirt2.ll
llvm/test/ThinLTO/X86/devirt_check.ll
llvm/test/ThinLTO/X86/devirt_promote.ll
llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
llvm/test/ThinLTO/X86/funcattrs-prop-unknown.ll
llvm/test/ThinLTO/X86/globals-import-blockaddr.ll
llvm/test/ThinLTO/X86/import-constant.ll
llvm/test/ThinLTO/X86/import-dsolocal.ll
llvm/test/ThinLTO/X86/index-const-prop-gvref-pie.ll
llvm/test/ThinLTO/X86/index-const-prop-gvref.ll
llvm/test/ThinLTO/X86/index-const-prop-linkage.ll
llvm/test/ThinLTO/X86/reference_non_importable.ll
llvm/test/ThinLTO/X86/weak_externals.ll
llvm/tools/gold/gold-plugin.cpp
llvm/tools/llvm-lto2/llvm-lto2.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 7a22ac4afa7e8..7e9fa055b0bc2 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -559,6 +559,9 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
CmdArgs.push_back(
Args.MakeArgString("-plugin-opt=jobs=" + Twine(Parallelism)));
+ if (!CLANG_ENABLE_OPAQUE_POINTERS_INTERNAL)
+ CmdArgs.push_back(Args.MakeArgString("-plugin-opt=no-opaque-pointers"));
+
// If an explicit debugger tuning argument appeared, pass it along.
if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
options::OPT_ggdbN_Group)) {
diff --git a/clang/test/CodeGen/thinlto-inline-asm2.c b/clang/test/CodeGen/thinlto-inline-asm2.c
index 5d7bbc097de7c..7606b27deac87 100644
--- a/clang/test/CodeGen/thinlto-inline-asm2.c
+++ b/clang/test/CodeGen/thinlto-inline-asm2.c
@@ -5,7 +5,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -flto=thin -emit-llvm-bc %t/b.c -o %t/b.bc
// RUN: llvm-nm %t/a.bc | FileCheck %s --check-prefix=NM
-// RUN: llvm-lto2 run %t/a.bc %t/b.bc -o %t/out -save-temps -r=%t/a.bc,ref,plx -r=%t/b.bc,ff_h264_cabac_tables,pl
+// RUN: llvm-lto2 run -lto-opaque-pointers %t/a.bc %t/b.bc -o %t/out -save-temps -r=%t/a.bc,ref,plx -r=%t/b.bc,ff_h264_cabac_tables,pl
// RUN: llvm-dis < %t/out.2.2.internalize.bc | FileCheck %s
//--- a.c
diff --git a/clang/test/Driver/arm-float-abi-lto.c b/clang/test/Driver/arm-float-abi-lto.c
index 83c2435d97a4d..8b6d8ff6b5d7a 100644
--- a/clang/test/Driver/arm-float-abi-lto.c
+++ b/clang/test/Driver/arm-float-abi-lto.c
@@ -2,9 +2,9 @@
// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -S -o - -emit-llvm -DCALL_LIB -DDEFINE_LIB | FileCheck %s
-// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=full -c -o %t.call_full.bc -DCALL_LIB
-// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=full -c -o %t.define_full.bc -DDEFINE_LIB
-// RUN: llvm-lto2 run -o %t.lto_full -save-temps %t.call_full.bc %t.define_full.bc \
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -Xclang -opaque-pointers -flto=full -c -o %t.call_full.bc -DCALL_LIB
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -Xclang -opaque-pointers -flto=full -c -o %t.define_full.bc -DDEFINE_LIB
+// RUN: llvm-lto2 run -lto-opaque-pointers -o %t.lto_full -save-temps %t.call_full.bc %t.define_full.bc \
// RUN: -r %t.call_full.bc,fn,px \
// RUN: -r %t.call_full.bc,fwrite,l \
// RUN: -r %t.call_full.bc,putchar,l \
@@ -14,9 +14,9 @@
// RUN: -r %t.define_full.bc,otherfn,px
// RUN: llvm-dis %t.lto_full.0.4.opt.bc -o - | FileCheck %s
-// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=thin -c -o %t.call_thin.bc -DCALL_LIB
-// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -flto=thin -c -o %t.define_thin.bc -DDEFINE_LIB
-// RUN: llvm-lto2 run -o %t.lto_thin -save-temps %t.call_thin.bc %t.define_thin.bc \
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -Xclang -opaque-pointers -flto=thin -c -o %t.call_thin.bc -DCALL_LIB
+// RUN: %clang --target=arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=hard -O1 %s -Xclang -opaque-pointers -flto=thin -c -o %t.define_thin.bc -DDEFINE_LIB
+// RUN: llvm-lto2 run -lto-opaque-pointers -o %t.lto_thin -save-temps %t.call_thin.bc %t.define_thin.bc \
// RUN: -r %t.call_thin.bc,fn,px \
// RUN: -r %t.call_thin.bc,fwrite,l \
// RUN: -r %t.call_thin.bc,putchar,l \
diff --git a/clang/test/Driver/lto-no-opaque-pointers.c b/clang/test/Driver/lto-no-opaque-pointers.c
new file mode 100644
index 0000000000000..9146ae5da5824
--- /dev/null
+++ b/clang/test/Driver/lto-no-opaque-pointers.c
@@ -0,0 +1,5 @@
+// UNSUPPORTED: enable-opaque-pointers
+// RUN: %clang --target=x86_64-unknown-linux -### %s -flto 2> %t
+// RUN: FileCheck %s < %t
+
+// CHECK: -plugin-opt=no-opaque-pointers
diff --git a/clang/test/Driver/lto-opaque-pointers.c b/clang/test/Driver/lto-opaque-pointers.c
new file mode 100644
index 0000000000000..acdf13c21fd41
--- /dev/null
+++ b/clang/test/Driver/lto-opaque-pointers.c
@@ -0,0 +1,5 @@
+// REQUIRES: enable-opaque-pointers
+// RUN: %clang --target=x86_64-unknown-linux -### %s -flto 2> %t
+// RUN: FileCheck %s < %t
+
+// CHECK-NOT: -plugin-opt=no-opaque-pointers
diff --git a/clang/test/Driver/memtag_lto.c b/clang/test/Driver/memtag_lto.c
index d73670f99cb60..2ad22141608c7 100644
--- a/clang/test/Driver/memtag_lto.c
+++ b/clang/test/Driver/memtag_lto.c
@@ -8,9 +8,9 @@
// RUN: %clang -O1 -target aarch64-unknown-linux -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s
// Full LTO
-// RUN: %clang -O1 -target aarch64-unknown-linux -c %s -flto=full -o %t.ltonewpm1.bc
-// RUN: %clang -O1 -target aarch64-unknown-linux -c -DBUILD2 %s -flto=full -o %t.ltonewpm2.bc
-// RUN: llvm-lto2 run -o %t.ltonewpm %t.ltonewpm1.bc %t.ltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
+// RUN: %clang -O1 -target aarch64-unknown-linux -c %s -Xclang -opaque-pointers -flto=full -o %t.ltonewpm1.bc
+// RUN: %clang -O1 -target aarch64-unknown-linux -c -DBUILD2 %s -Xclang -opaque-pointers -flto=full -o %t.ltonewpm2.bc
+// RUN: llvm-lto2 run -lto-opaque-pointers -o %t.ltonewpm %t.ltonewpm1.bc %t.ltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
// RUN: -r %t.ltonewpm1.bc,fn,plx \
// RUN: -r %t.ltonewpm1.bc,use,lx \
// RUN: -r %t.ltonewpm1.bc,use_local,plx \
@@ -19,9 +19,9 @@
// RUN: -r %t.ltonewpm2.bc,z, 2>&1 | FileCheck %s --allow-empty
// Thin LTO, new PM
-// RUN: %clang -O1 -target aarch64-unknown-linux -c %s -flto=thin -o %t.thinltonewpm1.bc
-// RUN: %clang -O1 -target aarch64-unknown-linux -c -DBUILD2 %s -flto=thin -o %t.thinltonewpm2.bc
-// RUN: llvm-lto2 run -o %t.thinltonewpm %t.thinltonewpm1.bc %t.thinltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
+// RUN: %clang -O1 -target aarch64-unknown-linux -c %s -Xclang -opaque-pointers -flto=thin -o %t.thinltonewpm1.bc
+// RUN: %clang -O1 -target aarch64-unknown-linux -c -DBUILD2 %s -Xclang -opaque-pointers -flto=thin -o %t.thinltonewpm2.bc
+// RUN: llvm-lto2 run -lto-opaque-pointers -o %t.thinltonewpm %t.thinltonewpm1.bc %t.thinltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
// RUN: -r %t.thinltonewpm1.bc,fn,plx \
// RUN: -r %t.thinltonewpm1.bc,use,lx \
// RUN: -r %t.thinltonewpm1.bc,use_local,plx \
@@ -39,9 +39,9 @@
// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -mllvm -stack-safety-print %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefixes=SSI,XUNSAFE,YSAFE
// Full LTO: both are safe.
-// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c %s -flto=full -o %t.ltonewpm1.bc
-// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c -DBUILD2 %s -flto=full -o %t.ltonewpm2.bc
-// RUN: llvm-lto2 run -o %t.ltonewpm %t.ltonewpm1.bc %t.ltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
+// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c %s -Xclang -opaque-pointers -flto=full -o %t.ltonewpm1.bc
+// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c -DBUILD2 %s -Xclang -opaque-pointers -flto=full -o %t.ltonewpm2.bc
+// RUN: llvm-lto2 run -lto-opaque-pointers -o %t.ltonewpm %t.ltonewpm1.bc %t.ltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
// RUN: -r %t.ltonewpm1.bc,fn,plx \
// RUN: -r %t.ltonewpm1.bc,use,lx \
// RUN: -r %t.ltonewpm1.bc,use_local,plx \
@@ -50,9 +50,9 @@
// RUN: -r %t.ltonewpm2.bc,z, 2>&1 | FileCheck %s -check-prefixes=SSI,XSAFE,YSAFE
// Thin LTO: both are safe.
-// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c %s -flto=thin -o %t.thinltonewpm1.bc
-// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c -DBUILD2 %s -flto=thin -o %t.thinltonewpm2.bc
-// RUN: llvm-lto2 run -o %t.thinltonewpm %t.thinltonewpm1.bc %t.thinltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
+// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c %s -Xclang -opaque-pointers -flto=thin -o %t.thinltonewpm1.bc
+// RUN: %clang -O1 -target aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag -c -DBUILD2 %s -Xclang -opaque-pointers -flto=thin -o %t.thinltonewpm2.bc
+// RUN: llvm-lto2 run -lto-opaque-pointers -o %t.thinltonewpm %t.thinltonewpm1.bc %t.thinltonewpm2.bc -save-temps -stack-safety-print -thinlto-threads 1 -O1 \
// RUN: -r %t.thinltonewpm1.bc,fn,plx \
// RUN: -r %t.thinltonewpm1.bc,use,lx \
// RUN: -r %t.thinltonewpm1.bc,use_local,plx \
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 32eb832776ff9..8a469c106a68a 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -198,6 +198,7 @@ struct Configuration {
bool nostdlib;
bool oFormatBinary;
bool omagic;
+ bool opaquePointers;
bool optEB = false;
bool optEL = false;
bool optimizeBBJumps;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 1e0a46040eb95..7b5a588fa3e5c 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1126,6 +1126,8 @@ static void readConfigs(opt::InputArgList &args) {
config->nostdlib = args.hasArg(OPT_nostdlib);
config->oFormatBinary = isOutputFormatBinary(args);
config->omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
+ config->opaquePointers = args.hasFlag(
+ OPT_plugin_opt_opaque_pointers, OPT_plugin_opt_no_opaque_pointers, true);
config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
config->optStatsFilename = args.getLastArgValue(OPT_plugin_opt_stats_file);
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index ae5447f57f919..488ac40e82d3c 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -164,6 +164,8 @@ static lto::Config createConfig() {
c.RunCSIRInstr = config->ltoCSProfileGenerate;
c.PGOWarnMismatch = config->ltoPGOWarnMismatch;
+ c.OpaquePointers = config->opaquePointers;
+
if (config->emitLLVM) {
c.PostInternalizeModuleHook = [](size_t task, const Module &m) {
if (std::unique_ptr<raw_fd_ostream> os =
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 73e7b2dded675..249f538f02672 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -626,6 +626,10 @@ def: J<"plugin-opt=cs-profile-path=">,
def: J<"plugin-opt=obj-path=">,
Alias<lto_obj_path_eq>,
HelpText<"Alias for --lto-obj-path=">;
+def plugin_opt_opaque_pointers: F<"plugin-opt=opaque-pointers">,
+ HelpText<"Use opaque pointers in IR during LTO (default)">;
+def plugin_opt_no_opaque_pointers: F<"plugin-opt=no-opaque-pointers">,
+ HelpText<"Use typed pointers in IR during LTO">;
def: J<"plugin-opt=opt-remarks-filename=">,
Alias<opt_remarks_filename>,
HelpText<"Alias for --opt-remarks-filename">;
diff --git a/lld/test/ELF/lto/discard-value-names.ll b/lld/test/ELF/lto/discard-value-names.ll
index d3f10ddaa352b..545c7bda1a9a9 100644
--- a/lld/test/ELF/lto/discard-value-names.ll
+++ b/lld/test/ELF/lto/discard-value-names.ll
@@ -7,7 +7,7 @@
; CHECK: @GlobalValueName
; CHECK: @foo(i32 %in)
; CHECK: somelabel:
-; CHECK: %GV = load i32, i32* @GlobalValueName
+; CHECK: %GV = load i32, ptr @GlobalValueName
; CHECK: %add = add i32 %in, %GV
; CHECK: ret i32 %add
diff --git a/lld/test/ELF/lto/ltopasses-basic.ll b/lld/test/ELF/lto/ltopasses-basic.ll
index 8489e70e18dc6..bc8328c644b60 100644
--- a/lld/test/ELF/lto/ltopasses-basic.ll
+++ b/lld/test/ELF/lto/ltopasses-basic.ll
@@ -12,6 +12,6 @@ define void @ctor() {
}
; `@ctor` doesn't do anything and so the optimizer should kill it, leaving no ctors
-; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
+; CHECK: @llvm.global_ctors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
; MLLVM: Pass Arguments:
diff --git a/lld/test/ELF/lto/type-merge.ll b/lld/test/ELF/lto/type-merge.ll
index c020703373546..97eb6b771e884 100644
--- a/lld/test/ELF/lto/type-merge.ll
+++ b/lld/test/ELF/lto/type-merge.ll
@@ -14,13 +14,13 @@ define void @foo() {
declare void @bar(i8*)
; CHECK: define void @foo() {
-; CHECK-NEXT: call void @bar(i8* null)
+; CHECK-NEXT: call void @bar(ptr null)
; CHECK-NEXT: ret void
; CHECK-NEXT: }
-; CHECK: declare void @bar(i8*)
+; CHECK: declare void @bar(ptr)
; CHECK: define void @zed() {
-; CHECK-NEXT: call void bitcast (void (i8*)* @bar to void ()*)()
+; CHECK-NEXT: call void @bar()
; CHECK-NEXT: ret void
; CHECK-NEXT: }
diff --git a/lld/test/ELF/lto/type-merge2.ll b/lld/test/ELF/lto/type-merge2.ll
index 95fed45db9a51..61dc7ff882eee 100644
--- a/lld/test/ELF/lto/type-merge2.ll
+++ b/lld/test/ELF/lto/type-merge2.ll
@@ -14,15 +14,12 @@ define void @foo() {
}
declare void @bar(%zed*)
-; CHECK: %zed = type { i8 }
-; CHECK-NEXT: %zed.0 = type { i16 }
-
; CHECK: define void @foo() {
-; CHECK-NEXT: call void bitcast (void (%zed.0*)* @bar to void (%zed*)*)(%zed* null)
+; CHECK-NEXT: call void @bar(ptr null)
; CHECK-NEXT: ret void
; CHECK-NEXT: }
-; CHECK: define void @bar(%zed.0* %this) {
-; CHECK-NEXT: store %zed.0* %this, %zed.0** null
+; CHECK: define void @bar(ptr %this) {
+; CHECK-NEXT: store ptr %this, ptr null
; CHECK-NEXT: ret void
; CHECK-NEXT: }
diff --git a/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test b/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
index 49c1fc5a82a27..9618948a2059d 100644
--- a/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
+++ b/lld/test/ELF/lto/wrap-unreferenced-before-codegen.test
@@ -28,8 +28,9 @@
# RUN: llvm-mc -triple x86_64-elf -filetype=obj -o %t/malloc.o %t/malloc.s
# RUN: ld.lld -shared -o %t/libmalloc.so -soname libmalloc.so %t/malloc.o
# RUN: llvm-mc -triple x86_64-elf -filetype=obj -o %t/emutls.o %t/emutls.s
-# RUN: llvm-as -o %t/usetls.bc %t/usetls.ll
-# RUN: ld.lld -shared -o %t/libusetls.so %t/usetls.bc %t/libmalloc.so \
+# RUN: llvm-as -opaque-pointers=1 -o %t/usetls.bc %t/usetls.ll
+# RUN: ld.lld --plugin-opt=opaque-pointers -shared -o %t/libusetls.so \
+# RUN: %t/usetls.bc %t/libmalloc.so \
# RUN: --start-lib %t/emutls.o -mllvm -emulated-tls --wrap malloc
# RUN: llvm-objdump --dynamic-reloc --disassemble %t/libusetls.so | \
# RUN: FileCheck --check-prefix=USETLS-DISASM %s
diff --git a/llvm/docs/OpaquePointers.rst b/llvm/docs/OpaquePointers.rst
index de553874a859f..8ae2595ae66e7 100644
--- a/llvm/docs/OpaquePointers.rst
+++ b/llvm/docs/OpaquePointers.rst
@@ -205,6 +205,9 @@ For users of the clang cc1 interface, ``-no-opaque-pointers`` can be passed.
Note that the ``CLANG_ENABLE_OPAQUE_POINTERS`` cmake option has no effect on
the cc1 interface.
+Usage for LTO can be disabled by passing ``-Wl,-plugin-opt=no-opaque-pointers``
+to the clang driver.
+
The next steps for the opaque pointer migration are:
* Migrate Clang/LLVM tests to use opaque pointers.
diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h
index dd4f8daac104c..54bb82d84d96e 100644
--- a/llvm/include/llvm/LTO/Config.h
+++ b/llvm/include/llvm/LTO/Config.h
@@ -177,6 +177,10 @@ struct Config {
/// Add FSAFDO discriminators.
bool AddFSDiscriminator = false;
+ /// Use opaque pointer types. Used to call LLVMContext::setOpaquePointers
+ /// unless already set by the `-opaque-pointers` commandline option.
+ bool OpaquePointers = true;
+
/// If this field is set, LTO will write input file paths and symbol
/// resolutions here in llvm-lto2 command line flag format. This can be
/// used for testing and for running the LTO pipeline outside of the linker
@@ -288,6 +292,8 @@ struct LTOLLVMContext : LLVMContext {
enableDebugTypeODRUniquing();
setDiagnosticHandler(
std::make_unique<LTOLLVMDiagnosticHandler>(&DiagHandler), true);
+ if (!hasSetOpaquePointersValue())
+ setOpaquePointers(C.OpaquePointers);
}
DiagnosticHandlerFunction DiagHandler;
};
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/ipa-alias.ll b/llvm/test/Analysis/StackSafetyAnalysis/ipa-alias.ll
index 8602bc7f706e8..8a371054c2262 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/ipa-alias.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/ipa-alias.ll
@@ -33,7 +33,7 @@
; RUN: -r %t.summ1.bc,PreemptableAliasWrite1,px \
; RUN: -r %t.summ1.bc,Write1,px
-; RUN: llvm-lto2 run %t.summ0.bc %t.summ1.bc -o %t.lto -stack-safety-print -stack-safety-run -save-temps -thinlto-threads 1 -O0 \
+; RUN: llvm-lto2 run -opaque-pointers=0 %t.summ0.bc %t.summ1.bc -o %t.lto -stack-safety-print -stack-safety-run -save-temps -thinlto-threads 1 -O0 \
; RUN: $(cat %t.res.txt) \
; RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL,LTO
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll b/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
index 1f1b379a2e8a3..6324b6b8c1964 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/ipa.ll
@@ -83,7 +83,7 @@
; RUN: -r %t.summ1.bc,Write8,px \
; RUN: -r %t.summ1.bc,WriteAndReturn8,px
-; RUN: llvm-lto2 run %t.summ0.bc %t.summ1.bc -o %t.lto -stack-safety-print -stack-safety-run -save-temps -thinlto-threads 1 -O0 \
+; RUN: llvm-lto2 run -opaque-pointers=0 %t.summ0.bc %t.summ1.bc -o %t.lto -stack-safety-print -stack-safety-run -save-temps -thinlto-threads 1 -O0 \
; RUN: $(cat %t.res.txt) \
; RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL,LTO
diff --git a/llvm/test/LTO/Resolution/X86/alias-alias.ll b/llvm/test/LTO/Resolution/X86/alias-alias.ll
index a8489112ae99e..093b5973d24ca 100644
--- a/llvm/test/LTO/Resolution/X86/alias-alias.ll
+++ b/llvm/test/LTO/Resolution/X86/alias-alias.ll
@@ -6,10 +6,10 @@
; CHECK-NOT: alias
; CHECK: @c = global i32 1
-; CHECK-NEXT: @d = global i32* @a
+; CHECK-NEXT: @d = global ptr @a
; CHECK-EMPTY:
-; CHECK-NEXT: @a = weak alias i32, i32* @b
-; CHECK-NEXT: @b = internal alias i32, i32* @c
+; CHECK-NEXT: @a = weak alias i32, ptr @b
+; CHECK-NEXT: @b = internal alias i32, ptr @c
; RES: 1.o{{$}}
; RES-NEXT: {{^}}-r={{.*}}1.o,c,p{{$}}
diff --git a/llvm/test/LTO/Resolution/X86/comdat.ll b/llvm/test/LTO/Resolution/X86/comdat.ll
index 06b61b7edf8bc..52b8f7f78805e 100644
--- a/llvm/test/LTO/Resolution/X86/comdat.ll
+++ b/llvm/test/LTO/Resolution/X86/comdat.ll
@@ -50,36 +50,36 @@ bb11:
; CHECK-DAG: @v1 = weak_odr global i32 42, comdat($c1)
-; CHECK-DAG: @r11 = global i32* @v1{{$}}
-; CHECK-DAG: @r12 = global i32 (i8*)* @f1{{$}}
+; CHECK-DAG: @r11 = global ptr @v1{{$}}
+; CHECK-DAG: @r12 = global ptr @f1{{$}}
-; CHECK-DAG: @r21 = global i32* @v1{{$}}
-; CHECK-DAG: @r22 = global i32 (i8*)* @f1{{$}}
+; CHECK-DAG: @r21 = global ptr @v1{{$}}
+; CHECK-DAG: @r22 = global ptr @f1{{$}}
; CHECK-DAG: @v1.1 = internal global i32 41, comdat($c2)
-; CHECK-DAG: @a11 = alias i32, i32* @v1{{$}}
-; CHECK-DAG: @a12 = alias i16, bitcast (i32* @v1 to i16*)
+; CHECK-DAG: @a11 = alias i32, ptr @v1{{$}}
+; CHECK-DAG: @a12 = alias i16, ptr @v1{{$}}
-; CHECK-DAG: @a13 = alias i32 (i8*), i32 (i8*)* @f1{{$}}
-; CHECK-DAG: @a14 = alias i16, bitcast (i32 (i8*)* @f1 to i16*)
+; CHECK-DAG: @a13 = alias i32 (ptr), ptr @f1{{$}}
+; CHECK-DAG: @a14 = alias i16, ptr @f1{{$}}
-; CHECK-DAG: @a21 = alias i32, i32* @v1.1{{$}}
-; CHECK-DAG: @a22 = alias i16, bitcast (i32* @v1.1 to i16*)
+; CHECK-DAG: @a21 = alias i32, ptr @v1.1{{$}}
+; CHECK-DAG: @a22 = alias i16, ptr @v1.1{{$}}
-; CHECK-DAG: @a23 = alias i32 (i8*), i32 (i8*)* @f1.2{{$}}
-; CHECK-DAG: @a24 = alias i16, bitcast (i32 (i8*)* @f1.2 to i16*)
+; CHECK-DAG: @a23 = alias i32 (ptr), ptr @f1.2{{$}}
+; CHECK-DAG: @a24 = alias i16, ptr @f1.2{{$}}
-; CHECK: define weak_odr dso_local i32 @f1(i8* %0) comdat($c1) {
+; CHECK: define weak_odr dso_local i32 @f1(ptr %0) comdat($c1) {
; CHECK-NEXT: bb10:
; CHECK-NEXT: br label %bb11{{$}}
; CHECK: bb11:
; CHECK-NEXT: ret i32 42
; CHECK-NEXT: }
-; CHECK: define internal i32 @f1.2(i8* %this) comdat($c2) {
+; CHECK: define internal i32 @f1.2(ptr %this) comdat($c2) {
; CHECK-NEXT: bb20:
-; CHECK-NEXT: store i8* %this, i8** null
+; CHECK-NEXT: store ptr %this, ptr null
; CHECK-NEXT: br label %bb21
; CHECK: bb21:
; CHECK-NEXT: ret i32 41
diff --git a/llvm/test/LTO/Resolution/X86/ifunc2.ll b/llvm/test/LTO/Resolution/X86/ifunc2.ll
index 0d824f6f3b27c..5dcfdbd44e70c 100644
--- a/llvm/test/LTO/Resolution/X86/ifunc2.ll
+++ b/llvm/test/LTO/Resolution/X86/ifunc2.ll
@@ -6,14 +6,14 @@
target datalayout = "e-p:64:64"
target triple = "x86_64-unknown-linux-gnu"
-; CHECK: @foo = ifunc i32 (), i32 ()* ()* @foo_resolver.2
+; CHECK: @foo = ifunc i32 (), ptr @foo_resolver.2
@foo = ifunc i32 (), i32 ()* ()* @foo_resolver
-; CHECK: define internal i32 ()* @foo_resolver.2() {
-; CHECK-NEXT: ret i32 ()* inttoptr (i32 1 to i32 ()*)
+; CHECK: define internal ptr @foo_resolver.2() {
+; CHECK-NEXT: ret ptr inttoptr (i32 1 to ptr)
define weak i32 ()* @foo_resolver() {
ret i32 ()* inttoptr (i32 1 to i32 ()*)
}
-; CHECK: define i32 ()* @foo_resolver() {
-; CHECK-NEXT: ret i32 ()* inttoptr (i32 2 to i32 ()*)
+; CHECK: define ptr @foo_resolver() {
+; CHECK-NEXT: ret ptr inttoptr (i32 2 to ptr)
diff --git a/llvm/test/LTO/Resolution/X86/local-def-dllimport.ll b/llvm/test/LTO/Resolution/X86/local-def-dllimport.ll
index 25b69b737362d..2dcd7ee64fa29 100644
--- a/llvm/test/LTO/Resolution/X86/local-def-dllimport.ll
+++ b/llvm/test/LTO/Resolution/X86/local-def-dllimport.ll
@@ -13,7 +13,7 @@ target triple = "x86_64-unknown-linux-gnu"
$g = comdat any
@g = global i8 42, comdat, !type !0
-; CHECK: define available_externally dllimport i8* @f()
+; CHECK: define available_externally dllimport ptr @f()
define available_externally dllimport i8* @f() {
ret i8* @g
}
diff --git a/llvm/test/LTO/X86/Inputs/opaque-pointers.ll b/llvm/test/LTO/X86/Inputs/opaque-pointers.ll
new file mode 100644
index 0000000000000..3c644346532ee
--- /dev/null
+++ b/llvm/test/LTO/X86/Inputs/opaque-pointers.ll
@@ -0,0 +1,7 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i64 @foo(ptr %p) {
+ %t = load i64, ptr %p
+ ret i64 %t
+}
diff --git a/llvm/test/LTO/X86/cfi_jt_aliases.ll b/llvm/test/LTO/X86/cfi_jt_aliases.ll
index d5d85d0dcbd35..06737f628a417 100644
--- a/llvm/test/LTO/X86/cfi_jt_aliases.ll
+++ b/llvm/test/LTO/X86/cfi_jt_aliases.ll
@@ -46,7 +46,7 @@
; CHECK-THIN-OD: jmp {{.*}} <a.cfi_jt
; CHECK-THIN-OD-NEXT: R_X86_64_PLT32 a
-; CHECK-USED: @llvm.used = appending global [3 x i8*] [i8* bitcast (void ()* @a.cfi_jt to i8*), i8* bitcast (void ()* @b.cfi_jt to i8*), i8* bitcast (void ()* @c.cfi_jt to i8*)], section "llvm.metadata"
+; CHECK-USED: @llvm.used = appending global [3 x ptr] [ptr @a.cfi_jt, ptr @b.cfi_jt, ptr @c.cfi_jt], section "llvm.metadata"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/mix-opaque-typed.ll b/llvm/test/LTO/X86/mix-opaque-typed.ll
new file mode 100644
index 0000000000000..fc95cd53b953d
--- /dev/null
+++ b/llvm/test/LTO/X86/mix-opaque-typed.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as -opaque-pointers=0 %s -o %t-typed.bc
+; RUN: llvm-as -opaque-pointers=1 %S/Inputs/opaque-pointers.ll -o %t-opaque.bc
+; RUN: llvm-lto2 run -o %t-lto.bc %t-typed.bc %t-opaque.bc -save-temps \
+; RUN: -lto-opaque-pointers \
+; RUN: -r %t-typed.bc,call_foo,px -r %t-typed.bc,foo,l \
+; RUN: -r %t-opaque.bc,foo,px
+; RUN: opt -S -o - %t-lto.bc.0.4.opt.bc | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare i64 @foo(i64* %p);
+
+define i64 @call_foo(i64* %p) {
+ ; CHECK-LABEL: define i64 @call_foo(ptr nocapture readonly %p) local_unnamed_addr #0 {
+ ; CHECK-NEXT: %t.i = load i64, ptr %p, align 8
+ %t = call i64 @foo(i64* %p)
+ ret i64 %t
+}
diff --git a/llvm/test/LTO/X86/type-mapping-bug4.ll b/llvm/test/LTO/X86/type-mapping-bug4.ll
index bdd687cfbefdc..da8275e8d327c 100644
--- a/llvm/test/LTO/X86/type-mapping-bug4.ll
+++ b/llvm/test/LTO/X86/type-mapping-bug4.ll
@@ -13,26 +13,25 @@
; Stage1 and stage2 are described in type-mapping-bug4_1.ll.
; Stage3 is described in this file.
-; CHECK: %class.CCSM = type opaque
-; CHECK: %class.CB = type { %"class.std::unique_ptr_base.1" }
-; CHECK: %"class.std::unique_ptr_base.1" = type { %class.CCSM* }
+; CHECK: %class.CB.1 = type { %"class.std::unique_ptr_base.2" }
+; CHECK: %"class.std::unique_ptr_base.2" = type { ptr }
; CHECK: define void @j() {
-; CHECK: call void @h(%class.CCSM* undef)
+; CHECK: call void @h(ptr undef)
; CHECK: ret void
; CHECK: }
-; CHECK: declare void @h(%class.CCSM*)
+; CHECK: declare void @h(ptr)
; CHECK: define void @a() {
-; CHECK: call void @llvm.dbg.value(metadata %class.CB* undef, metadata !10, metadata !DIExpression())
+; CHECK: call void @llvm.dbg.value(metadata ptr undef, metadata !10, metadata !DIExpression())
; CHECK: ret void
; CHECK: }
; CHECK: declare void @llvm.dbg.value(metadata, metadata, metadata) #0
-; CHECK: define void @d(%class.CB* %0) {
-; CHECK: %2 = getelementptr inbounds %class.CB, %class.CB* undef, i64 0, i32 0, i32 0
+; CHECK: define void @d(ptr %0) {
+; CHECK: %2 = getelementptr inbounds %class.CB.1, ptr undef, i64 0, i32 0, i32 0
; CHECK: ret void
; CHECK: }
diff --git a/llvm/test/ThinLTO/X86/Inputs/import-constant.ll b/llvm/test/ThinLTO/X86/Inputs/import-constant.ll
index 94bba2d02c885..dce788ace1c97 100644
--- a/llvm/test/ThinLTO/X86/Inputs/import-constant.ll
+++ b/llvm/test/ThinLTO/X86/Inputs/import-constant.ll
@@ -10,6 +10,6 @@ target triple = "x86_64-unknown-linux-gnu"
define dso_local nonnull %struct.S* @_Z6getObjv() local_unnamed_addr {
entry:
- store %struct.S* null, %struct.S** getelementptr inbounds (%struct.Q, %struct.Q* @outer, i64 0, i32 0), align 8
+ store %struct.S* null, %struct.S** getelementptr inbounds (%struct.Q, %struct.Q* @outer, i64 1, i32 0), align 8
ret %struct.S* @_ZL3Obj
}
diff --git a/llvm/test/ThinLTO/X86/cfi-devirt.ll b/llvm/test/ThinLTO/X86/cfi-devirt.ll
index 4ad6090075a2f..78fad2f15ad0e 100644
--- a/llvm/test/ThinLTO/X86/cfi-devirt.ll
+++ b/llvm/test/ThinLTO/X86/cfi-devirt.ll
@@ -94,7 +94,7 @@ cont2:
; CHECK-IR: br i1 {{.*}}, label %trap, label %cont2
; We still have to call it as virtual.
- ; CHECK-IR: %call3 = tail call i32 %7
+ ; CHECK-IR: %call3 = tail call i32 %5
%call3 = tail call i32 %8(%struct.A* nonnull %obj, i32 %call)
ret i32 %call3
}
diff --git a/llvm/test/ThinLTO/X86/cfi-unsat.ll b/llvm/test/ThinLTO/X86/cfi-unsat.ll
index fffe077a21d5a..e60ebdc9e4313 100644
--- a/llvm/test/ThinLTO/X86/cfi-unsat.ll
+++ b/llvm/test/ThinLTO/X86/cfi-unsat.ll
@@ -59,14 +59,12 @@ cont:
; CHECK-IR0: define weak_odr i32 @test
; CHECK-IR0-NEXT: entry:
-; CHECK-IR0-NEXT: %0 = bitcast
; CHECK-IR0-NEXT: %vtable5 =
; CHECK-IR0-NEXT: tail call void @llvm.trap()
; CHECK-IR0-NEXT: unreachable
; CHECK-IR0-NEXT: }
; CHECK-IR0: define weak_odr i32 @testb
; CHECK-IR0-NEXT: entry:
-; CHECK-IR0-NEXT: %0 = bitcast
; CHECK-IR0-NEXT: %vtable5 =
; CHECK-IR0-NEXT: tail call void @llvm.trap()
; CHECK-IR0-NEXT: unreachable
diff --git a/llvm/test/ThinLTO/X86/devirt-after-icp.ll b/llvm/test/ThinLTO/X86/devirt-after-icp.ll
index 7c1cec4c1ccfe..0b306f90feaeb 100644
--- a/llvm/test/ThinLTO/X86/devirt-after-icp.ll
+++ b/llvm/test/ThinLTO/X86/devirt-after-icp.ll
@@ -100,7 +100,7 @@ if.true.direct_targ: ; preds = %entry
%8 = load i32 (%class.B*)*, i32 (%class.B*)** %vfn.i, align 8
; Call to bar() can be devirtualized to call to B::bar(), since it was
; inlined from B::foo() after ICP introduced the guarded promotion.
-; CHECK-IR: %call.i = tail call i32 @_ZN1B3barEv(%class.B* %3)
+; CHECK-IR: %call.i = tail call i32 @_ZN1B3barEv(ptr nonnull %a)
%call.i = tail call i32 %8(%class.B* %5)
br label %if.end.icp
diff --git a/llvm/test/ThinLTO/X86/devirt2.ll b/llvm/test/ThinLTO/X86/devirt2.ll
index 0a10a40e26fd8..43f76a81ba524 100644
--- a/llvm/test/ThinLTO/X86/devirt2.ll
+++ b/llvm/test/ThinLTO/X86/devirt2.ll
@@ -180,7 +180,7 @@ entry:
; Check that the call was devirtualized. Ignore extra character before
; symbol name which would happen if it was promoted during module
; splitting for hybrid WPD.
- ; CHECK-IR1: %call = tail call i32 bitcast (void ()* @{{.*}}_ZN1A1nEi
+ ; CHECK-IR1: %call = tail call i32 @_ZN1A1nEi
%call = tail call i32 %fptr1(%struct.A* nonnull %obj, i32 %a)
%3 = bitcast i8** %vtable to i32 (%struct.A*, i32)**
diff --git a/llvm/test/ThinLTO/X86/devirt_check.ll b/llvm/test/ThinLTO/X86/devirt_check.ll
index 63a64cb2e1b19..bf03afa0d8c61 100644
--- a/llvm/test/ThinLTO/X86/devirt_check.ll
+++ b/llvm/test/ThinLTO/X86/devirt_check.ll
@@ -54,20 +54,20 @@ entry:
; Check that the call was devirtualized, but preceeded by a check guarding
; a trap if the function pointer doesn't match.
- ; TRAP: %.not = icmp eq i32 (%struct.A*, i32)* %fptr1, @_ZN1A1nEi
+ ; TRAP: %.not = icmp eq ptr %fptr1, @_ZN1A1nEi
; Ensure !prof and !callees metadata for indirect call promotion removed.
; TRAP-NOT: prof
; TRAP-NOT: callees
- ; TRAP: br i1 %.not, label %3, label %2
- ; TRAP: 2:
+ ; TRAP: br i1 %.not, label %1, label %0
+ ; TRAP: 0:
; TRAP: tail call void @llvm.debugtrap()
- ; TRAP: br label %3
- ; TRAP: 3:
+ ; TRAP: br label %1
+ ; TRAP: 1:
; TRAP: tail call i32 @_ZN1A1nEi
; Check that the call was devirtualized, but preceeded by a check guarding
; a fallback if the function pointer doesn't match.
- ; FALLBACK: %2 = icmp eq i32 (%struct.A*, i32)* %fptr1, @_ZN1A1nEi
- ; FALLBACK: br i1 %2, label %if.true.direct_targ, label %if.false.orig_indirect
+ ; FALLBACK: %0 = icmp eq ptr %fptr1, @_ZN1A1nEi
+ ; FALLBACK: br i1 %0, label %if.true.direct_targ, label %if.false.orig_indirect
; FALLBACK: if.true.direct_targ:
; FALLBACK: tail call i32 @_ZN1A1nEi
; Ensure !prof and !callees metadata for indirect call promotion removed.
diff --git a/llvm/test/ThinLTO/X86/devirt_promote.ll b/llvm/test/ThinLTO/X86/devirt_promote.ll
index e978d543d900f..39f0229de9ca6 100644
--- a/llvm/test/ThinLTO/X86/devirt_promote.ll
+++ b/llvm/test/ThinLTO/X86/devirt_promote.ll
@@ -58,7 +58,7 @@ entry:
%fptr1 = load i32 (%struct.A*, i32)*, i32 (%struct.A*, i32)** %2, align 8
; Check that the call was devirtualized.
- ; CHECK-IR1: %call = tail call i32 bitcast (void ()* @_ZN1A1nEi
+ ; CHECK-IR1: %call = tail call i32 @_ZN1A1nEi
%call = tail call i32 %fptr1(%struct.A* nonnull %obj, i32 %a)
ret i32 %call
diff --git a/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll b/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
index 5966794152c16..f5a37551085ab 100644
--- a/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
+++ b/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
@@ -24,7 +24,7 @@
; REMARK-COUNT-3: single-impl: devirtualized a call to _ZNK1A1fEv
-; IMPORT: define available_externally hidden i32 @_ZNK1A1fEv(%struct.A* %this)
+; IMPORT: define available_externally hidden i32 @_ZNK1A1fEv(ptr %this)
; IMPORT-NEXT: entry:
; IMPORT-NEXT: ret i32 3
diff --git a/llvm/test/ThinLTO/X86/funcattrs-prop-unknown.ll b/llvm/test/ThinLTO/X86/funcattrs-prop-unknown.ll
index c53120f1416da..c509b669ccbe8 100644
--- a/llvm/test/ThinLTO/X86/funcattrs-prop-unknown.ll
+++ b/llvm/test/ThinLTO/X86/funcattrs-prop-unknown.ll
@@ -8,14 +8,14 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-NOT: ; Function Attrs:
-; CHECK: define i32 @indirect(i32 ()* nocapture %0) {
+; CHECK: define i32 @indirect(ptr nocapture %0) {
define i32 @indirect(i32 ()* nocapture) {
%2 = tail call i32 %0()
ret i32 %2
}
; CHECK-NOT: ; Function Attrs:
-; CHECK: define i8* @inlineasm() {
+; CHECK: define ptr @inlineasm() {
define i8* @inlineasm() {
entry:
%0 = tail call i8* asm sideeffect "lea ff_h264_cabac_tables(%rip), $0", "=&r,~{dirflag},~{fpsr},~{flags}"()
@@ -32,4 +32,4 @@ define void @selectcallee() {
declare void @f()
declare void @g()
- at global = extern_weak global i32
\ No newline at end of file
+ at global = extern_weak global i32
diff --git a/llvm/test/ThinLTO/X86/globals-import-blockaddr.ll b/llvm/test/ThinLTO/X86/globals-import-blockaddr.ll
index 96d7b851abbf3..e7a3ffbffb7c1 100644
--- a/llvm/test/ThinLTO/X86/globals-import-blockaddr.ll
+++ b/llvm/test/ThinLTO/X86/globals-import-blockaddr.ll
@@ -6,9 +6,9 @@
; Verify that we haven't imported GV containing blockaddress
; CHECK: @label_addr.llvm.0 = external hidden constant
; Verify that bar is not imported since it has address-taken block that is target of indirect branch
-; CHECK: declare [1 x i8*]* @bar()
+; CHECK: declare ptr @bar()
; Verify that foo is imported
-; CHECK: available_externally [1 x i8*]* @foo
+; CHECK: available_externally ptr @foo
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/ThinLTO/X86/import-constant.ll b/llvm/test/ThinLTO/X86/import-constant.ll
index e5254948f591e..dd45c51e85d09 100644
--- a/llvm/test/ThinLTO/X86/import-constant.ll
+++ b/llvm/test/ThinLTO/X86/import-constant.ll
@@ -25,18 +25,18 @@
; RUN: llvm-dis %t-out-norefs.1.3.import.bc -o - | FileCheck %s --check-prefix=NOREFS
; Check that variable has been promoted in the source module
-; PROMOTE: @_ZL3Obj.llvm.{{.*}} = hidden constant %struct.S { i32 4, i32 8, i32* @val }
+; PROMOTE: @_ZL3Obj.llvm.{{.*}} = hidden constant %struct.S { i32 4, i32 8, ptr @val }
; @outer is a write-only variable, so it's been converted to zeroinitializer.
; IMPORT: @val = available_externally global i32 42
-; IMPORT-NEXT: @_ZL3Obj.llvm.{{.*}} = available_externally hidden constant %struct.S { i32 4, i32 8, i32* @val }
+; IMPORT-NEXT: @_ZL3Obj.llvm.{{.*}} = available_externally hidden constant %struct.S { i32 4, i32 8, ptr @val }
; IMPORT-NEXT: @outer = internal local_unnamed_addr global %struct.Q zeroinitializer
; OPT: @outer = internal unnamed_addr global %struct.Q zeroinitializer
; OPT: define dso_local i32 @main()
; OPT-NEXT: entry:
-; OPT-NEXT: store %struct.S* null, %struct.S** getelementptr inbounds (%struct.Q, %struct.Q* @outer, i64 0, i32 0)
+; OPT-NEXT: store ptr null, ptr getelementptr inbounds (%struct.Q, ptr @outer, i64 1, i32 0)
; OPT-NEXT: ret i32 12
; NOREFS: @_ZL3Obj.llvm.{{.*}} = external hidden constant %struct.S
diff --git a/llvm/test/ThinLTO/X86/import-dsolocal.ll b/llvm/test/ThinLTO/X86/import-dsolocal.ll
index 11d41e70e19b6..aea53cfcd0743 100644
--- a/llvm/test/ThinLTO/X86/import-dsolocal.ll
+++ b/llvm/test/ThinLTO/X86/import-dsolocal.ll
@@ -21,21 +21,21 @@
; RUN: llvm-dis %t2.1.3.import.bc -o - | FileCheck %s --check-prefixes=DEST,DEST2
; DEST: @a = available_externally global i32 42, align 4
-; DEST-NEXT: @b = external global i32*, align 8
+; DEST-NEXT: @b = external global ptr, align 8
; DEST: declare void @linkonce()
; DEST: declare void @weak()
; DEST: define dso_local i32 @main()
; DEST: define available_externally void @extern()
-; DEST1: declare i32 @extern_aux(i32*, i32**)
-; DEST1: declare i32 @linkonceodr_aux(i32*, i32**)
-; DEST2: define available_externally i32 @extern_aux(i32* %a, i32** %b)
-; DEST2: define available_externally i32 @linkonceodr_aux(i32* %a, i32** %b)
+; DEST1: declare i32 @extern_aux(ptr, ptr)
+; DEST1: declare i32 @linkonceodr_aux(ptr, ptr)
+; DEST2: define available_externally i32 @extern_aux(ptr %a, ptr %b)
+; DEST2: define available_externally i32 @linkonceodr_aux(ptr %a, ptr %b)
; DEST: define available_externally void @weakodr()
-; DEST1: declare i32 @weakodr_aux(i32*, i32**)
-; DEST2: define available_externally i32 @weakodr_aux(i32* %a, i32** %b)
+; DEST1: declare i32 @weakodr_aux(ptr, ptr)
+; DEST2: define available_externally i32 @weakodr_aux(ptr %a, ptr %b)
;--- a.ll
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/ThinLTO/X86/index-const-prop-gvref-pie.ll b/llvm/test/ThinLTO/X86/index-const-prop-gvref-pie.ll
index 62c4164594c32..85eacf4d8baed 100644
--- a/llvm/test/ThinLTO/X86/index-const-prop-gvref-pie.ll
+++ b/llvm/test/ThinLTO/X86/index-const-prop-gvref-pie.ll
@@ -6,7 +6,7 @@
; RUN: llvm-dis %t3.2.3.import.bc -o - | FileCheck %s --check-prefix=DEST
;; For PIE, keep dso_local for declarations to enable direct access.
-; DEST: @b = external dso_local global i32*
+; DEST: @b = external dso_local global ptr
; DEST-NEXT: @a = available_externally dso_local global i32 42, align 4
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/ThinLTO/X86/index-const-prop-gvref.ll b/llvm/test/ThinLTO/X86/index-const-prop-gvref.ll
index 293eb1dc33a66..069285f8eb377 100644
--- a/llvm/test/ThinLTO/X86/index-const-prop-gvref.ll
+++ b/llvm/test/ThinLTO/X86/index-const-prop-gvref.ll
@@ -12,13 +12,13 @@
; RUN: llvm-dis %t4.2.3.import.bc -o - | FileCheck %s --check-prefix=DEST_DSO
; No variable in the source module should have been internalized
-; SRC: @b = dso_local global i32* @a
+; SRC: @b = dso_local global ptr @a
; SRC-NEXT: @a = dso_local global i32 42
; We can't internalize globals referenced by other live globals
-; DEST: @b = external dso_local global i32*
+; DEST: @b = external dso_local global ptr
; DEST-NEXT: @a = available_externally dso_local global i32 42, align 4
-; DEST_DSO: @b = external global i32*
+; DEST_DSO: @b = external global ptr
; DEST_DSO-NEXT: @a = available_externally global i32 42, align 4
;; Test old API.
diff --git a/llvm/test/ThinLTO/X86/index-const-prop-linkage.ll b/llvm/test/ThinLTO/X86/index-const-prop-linkage.ll
index 80f3f11e2c543..c94224cda7c47 100644
--- a/llvm/test/ThinLTO/X86/index-const-prop-linkage.ll
+++ b/llvm/test/ThinLTO/X86/index-const-prop-linkage.ll
@@ -9,7 +9,7 @@
; - common linkage
; - available_externally linkage
; - reference from @llvm.used
-; CHECK: @llvm.used = appending global [1 x i32*] [i32* @g2]
+; CHECK: @llvm.used = appending global [1 x ptr] [ptr @g2]
; CHECK-NEXT: @g1 = external global i32, align 4
; CHECK-NEXT: @g2 = available_externally global i32 42, align 4
; CHECK-NEXT: @g3 = available_externally global i32 42, align 4
diff --git a/llvm/test/ThinLTO/X86/reference_non_importable.ll b/llvm/test/ThinLTO/X86/reference_non_importable.ll
index a488b2432f7bd..e36bf370d813a 100644
--- a/llvm/test/ThinLTO/X86/reference_non_importable.ll
+++ b/llvm/test/ThinLTO/X86/reference_non_importable.ll
@@ -22,7 +22,7 @@ target triple = "x86_64-apple-macosx10.11.0"
; We want foo to be imported in the main module!
; RUN: llvm-dis < %t.o.2.3.import.bc | FileCheck %s --check-prefix=IMPORT
-; IMPORT: define available_externally dso_local i8** @foo()
+; IMPORT: define available_externally dso_local ptr @foo()
define i8 **@foo() {
ret i8 **@b
}
diff --git a/llvm/test/ThinLTO/X86/weak_externals.ll b/llvm/test/ThinLTO/X86/weak_externals.ll
index 83e0e0ecd6110..c731cd5d533e7 100644
--- a/llvm/test/ThinLTO/X86/weak_externals.ll
+++ b/llvm/test/ThinLTO/X86/weak_externals.ll
@@ -10,9 +10,9 @@
; RUN: llvm-dis %t.out.1.2.internalize.bc -o - | FileCheck %s --check-prefix=INTERNALIZE
; CHECK: @_ZZN9SingletonI1SE11getInstanceEvE8instance = available_externally dso_local global %struct.S zeroinitializer
-; CHECK: @_ZZN9SingletonI1SE11getInstanceEvE13instance_weak = available_externally dso_local global %struct.S* null, align 8
-; CHECK: define linkonce_odr dso_local dereferenceable(16) %struct.S* @_ZN9SingletonI1SE11getInstanceEv() comdat
-; INTERNALIZE: define internal dereferenceable(16) %struct.S* @_ZN9SingletonI1SE11getInstanceEv()
+; CHECK: @_ZZN9SingletonI1SE11getInstanceEvE13instance_weak = available_externally dso_local global ptr null, align 8
+; CHECK: define linkonce_odr dso_local dereferenceable(16) ptr @_ZN9SingletonI1SE11getInstanceEv() comdat
+; INTERNALIZE: define internal dereferenceable(16) ptr @_ZN9SingletonI1SE11getInstanceEv()
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index 019bfe07e026f..a9814c650f055 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -208,6 +208,8 @@ namespace options {
static std::string stats_file;
// Asserts that LTO link has whole program visibility
static bool whole_program_visibility = false;
+ // Use opaque pointer types.
+ static bool opaque_pointers = true;
// Optimization remarks filename, accepted passes and hotness options
static std::string RemarksFilename;
@@ -308,6 +310,10 @@ namespace options {
RemarksFormat = std::string(opt);
} else if (opt.consume_front("stats-file=")) {
stats_file = std::string(opt);
+ } else if (opt == "opaque-pointers") {
+ opaque_pointers = true;
+ } else if (opt == "no-opaque-pointers") {
+ opaque_pointers = false;
} else {
// Save this option to pass to the code generator.
// ParseCommandLineOptions() expects argv[0] to be program name. Lazily
@@ -957,6 +963,8 @@ static std::unique_ptr<LTO> createLTO(IndexWriteCallback OnIndexWrite,
Conf.HasWholeProgramVisibility = options::whole_program_visibility;
+ Conf.OpaquePointers = options.opaque_pointers;
+
Conf.StatsFile = options::stats_file;
return std::make_unique<LTO>(std::move(Conf), Backend,
options::ParallelCodeGenParallelismLevel);
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index a4ba5457b067a..ca563f2885698 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -143,6 +143,10 @@ static cl::opt<bool>
cl::desc("Run PGO context sensitive IR instrumentation"),
cl::init(false), cl::Hidden);
+static cl::opt<bool> LtoOpaquePointers("lto-opaque-pointers",
+ cl::desc("Enable opaque pointer types"),
+ cl::init(true), cl::Hidden);
+
static cl::opt<bool>
DebugPassManager("debug-pass-manager", cl::init(false), cl::Hidden,
cl::desc("Print pass management debugging information"));
@@ -291,6 +295,7 @@ static int run(int argc, char **argv) {
Conf.StatsFile = StatsFile;
Conf.PTO.LoopVectorization = Conf.OptLevel > 1;
Conf.PTO.SLPVectorization = Conf.OptLevel > 1;
+ Conf.OpaquePointers = LtoOpaquePointers;
ThinBackend Backend;
if (ThinLTODistributedIndexes)
More information about the cfe-commits
mailing list