diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index e4fdad8265c86..1769b0ea21bdd 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4673,6 +4673,9 @@ def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">, def mmark_bti_property : Flag<["-"], "mmark-bti-property">, Group, HelpText<"Add .note.gnu.property with BTI to assembly files (AArch64 only)">; +def mno_large_global_group_reloc: Flag<["-"], "mno-large-global-group-reloc">, + Group, + HelpText<"Disable group relocation type for global value and symbol when code model is large">; def mno_bti_at_return_twice : Flag<["-"], "mno-bti-at-return-twice">, Group, HelpText<"Do not add a BTI instruction after a setjmp or other" diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 997ec2d491d02..8c2d12771e5a8 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5006,6 +5006,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.getLastArg(options::OPT_save_temps_EQ)) Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ); + if (Args.getLastArg(options::OPT_mno_large_global_group_reloc)){ + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mno-large-global-group-reloc"); + } + auto *MemProfArg = Args.getLastArg(options::OPT_fmemory_profile, options::OPT_fmemory_profile_EQ, options::OPT_fno_memory_profile); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index 8344e79f78e1e..5c602a0fd6964 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -66,6 +66,10 @@ namespace { #include "AArch64GenGlobalISel.inc" #undef GET_GLOBALISEL_PREDICATE_BITSET +static cl::opt DisableLargeGlobalGroupReloc( + "mno-large-global-group-reloc", + cl::desc("Disable group relocation type for global value and symbol when code model is large"), + cl::init(false)); class AArch64InstructionSelector : public InstructionSelector { public: @@ -2850,7 +2854,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) { I.setDesc(TII.get(AArch64::LOADgot)); I.getOperand(1).setTargetFlags(OpFlags); } else if (TM.getCodeModel() == CodeModel::Large && - !TM.isPositionIndependent()) { + !DisableLargeGlobalGroupReloc && !TM.isPositionIndependent()) { // Materialize the global using movz/movk instructions. materializeLargeCMVal(I, GV, OpFlags); I.eraseFromParent(); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir index 28d279d742164..dadde2d8f3342 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir @@ -2,6 +2,7 @@ # RUN: llc -mtriple=aarch64-unknown-unknown -o - -verify-machineinstrs -run-pass=instruction-select %s | FileCheck %s # RUN: llc -mtriple=aarch64-unknown-unknown -o - -verify-machineinstrs -run-pass=instruction-select -code-model=large %s | FileCheck %s --check-prefix=LARGE # RUN: llc -mtriple=aarch64-unknown-unknown -o - -verify-machineinstrs -run-pass=instruction-select -code-model=large -relocation-model=pic %s | FileCheck %s --check-prefix=LARGE-PIC +# RUN: llc -mtriple=aarch64-unknown-unknown -o - -verify-machineinstrs -run-pass=instruction-select -code-model=large -mno-large-global-group-reloc %s | FileCheck %s --check-prefix=NO-LARGE-GLOBAL-GROUP-RELOC --- | source_filename = "blockaddress.ll" target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" @@ -62,6 +63,16 @@ body: | ; LARGE-PIC-NEXT: BR [[MOVaddrBA]] ; LARGE-PIC-NEXT: {{ $}} ; LARGE-PIC-NEXT: bb.1.block (ir-block-address-taken %ir-block.block): + ; NO-LARGE-GLOBAL-GROUP-RELOC-LABEL: name: test_blockaddress + ; NO-LARGE-GLOBAL-GROUP-RELOC: bb.0 (%ir-block.0): + ; NO-LARGE-GLOBAL-GROUP-RELOC: [[MOVZXi:%[0-9]+]]:gpr64 = MOVZXi target-flags(aarch64-g0, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 0 + ; NO-LARGE-GLOBAL-GROUP-RELOC: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[MOVZXi]], target-flags(aarch64-g1, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 16 + ; NO-LARGE-GLOBAL-GROUP-RELOC: [[MOVKXi1:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi]], target-flags(aarch64-g2, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 32 + ; NO-LARGE-GLOBAL-GROUP-RELOC: [[MOVKXi2:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi1]], target-flags(aarch64-g3) blockaddress(@test_blockaddress, %ir-block.block), 48 + ; NO-LARGE-GLOBAL-GROUP-RELOC: [[MOVaddr:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @addr, target-flags(aarch64-pageoff, aarch64-nc) @addr + ; NO-LARGE-GLOBAL-GROUP-RELOC: STRXui [[MOVKXi2]], [[MOVaddr]], 0 :: (store (p0) into @addr) + ; NO-LARGE-GLOBAL-GROUP-RELOC: BR [[MOVKXi2]] + ; NO-LARGE-GLOBAL-GROUP-RELOC: bb.1.block (address-taken): bb.1 (%ir-block.0): %0:gpr(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block) %1:gpr(p0) = G_GLOBAL_VALUE @addr