// We're keeping these builders around because we'll want to add support for
// floating point to them.
- auto &LoadStoreBuilder =
- getActionDefinitionsBuilder({G_LOAD, G_STORE})
- .legalForTypesWithMemDesc({
- {s1, p0, 8, 8},
- {s8, p0, 8, 8},
- {s16, p0, 16, 8},
- {s32, p0, 32, 8},
- {p0, p0, 32, 8}});
+ auto &LoadStoreBuilder = getActionDefinitionsBuilder({G_LOAD, G_STORE})
+ .legalForTypesWithMemDesc({{s1, p0, 8, 8},
+ {s8, p0, 8, 8},
+ {s16, p0, 16, 8},
+ {s32, p0, 32, 8},
+ {p0, p0, 32, 8}})
+ .unsupportedIfMemSizeNotPow2();
getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0});
getActionDefinitionsBuilder(G_GLOBAL_VALUE).legalFor({p0});
{G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FCONSTANT, G_FNEG})
.legalFor({s32, s64});
- LoadStoreBuilder.legalFor({{s64, p0}});
+ LoadStoreBuilder
+ .legalForTypesWithMemDesc({{s64, p0, 64, 32}})
+ .maxScalar(0, s32);
PhiBuilder.legalFor({s64});
getActionDefinitionsBuilder(G_FCMP).legalForCartesianProduct({s1},
# RUN: llc -mtriple arm-- -run-pass=legalizer %s -o - | FileCheck %s
-# RUN: llc -mtriple thumb-- -mattr=+v6t2 -run-pass=legalizer %s -o - | FileCheck %s
+# RUN: llc -mtriple thumbv7-- -run-pass=legalizer %s -o - | FileCheck %s
--- |
define void @test_legal_loads_stores() { ret void }
define void @test_load_from_stack() { ret void }
+ define void @test_load_store_64_vfp() #0 { ret void }
+ define void @test_load_store_64_novfp() #1 { ret void }
+
define void @test_gep() { ret void }
+
+ attributes #0 = { "target-features"="+vfp2" }
+ attributes #1 = { "target-features"="-vfp2" }
...
---
name: test_legal_loads_stores
BX_RET 14, $noreg, implicit $r0
...
---
+name: test_load_store_64_vfp
+# CHECK-LABEL: name: test_load_store_64_vfp
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins: $r0
+
+ ; Can't use the VFP support for unaligned operations, we need to use 32-bits
+ ; operations instead.
+ ; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0
+ ; CHECK-NEXT: [[V1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load 4, align 1)
+ ; CHECK-NEXT: [[OFF:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; CHECK-NEXT: [[OFFCOPY:%[0-9]+]]:_(s32) = COPY [[OFF]]
+ ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFCOPY]]
+ ; CHECK-NEXT: [[V2:%[0-9]+]]:_(s32) = G_LOAD [[ADDR2]](p0) :: (load 4, align 1)
+ ; CHECK-NEXT: G_STORE [[V1]](s32), [[ADDR1]](p0) :: (store 4, align 1)
+ ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFF]]
+ ; CHECK-NEXT: G_STORE [[V2]](s32), [[ADDR2]](p0) :: (store 4, align 1)
+ %0(p0) = COPY $r0
+ %1(s64) = G_LOAD %0(p0) :: (load 8, align 1)
+ G_STORE %1(s64), %0(p0) :: (store 8, align 1)
+
+ ; For word-aligned we can use VFP operations.
+ ; CHECK: [[V:%[0-9]+]]:_(s64) = G_LOAD %0(p0) :: (load 8, align 4)
+ ; CHECK: G_STORE [[V]](s64), %0(p0) :: (store 8, align 4)
+ %2(s64) = G_LOAD %0(p0) :: (load 8, align 4)
+ G_STORE %2(s64), %0(p0) :: (store 8, align 4)
+
+ BX_RET 14, $noreg
+...
+---
+name: test_load_store_64_novfp
+# CHECK-LABEL: name: test_load_store_64_novfp
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins: $r0
+
+ ; When we don't have VFP support, we need to use 32-bit operations.
+ ; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0
+ ; CHECK-NEXT: [[V1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load 4, align 1)
+ ; CHECK-NEXT: [[OFF:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; CHECK-NEXT: [[OFFCOPY:%[0-9]+]]:_(s32) = COPY [[OFF]]
+ ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFCOPY]]
+ ; CHECK-NEXT: [[V2:%[0-9]+]]:_(s32) = G_LOAD [[ADDR2]](p0) :: (load 4, align 1)
+ ; CHECK-NEXT: G_STORE [[V1]](s32), [[ADDR1]](p0) :: (store 4, align 1)
+ ; CHECK-NEXT: [[OFFCOPY:%[0-9]+]]:_(s32) = COPY [[OFF]]
+ ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFCOPY]]
+ ; CHECK-NEXT: G_STORE [[V2]](s32), [[ADDR2]](p0) :: (store 4, align 1)
+ %0(p0) = COPY $r0
+ %1(s64) = G_LOAD %0(p0) :: (load 8, align 1)
+ G_STORE %1(s64), %0(p0) :: (store 8, align 1)
+
+ ; CHECK: [[V1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load 4)
+ ; CHECK-NEXT: [[OFFCOPY:%[0-9]+]]:_(s32) = COPY [[OFF]]
+ ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFCOPY]]
+ ; CHECK-NEXT: [[V2:%[0-9]+]]:_(s32) = G_LOAD [[ADDR2]](p0) :: (load 4)
+ ; CHECK-NEXT: G_STORE [[V1]](s32), [[ADDR1]](p0) :: (store 4)
+ ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFF]]
+ ; CHECK-NEXT: G_STORE [[V2]](s32), [[ADDR2]](p0) :: (store 4)
+ %2(s64) = G_LOAD %0(p0) :: (load 8, align 4)
+ G_STORE %2(s64), %0(p0) :: (store 8, align 4)
+
+ BX_RET 14, $noreg
+...
+---
name: test_gep
# CHECK-LABEL: name: test_gep
legalized: false
# RUN: llc -mtriple arm-- -run-pass=legalizer %s -o - | FileCheck %s
--- |
- define void @test_load_store_64() #0 { ret void }
-
define void @test_constants_s64() { ret void }
define void @test_phi_s64() #0 { ret void }
attributes #0 = { "target-features"="+vfp2" }
...
---
-name: test_load_store_64
-# CHECK-LABEL: name: test_load_store_64
-legalized: false
-# CHECK: legalized: true
-regBankSelected: false
-selected: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _ }
- - { id: 1, class: _ }
- - { id: 2, class: _ }
- - { id: 3, class: _ }
- - { id: 4, class: _ }
- - { id: 5, class: _ }
- - { id: 6, class: _ }
-body: |
- bb.0:
- liveins: $r0
-
- ; These are legal, so we should find them unchanged in the output
- ; CHECK-DAG: G_STORE {{%[0-9]+}}(s64), %0(p0)
- ; CHECK-DAG: {{%[0-9]+}}:_(s64) = G_LOAD %0(p0)
- %0(p0) = COPY $r0
- %1(s64) = G_LOAD %0(p0) :: (load 8)
- G_STORE %1(s64), %0(p0) :: (store 8)
- BX_RET 14, $noreg
-...
----
name: test_constants_s64
# CHECK-LABEL: name: test_constants_s64
legalized: false