33 Commits

Author SHA1 Message Date
Arthur Eubanks
6bbb73b4cb
[X86] Fix determining if globals with size <8 bits are large (#84975)
Previously any global under 8 bits would accidentally be considered 0
sized, which is considered a large global.
2024-03-12 12:43:29 -07:00
Arthur Eubanks
45219702e7 [test][X86] Precommit test for large data threshold and i1 global 2024-03-12 19:08:40 +00:00
Arthur Eubanks
198652a0ff
[X86] Treat __start_*/__stop_* symbols as large (#79909)
Followup to #79884.

The linker adds __start_foo/__stop_foo symbols pointing to the
beginning/end of the foo section. These can be far away from text, so
treat them as large symbols under the medium/large code models.
Performance to access these is almost certainly not important.
2024-01-29 21:00:16 -07:00
Arthur Eubanks
d6e07e0845
[X86] Treat __ehdr_start as large (#79884)
The __ehdr_start symbol is added by the linker and points to the ELF
file headers, which can be very far away from text. Treat it as a large
symbol under the medium/large code models. Performance to access
__ehdr_start is almost certainly not important.

There are a couple of other symbols that the linker adds [1], but this
is the most relevant one that may be far away from text.

[1]
547c395b27/lld/ELF/Writer.cpp (L226)
2024-01-29 14:25:40 -08:00
Arthur Eubanks
2366d53d8d
[X86] Fix more medium code model addressing modes (#75641)
By looking at whether a global is large instead of looking at the code
model.

This also fixes references to large data in the small code model.

We now always fold any 32-bit offset into the addressing mode with the
large code model since it uses 64-bit relocations.
2023-12-21 10:40:56 -08:00
Arthur Eubanks
b3e353d263
[X86] Don't use rip-relative lea to get a function address in medium static mode (#75656)
This essentially reverts https://reviews.llvm.org/D140593. Somewhere
along the line we properly fixed the medium code model to assume
functions are small, so now we get a 32-bit movl as desired.
2023-12-15 15:15:18 -08:00
Arthur Eubanks
239a41e8f2 Re-Reland [X86] Respect code models more when determining if a global reference can fit in 32 bits (#75386)
For non-GlobalValue references, the small and medium code models can use
32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.
Even the large code model can reference small objects with 32 bit
constants as long as we're in no-pic mode, or if the reference is offset
from the GOT.

Original commit broke the build...

First reland broke large PIC builds referencing small data since it was using GOTOFF as a 32-bit constant.
2023-12-14 14:12:37 -08:00
Arthur Eubanks
15617d14f7 Revert "Reland [X86] Respect code models more when determining if a global reference can fit in 32 bits (#75386)"
This reverts commit ec92d74a0ef89b9dd46aee6ec8aca6bfd3c66a54.

Breaks some compiler-rt tests, e.g. https://lab.llvm.org/buildbot/#/builders/37/builds/28834
2023-12-14 12:28:50 -08:00
Arthur Eubanks
ec92d74a0e Reland [X86] Respect code models more when determining if a global reference can fit in 32 bits (#75386)
For non-GlobalValue references, the small and medium code models can use
32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.
Even the large code model can reference small objects with 32 bit
constants as long as we're in no-pic mode, or if the reference is offset
from the GOT.

Original commit broke the build...
2023-12-14 09:49:35 -08:00
Arthur Eubanks
f0c03da63c
Revert "[X86] Respect code models more when determining if a global reference can fit in 32 bits" (#75500)
Reverts llvm/llvm-project#75386

Breaks build.
2023-12-14 09:32:55 -08:00
Arthur Eubanks
5e38ba26d2
[X86] Respect code models more when determining if a global reference can fit in 32 bits (#75386)
For non-GlobalValue references, the small and medium code models can use
32 bit constants.

For GlobalValue references, use TargetMachine::isLargeGlobalObject().
Look through aliases for determining if a GlobalValue is small or large.
Even the large code model can reference small objects with 32 bit
constants as long as we're in no-pic mode, or if the reference is offset
from the GOT.
2023-12-14 09:28:27 -08:00
Arthur Eubanks
e8f43883a0 [X86][test] Use separate check prefix in code-model-elf.ll
Since these will produce different results in upcoming changes.
2023-12-13 13:05:59 -08:00
Arthur Eubanks
f82c85d21f
[X86] Handle unsized types in TargetMachine::isLargeGlobalObject() (#74952)
isLargeGlobalObject() didn't handle opaque types, resulting in crashes.
2023-12-11 19:13:09 -08:00
Arthur Eubanks
3850131197
[X86] Handle ifuncs in TargetMachine::isLargeGlobalObject() (#74911)
isLargeGlobalObject() didn't handle GlobalIFuncs, resulting in crashes.

Treat ifuncs the same as normal Functions.
2023-12-11 19:01:44 -08:00
Arthur Eubanks
687e63a2bd
[X86] Allow accessing large globals in small code model (#74785)
This removes some assumptions that the small code model will only
reference "near" globals.

There are still some missing optimizations and wrong code sequences, but
I'd like to address those separately. This will require auditing any
checks of the code model in the X86 backend.
2023-12-08 11:09:54 -08:00
Arthur Eubanks
d8a04398f9 Reland [X86] With large code model, put functions into .ltext with large section flag (#73037)
So that when mixing small and large text, large text stays out of the
way of the rest of the binary.

This is useful for mixing precompiled small code model object files and
built-from-source large code model binaries so that the the text
sections don't get merged.

The reland fixes an issue where a function in the large code model would reference small data without GOTOFF.

This was incorrectly reverted in 76f78ecc789d58baa3a88b2fe2a57428f07e5362.
2023-12-01 14:23:44 -08:00
Dmitri Gribenko
76f78ecc78 Revert "Reland [X86] With large code model, put functions into .ltext with large section flag (#73037)"
This reverts commit 4bf8a688956a759b7b6b8d94f42d25c13c7af130.

This commit seems to be breaking the semantics of the
ObjectFile::isSectionText method, which breaks numba/llvmlite bindings.
2023-12-01 17:18:14 +01:00
Arthur Eubanks
4bf8a68895 Reland [X86] With large code model, put functions into .ltext with large section flag (#73037)
So that when mixing small and large text, large text stays out of the
way of the rest of the binary.

This is useful for mixing precompiled small code model object files and
built-from-source large code model binaries so that the the text
sections don't get merged.

The reland fixes an issue where a function in the large code model would reference small data without GOTOFF.
2023-11-30 15:17:17 -08:00
Arthur Eubanks
9b6b2a0cec
[X86] Use RIP-relative for non-globals in medium code model in classifyLocalReference() (#67070)
We only want to treat globals as potentially far away, not other things
like constants in the constant pool.
This matches the object file emission that only puts the large section
flag on globals.

Remove FIXME since the remaining differences are accesses to 0 sized
globals which are intentional.
2023-09-21 16:50:33 -07:00
Arthur Eubanks
1a8c69176e [X86] Use RIP-relative addressing for data under large data threshold for medium code model
Since those data are assumed to be within the relocation offset limit.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D150297
2023-09-19 11:14:45 -07:00
Arthur Eubanks
161544dced [test] Add zero size global test to code-model-elf.ll 2023-05-31 13:04:15 -07:00
Thomas Köppe
82be8a1d2b [X86] Emit RIP-relative access to local function in PIC medium code model
Currently, the medium code model for x86_64 emits position-dependent relocations (R_X86_64_64) for local functions, regardless of PIC or no-PIC mode. (This means generically that code compiled with the medium model cannot be linked into a position-independent executable.)

Example:

```
static int g(int n) {
  return 2 * n + 3;
}

void f(int(**p)(int)) {
  *p = g;
}
```

This results in:

```
Disassembly of section .text:

0000000000000000 <f>:
       0: 48 b8 00 00 00 00 00 00 00 00	movabs	rax, 0x0
       a: 48 89 07                     	mov	qword ptr [rdi], rax
       d: c3                           	ret
```

```
Relocation section '.rela.text' at offset 0xf0 contains 1 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000002  0000000200000001 R_X86_64_64            0000000000000000 .text + 10
```

This patch changes the behaviour to unconditionally emit a RIP-relative access, both in PIC and non-PIC mode. This fixes PIC mode, and is perhaps an improvement in non-PIC mode, too, since it results in a shorter instruction. A 32-bit relocation should suffice since the medium memory model demands that all code fit within 2GiB.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D140593
2022-12-28 11:14:39 -08:00
Nikita Popov
2f448bf509 [X86] Migrate tests to use opaque pointers (NFC)
Test updates were performed using:
https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34

These are only the test updates where the test passed without
further modification (which is almost all of them, as the backend
is largely pointer-type agnostic).
2022-06-22 14:38:25 +02:00
Roman Lebedev
0aef747b84
[NFC][X86][Codegen] Megacommit: mass-regenerate all check lines that were already autogenerated
The motivation is that the update script has at least two deviations
(`<...>@GOT`/`<...>@PLT`/ and not hiding pointer arithmetics) from
what pretty much all the checklines were generated with,
and most of the tests are still not updated, so each time one of the
non-up-to-date tests is updated to see the effect of the code change,
there is a lot of noise. Instead of having to deal with that each
time, let's just deal with everything at once.

This has been done via:
```
cd llvm-project/llvm/test/CodeGen/X86
grep -rl "; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py" | xargs -L1 <...>/llvm-project/llvm/utils/update_llc_test_checks.py --llc-binary <...>/llvm-project/build/bin/llc
```

Not all tests were regenerated, however.
2021-06-11 23:57:02 +03:00
Craig Topper
0248e24071 [X86][update_llc_test_checks] Use a less greedy regular expression for replacing constant pool labels in tests.
While working on D97208 I noticed that these greedy regular
expressions prevent tests from failing when (%rip) appears after
a constant pool label when it didn't before.

Reviewed By: RKSimon, pengfei

Differential Revision: https://reviews.llvm.org/D99460
2021-03-28 11:39:46 -07:00
Fangrui Song
a084c0388e [TargetMachine] Don't imply dso_local on function declarations in Reloc::Static model for ELF/wasm
clang/lib/CodeGen/CodeGenModule sets dso_local on applicable function declarations,
we don't need to duplicate the work in TargetMachine:shouldAssumeDSOLocal.
(Actually the long-term goal (started by r324535) is to drop TargetMachine::shouldAssumeDSOLocal.)

By not implying dso_local, we will respect dso_local/dso_preemptable specifiers
set by the frontend. This allows the proposed -fno-direct-access-external-data
option to work with -fno-pic and prevent a canonical PLT entry (SHN_UNDEF with non-zero st_value)
when taking the address of a function symbol.

This patch should be NFC in terms of the Clang emitted assembly because the case
we don't set dso_local is a case Clang sets dso_local. However, some tests don't
set dso_local on some function declarations and expose some differences. Most
tests have been fixed to be more robust in the previous commit.
2020-12-05 14:54:37 -08:00
Fangrui Song
961f31d8ad [TargetMachine] Don't imply dso_local on global variable declarations in Reloc::Static model
clang/lib/CodeGen/CodeGenModule sets dso_local on applicable global variables,
we don't need to duplicate the work in TargetMachine:shouldAssumeDSOLocal.
(Actually the long-term goal (started by r324535) is to remove as much
additional implied dso_local in TargetMachine:shouldAssumeDSOLocal as possible.)

By not implying dso_local, we will respect dso_local/dso_preemptable specifiers
set by the frontend. This allows the proposed -fno-direct-access-external-data
option to work with -fno-pic and prevent copy relocations.

This patch should be NFC in terms of the Clang behavior because the case we
don't set dso_local is a case Clang sets dso_local. However, some tests don't
set dso_local on some `external global` and expose some differences. Most tests
have been fixed to be more robust in previous commits.
2020-12-04 19:03:41 -08:00
Craig Topper
8c050070fb [X86] Fix a nullptr dereference in X86Subtarget::classifyLocalReference when compiling with -mcmodel=medium -fpic and using a constant pool
LowerConstantPool passes a nullptr into classifyLocalReference. The medium code model handling for PIC will try to deference it using isa. This patch switches to isa_and_nonnull.

Differential Revision: https://reviews.llvm.org/D80763
2020-05-28 17:20:42 -07:00
Fangrui Song
872c5fb143 [AsmPrinter] Don't generate .Lfoo$local for -fno-PIC and -fPIE
-fno-PIC and -fPIE code generally cannot be linked in -shared mode and there is no benefit accessing via local aliases.

Actually, a .Lfoo$local reference will be converted to a STT_SECTION (if no section relaxation) reference which will cause the section symbol (sizeof(Elf64_Sym)=24) to be generated.
2020-05-25 23:35:49 -07:00
Fangrui Song
5b22bcc2b7 [X86][ELF] Prefer to lower MC_GlobalAddress operands to .Lfoo$local
For a MC_GlobalAddress reference to a dso_local external GlobalValue with a definition, emit .Lfoo$local to avoid a relocation.

-fno-pic and -fpie can infer dso_local but -fpic cannot.  In the future,
we can explore the possibility of inferring dso_local with -fpic. As the
description of D73228 says, LLVM's existing IPO optimization behaviors
(like -fno-semantic-interposition) and a previous assembly behavior give
us enough license to be aggressive here.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D73230
2020-01-30 17:52:35 -08:00
Craig Topper
3fe4bd464c [X86] Fix tls variable lowering issue with large code model
Summary:
The problem here is the lowering for tls variable. Below is the DAG for the code.
SelectionDAG has 11 nodes:

t0: ch = EntryToken
      t8: i64,ch = load<(load 8 from `i8 addrspace(257)* null`, addrspace 257)> t0, Constant:i64<0>, undef:i64
        t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @x> 0 [TF=10]
      t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64
    t12: i64 = add t8, t11
  t4: i32,ch = load<(dereferenceable load 4 from @x)> t0, t12, undef:i64
t6: ch = CopyToReg t0, Register:i32 %0, t4
And when mcmodel is large, below instruction can NOT be folded.

  t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @x> 0 [TF=10]
t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64
So "t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64" is lowered to " Morphed node: t11: i64,ch = MOV64rm<Mem:(load 8 from got)> t10, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i32 $noreg, t0"

When llvm start to lower "t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @x> 0 [TF=10]", it fails.

The patch is to fold the load and X86ISD::WrapperRIP.

Fixes PR26906

Patch by LuoYuanke

Reviewers: craig.topper, rnk, annita.zhang, wxiao3

Reviewed By: rnk

Subscribers: llvm-commits

Tags: #llvm

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

llvm-svn: 354756
2019-02-24 19:33:37 +00:00
Reid Kleckner
49a24278ba [ELF] Fix large code model MIR verifier errors
Instead of using the MOVGOT64r pseudo, use the existing
MO_PIC_BASE_OFFSET support on symbol operands. Now I don't have to
create a "scratch register operand" for the pseudo to use, and the
register allocator can make better decisions.

Fixes some X86 verifier errors tracked in PR27481.

llvm-svn: 345219
2018-10-24 22:57:28 +00:00
Reid Kleckner
980c4df037 Re-land r335297 "[X86] Implement more of x86-64 large and medium PIC code models"
Don't try to generate large PIC code for non-ELF targets. Neither COFF
nor MachO have relocations for large position independent code, and
users have been using "large PIC" code models to JIT 64-bit code for a
while now. With this change, if they are generating ELF code, their
JITed code will truly be PIC, but if they target MachO or COFF, it will
contain 64-bit immediates that directly reference external symbols. For
a JIT, that's perfectly fine.

llvm-svn: 337740
2018-07-23 21:14:35 +00:00