diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1281,8 +1281,9 @@ config->emitDataInCodeInfo = args.hasFlag(OPT_data_in_code_info, OPT_no_data_in_code_info, true); config->icfLevel = getICFLevel(args); - config->dedupLiterals = args.hasArg(OPT_deduplicate_literals) || - config->icfLevel != ICFLevel::none; + config->dedupLiterals = + args.hasFlag(OPT_deduplicate_literals, OPT_icf_eq, false) || + config->icfLevel != ICFLevel::none; config->warnDylibInstallName = args.hasFlag( OPT_warn_dylib_install_name, OPT_no_warn_dylib_install_name, false); config->callGraphProfileSort = args.hasFlag( diff --git a/lld/MachO/ld64-vs-lld.rst b/lld/MachO/ld64-vs-lld.rst --- a/lld/MachO/ld64-vs-lld.rst +++ b/lld/MachO/ld64-vs-lld.rst @@ -4,6 +4,13 @@ This doc lists all significant deliberate differences in behavior between LD64 and LLD-MachO. +``-no_deduplicate`` Flag +********************** +- LD64: + * This turns off ICF (deduplication pass) in the linker. +- LLD + * This turns off ICF and string merging in the linker. + ObjC symbols treatment ********************** There are differences in how LLD and LD64 handle ObjC symbols loaded from archives. diff --git a/lld/test/MachO/literal-dedup.s b/lld/test/MachO/literal-dedup.s --- a/lld/test/MachO/literal-dedup.s +++ b/lld/test/MachO/literal-dedup.s @@ -6,6 +6,29 @@ # RUN: llvm-objdump --macho --section="__TEXT,__literals" --section="__DATA,ptrs" --syms %t/test | FileCheck %s # RUN: llvm-readobj --section-headers %t/test | FileCheck %s --check-prefix=HEADER +## Make sure literal deduplication can be overridden or that the later flag wins. +# RUN: %lld -dylib --deduplicate-literals -no_deduplicate %t/test.o %t/qux.o -o %t/no-dedup-test +# RUN: llvm-objdump --macho --section="__TEXT,__literals" --section="__DATA,ptrs" %t/no-dedup-test | FileCheck %s --check-prefix=NO-DEDUP + +# RUN: %lld -dylib -no_deduplicate --deduplicate-literals %t/test.o %t/qux.o -o %t/test +# RUN: llvm-objdump --macho --section="__TEXT,__literals" --section="__DATA,ptrs" --syms %t/test | FileCheck %s +# RUN: llvm-readobj --section-headers %t/test | FileCheck %s --check-prefix=HEADER + +# NO-DEDUP-NOT: Contents of (__TEXT,__literals) section +# NO-DEDUP: Contents of (__DATA,ptrs) section +# NO-DEDUP-NEXT: __TEXT:__literal16:0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal16:0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal16:0xfeedface 0xfeedface 0xfeedface 0xfeedface +# NO-DEDUP-NEXT: __TEXT:__literal16:0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal8:0xdeadbeef 0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal8:0xdeadbeef 0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal8:0xfeedface 0xfeedface +# NO-DEDUP-NEXT: __TEXT:__literal8:0xdeadbeef 0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal4:0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal4:0xdeadbeef +# NO-DEDUP-NEXT: __TEXT:__literal4:0xfeedface +# NO-DEDUP-NEXT: __TEXT:__literal4:0xdeadbeef + # CHECK: Contents of (__TEXT,__literals) section # CHECK-NEXT: [[#%.16x,DEADBEEF16:]] ef be ad de ef be ad de ef be ad de ef be ad de # CHECK-NEXT: [[#%.16x,FEEDFACE16:]] ce fa ed fe ce fa ed fe ce fa ed fe ce fa ed fe diff --git a/lld/test/MachO/silent-ignore.s b/lld/test/MachO/silent-ignore.s --- a/lld/test/MachO/silent-ignore.s +++ b/lld/test/MachO/silent-ignore.s @@ -6,7 +6,6 @@ ## `--version` flag.) # RUN: %lld --version \ # RUN: -dynamic \ -# RUN: -no_deduplicate \ # RUN: -lto_library /lib/foo \ # RUN: -macosx_version_min 0 \ # RUN: -no_dtrace_dof \