mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
GlobalISel: legalize 1-bit load/store and mark 8/16 bit variants legal on AArch64.
llvm-svn: 279548
This commit is contained in:
parent
3b30fbd4c0
commit
685dd8eded
@ -105,6 +105,8 @@ MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) {
|
||||
MachineLegalizeHelper::LegalizeResult
|
||||
MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
|
||||
unsigned WideSize = WideTy.getSizeInBits();
|
||||
MIRBuilder.setInstr(MI);
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
default:
|
||||
return UnableToLegalize;
|
||||
@ -117,9 +119,6 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
|
||||
// Perform operation at larger width (any extension is fine here, high bits
|
||||
// don't affect the result) and then truncate the result back to the
|
||||
// original type.
|
||||
|
||||
MIRBuilder.setInstr(MI);
|
||||
|
||||
unsigned Src1Ext = MRI.createGenericVirtualRegister(WideSize);
|
||||
unsigned Src2Ext = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildAnyExtend(WideTy, Src1Ext, MI.getOperand(1).getReg());
|
||||
@ -133,8 +132,29 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_LOAD: {
|
||||
assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
|
||||
"illegal to increase number of bytes loaded");
|
||||
|
||||
unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildLoad(WideTy, MI.getType(1), DstExt,
|
||||
MI.getOperand(1).getReg(), **MI.memoperands_begin());
|
||||
MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_STORE: {
|
||||
assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
|
||||
"illegal to increase number of bytes modified by a store");
|
||||
|
||||
unsigned SrcExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildAnyExtend(WideTy, SrcExt, MI.getOperand(0).getReg());
|
||||
MIRBuilder.buildStore(WideTy, MI.getType(1), SrcExt,
|
||||
MI.getOperand(1).getReg(), **MI.memoperands_begin());
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_CONSTANT: {
|
||||
MIRBuilder.setInstr(MI);
|
||||
unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildConstant(WideTy, DstExt, MI.getOperand(1).getImm());
|
||||
MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
|
||||
@ -142,7 +162,6 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) {
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_FCONSTANT: {
|
||||
MIRBuilder.setInstr(MI);
|
||||
unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildFConstant(WideTy, DstExt, *MI.getOperand(1).getFPImm());
|
||||
MIRBuilder.buildFPTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
|
||||
|
@ -51,10 +51,13 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() {
|
||||
for (auto Ty : {s32, s64})
|
||||
setAction(BinOp, Ty, Legal);
|
||||
|
||||
for (auto MemOp : {G_LOAD, G_STORE})
|
||||
for (auto Ty : {s32, s64})
|
||||
for (auto MemOp : {G_LOAD, G_STORE}) {
|
||||
for (auto Ty : {s8, s16, s32, s64})
|
||||
setAction(MemOp, Ty, Legal);
|
||||
|
||||
setAction(MemOp, s1, WidenScalar);
|
||||
}
|
||||
|
||||
for (auto Ty : {s32, s64}) {
|
||||
setAction(TargetOpcode::G_CONSTANT, Ty, Legal);
|
||||
setAction(TargetOpcode::G_FCONSTANT, Ty, Legal);
|
||||
|
84
test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir
Normal file
84
test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir
Normal file
@ -0,0 +1,84 @@
|
||||
# RUN: llc -O0 -run-pass=legalize-mir -global-isel %s -o - 2>&1 | FileCheck %s
|
||||
|
||||
--- |
|
||||
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
||||
target triple = "aarch64-apple-ios"
|
||||
define void @test_load(i8* %addr) {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
define void @test_store(i8* %addr) {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
...
|
||||
|
||||
---
|
||||
name: test_load
|
||||
isSSA: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
- { id: 3, class: _ }
|
||||
- { id: 4, class: _ }
|
||||
- { id: 5, class: _ }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_load
|
||||
%0(64) = COPY %x0
|
||||
|
||||
; CHECK: [[BIT8:%[0-9]+]](8) = G_LOAD { s8, p0 } %0 :: (load 1 from %ir.addr)
|
||||
; CHECK: %1(1) = G_TRUNC s1 [[BIT8]]
|
||||
%1(1) = G_LOAD { s1, p0 } %0 :: (load 1 from %ir.addr)
|
||||
|
||||
; CHECK: %2(8) = G_LOAD { s8, p0 } %0 :: (load 1 from %ir.addr)
|
||||
%2(8) = G_LOAD { s8, p0 } %0 :: (load 1 from %ir.addr)
|
||||
|
||||
; CHECK: %3(16) = G_LOAD { s16, p0 } %0 :: (load 2 from %ir.addr)
|
||||
%3(16) = G_LOAD { s16, p0 } %0 :: (load 2 from %ir.addr)
|
||||
|
||||
; CHECK: %4(32) = G_LOAD { s32, p0 } %0 :: (load 4 from %ir.addr)
|
||||
%4(32) = G_LOAD { s32, p0 } %0 :: (load 4 from %ir.addr)
|
||||
|
||||
; CHECK: %5(64) = G_LOAD { s64, p0 } %0 :: (load 8 from %ir.addr)
|
||||
%5(64) = G_LOAD { s64, p0 } %0 :: (load 8 from %ir.addr)
|
||||
...
|
||||
|
||||
---
|
||||
name: test_store
|
||||
isSSA: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
- { id: 3, class: _ }
|
||||
- { id: 4, class: _ }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_store
|
||||
|
||||
%0(64) = COPY %x0
|
||||
%1(32) = COPY %w1
|
||||
|
||||
; CHECK: [[BIT8:%[0-9]+]](8) = G_ANYEXTEND s8 %2
|
||||
; CHECK: G_STORE { s8, p0 } [[BIT8]], %0 :: (store 1 into %ir.addr)
|
||||
%2(1) = G_TRUNC s1 %1
|
||||
G_STORE { s1, p0 } %2, %0 :: (store 1 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE { s8, p0 } %3, %0 :: (store 1 into %ir.addr)
|
||||
%3(8) = G_TRUNC s8 %1
|
||||
G_STORE { s8, p0 } %3, %0 :: (store 1 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE { s16, p0 } %4, %0 :: (store 2 into %ir.addr)
|
||||
%4(16) = G_TRUNC s16 %1
|
||||
G_STORE { s16, p0 } %4, %0 :: (store 2 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE { s32, p0 } %1, %0 :: (store 4 into %ir.addr)
|
||||
G_STORE { s32, p0 } %1, %0 :: (store 4 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE { s64, p0 } %0, %0 :: (store 8 into %ir.addr)
|
||||
G_STORE { s64, p0 } %0, %0 :: (store 8 into %ir.addr)
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user