[ARM] GlobalISel: Add support for G_TRUNC

Select them as copies. We only select if both the source and the
destination are on the same register bank, so this shouldn't cause any
trouble.

llvm-svn: 300971
This commit is contained in:
Diana Picus 2017-04-21 13:16:50 +00:00
parent 4df04ec227
commit 64a33431eb
5 changed files with 103 additions and 6 deletions

View File

@ -47,12 +47,9 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
unsigned SrcReg = I.getOperand(1).getReg();
const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
(void)SrcSize;
assert((DstSize == SrcSize ||
// Copies are a means to setup initial types, the number of
// bits may not exactly match.
(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
DstSize <= SrcSize)) &&
"Copy with different width?!");
// We use copies for trunc, so it's ok for the size of the destination to be
// smaller (the higher bits will just be undefined).
assert(DstSize <= SrcSize && "Copy with different width?!");
assert((RegBank->getID() == ARM::GPRRegBankID ||
RegBank->getID() == ARM::FPRRegBankID) &&
@ -294,6 +291,28 @@ bool ARMInstructionSelector::select(MachineInstr &I) const {
}
break;
}
case G_TRUNC: {
// The high bits are undefined, so there's nothing special to do, just
// treat it as a copy.
auto SrcReg = I.getOperand(1).getReg();
auto DstReg = I.getOperand(0).getReg();
const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
if (SrcRegBank.getID() != DstRegBank.getID()) {
DEBUG(dbgs() << "G_TRUNC operands on different register banks\n");
return false;
}
if (SrcRegBank.getID() != ARM::GPRRegBankID) {
DEBUG(dbgs() << "G_TRUNC on non-GPR not supported yet\n");
return false;
}
I.setDesc(TII.get(COPY));
return selectCopy(I, TII, MRI, TRI, RBI);
}
case G_ADD:
case G_GEP:
I.setDesc(TII.get(ARM::ADDrr));

View File

@ -223,6 +223,7 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_MUL:
case G_SEXT:
case G_ZEXT:
case G_TRUNC:
case G_GEP:
// FIXME: We're abusing the fact that everything lives in a GPR for now; in
// the real world we would use different mappings.

View File

@ -5,6 +5,8 @@
define void @test_sext_s8() { ret void }
define void @test_zext_s16() { ret void }
define void @test_trunc_s32_16() { ret void }
define void @test_add_s8() { ret void }
define void @test_add_s16() { ret void }
define void @test_add_s32() { ret void }
@ -142,6 +144,34 @@ body: |
; CHECK: BX_RET 14, _, implicit %r0
...
---
name: test_trunc_s32_16
# CHECK-LABEL: name: test_trunc_s32_16
legalized: true
regBankSelected: true
selected: false
# CHECK: selected: true
registers:
- { id: 0, class: gprb }
- { id: 1, class: gprb }
# CHECK-DAG: id: 0, class: gpr
# CHECK-DAG: id: 1, class: gpr
body: |
bb.0:
liveins: %r0
%0(s32) = COPY %r0
; CHECK: [[VREGX:%[0-9]+]] = COPY %r0
%1(s16) = G_TRUNC %0(s32)
; CHECK: [[VREGTRUNC:%[0-9]+]] = COPY [[VREGX]]
%r0 = COPY %1(s16)
; CHECK: %r0 = COPY [[VREGTRUNC]]
BX_RET 14, _, implicit %r0
; CHECK: BX_RET 14, _, implicit %r0
...
---
name: test_add_s8
# CHECK-LABEL: name: test_add_s8
legalized: true

View File

@ -40,6 +40,30 @@ entry:
ret i16 %x
}
define void @test_trunc_i32_i16(i32 %v, i16 *%p) {
; CHECK-LABEL: test_trunc_i32_i16:
; The trunc doesn't result in any instructions, but we
; expect the store to be explicitly 16-bit.
; CHECK: strh r0, [r1]
; CHECK: bx lr
entry:
%v16 = trunc i32 %v to i16
store i16 %v16, i16 *%p
ret void
}
define void @test_trunc_i32_i8(i32 %v, i8 *%p) {
; CHECK-LABEL: test_trunc_i32_i8:
; The trunc doesn't result in any instructions, but we
; expect the store to be explicitly 8-bit.
; CHECK: strb r0, [r1]
; CHECK: bx lr
entry:
%v8 = trunc i32 %v to i8
store i8 %v8, i8 *%p
ret void
}
define i8 @test_add_i8(i8 %x, i8 %y) {
; CHECK-LABEL: test_add_i8:
; CHECK: add r0, r0, r1

View File

@ -22,6 +22,8 @@
define void @test_constants() { ret void }
define void @test_trunc_s32_16() { ret void }
define void @test_fadd_s32() #0 { ret void }
define void @test_fadd_s64() #0 { ret void }
@ -442,6 +444,27 @@ body: |
BX_RET 14, _, implicit %r0
...
---
name: test_trunc_s32_16
# CHECK-LABEL: name: test_trunc_s32_16
legalized: true
regBankSelected: false
selected: false
# CHECK: registers:
# CHECK: - { id: 0, class: gprb }
# CHECK: - { id: 1, class: gprb }
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
body: |
bb.0:
liveins: %r0
%0(s32) = COPY %r0
%1(s16) = G_TRUNC %0(s32)
%r0 = COPY %1(s16)
BX_RET 14, _, implicit %r0
...
---
name: test_fadd_s32
# CHECK-LABEL: name: test_fadd_s32
legalized: true