
addr matching was the only gatekeeper for starting selecting G_LOAD and G_STORE using SDAG patterns. * Introduce a complex renderer gi_addr for addr. In this patch only the existing functionality has been implemented. The renderer's name is the same as in SDAG: selectAddr. Apparently the type of GIComplexOperandMatcher doesn't matter as RISCV also uses s32 for both 64 and 32 bit pointers. * X86SelectAddress now is used for both: pattern matching and manual selection. As a result it accumulates all the code that previously was distributed among different selection functions. * Replace getLoadStoreOp with getPtrLoadStoreOp in Load/Store selector as GlobalISel matcher or emitter can't map the pointer type into i32/i64 types used in SDAG patterns for pointers. So the load and store selection of pointers is still manual. getLoadStoreOp is still present because it is used in G_FCONSTANT lowering that requires extra efforts to select it using SDAG patterns. * Since truncating stores are not supported, we custom legalize them by matching types of store and MMO. * Introduce a constant pool flag in X86AddressMode because otherwise we need to introduce a GlobalISel copy for X86ISelAddressMode. * Also please notice in the tests that GlobalISel prefers to fold memory operands immediately comparing to SDAG. The reason is that GlobalISel doesn't have target hooks in GIM_CheckIsSafeToFold. Or maybe another check on profitability is required along with safety check that is currently not present.
83 lines
3.0 KiB
YAML
83 lines
3.0 KiB
YAML
# RUN: llc -mtriple=i386-linux-gnu -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32ALL --check-prefix=X32
|
|
# RUN: llc -mtriple=x86_64-linux-gnux32 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32ALL --check-prefix=X32ABI
|
|
|
|
--- |
|
|
|
|
@g_int = dso_local global i32 0, align 4
|
|
|
|
define dso_local void @test_global_ptrv() {
|
|
entry:
|
|
store ptr @g_int, ptr undef
|
|
ret void
|
|
}
|
|
|
|
define dso_local i32 @test_global_valv() {
|
|
entry:
|
|
%0 = load i32, ptr @g_int, align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
...
|
|
---
|
|
name: test_global_ptrv
|
|
# CHECK-LABEL: name: test_global_ptrv
|
|
alignment: 16
|
|
legalized: true
|
|
regBankSelected: true
|
|
# X32: registers:
|
|
# X32-NEXT: - { id: 0, class: gr32, preferred-register: '', flags: [ ] }
|
|
# X32-NEXT: - { id: 1, class: gr32, preferred-register: '', flags: [ ] }
|
|
#
|
|
# X32ABI: registers:
|
|
# X32ABI-NEXT: - { id: 0, class: low32_addr_access, preferred-register: '', flags: [ ] }
|
|
# X32ABI-NEXT: - { id: 1, class: gr32, preferred-register: '', flags: [ ] }
|
|
registers:
|
|
- { id: 0, class: gpr, preferred-register: '' }
|
|
- { id: 1, class: gpr, preferred-register: '' }
|
|
# X32: %0:gr32 = IMPLICIT_DEF
|
|
# X32-NEXT: %1:gr32 = LEA32r $noreg, 1, $noreg, @g_int, $noreg
|
|
# X32-NEXT: MOV32mr %0, 1, $noreg, 0, $noreg, %1 :: (store (p0) into `ptr undef`)
|
|
# X32-NEXT: RET 0
|
|
#
|
|
# X32ABI: %0:low32_addr_access = IMPLICIT_DEF
|
|
# X32ABI-NEXT: %1:gr32 = LEA64_32r $noreg, 1, $noreg, @g_int, $noreg
|
|
# X32ABI-NEXT: MOV32mr %0, 1, $noreg, 0, $noreg, %1 :: (store (p0) into `ptr undef`)
|
|
# X32ABI-NEXT: RET 0
|
|
body: |
|
|
bb.1.entry:
|
|
liveins: $rdi
|
|
|
|
%0(p0) = IMPLICIT_DEF
|
|
%1(p0) = G_GLOBAL_VALUE @g_int
|
|
G_STORE %1(p0), %0(p0) :: (store (p0) into `ptr undef`)
|
|
RET 0
|
|
|
|
...
|
|
---
|
|
name: test_global_valv
|
|
# CHECK-LABEL: name: test_global_valv
|
|
alignment: 16
|
|
legalized: true
|
|
regBankSelected: true
|
|
# X32ALL: registers:
|
|
# X32ALL-NEXT: - { id: 0, class: gr32, preferred-register: '', flags: [ ] }
|
|
# X32ALL-NEXT: - { id: 1, class: gpr, preferred-register: '', flags: [ ] }
|
|
registers:
|
|
- { id: 0, class: gpr, preferred-register: '' }
|
|
- { id: 1, class: gpr, preferred-register: '' }
|
|
# X32: %0:gr32 = MOV32rm $noreg, 1, $noreg, @g_int, $noreg :: (load (s32) from @g_int)
|
|
# X32-NEXT: $eax = COPY %0
|
|
# X32-NEXT: RET 0, implicit $eax
|
|
#
|
|
# X32ABI: %0:gr32 = MOV32rm $noreg, 1, $noreg, @g_int, $noreg :: (load (s32) from @g_int)
|
|
# X32ABI-NEXT: $eax = COPY %0
|
|
# X32ABI-NEXT: RET 0, implicit $eax
|
|
body: |
|
|
bb.1.entry:
|
|
%1(p0) = G_GLOBAL_VALUE @g_int
|
|
%0(s32) = G_LOAD %1(p0) :: (load (s32) from @g_int)
|
|
$eax = COPY %0(s32)
|
|
RET 0, implicit $eax
|
|
|
|
...
|