Skip to content

Commit

Permalink
GlobalISel: support same-size casts on AArch64.
Browse files Browse the repository at this point in the history
Mostly Ahmed's work again, I'm just sprucing things up slightly before
committing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283952 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
TNorthover committed Oct 11, 2016
1 parent 426fd51 commit f8322a8
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
62 changes: 62 additions & 0 deletions lib/Target/AArch64/AArch64InstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ AArch64InstructionSelector::AArch64InstructionSelector(
: InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI) {}

// FIXME: This should be target-independent, inferred from the types declared
// for each class in the bank.
static const TargetRegisterClass *
getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB,
const RegisterBankInfo &RBI) {
if (RB.getID() == AArch64::GPRRegBankID) {
if (Ty.getSizeInBits() <= 32)
return &AArch64::GPR32RegClass;
if (Ty.getSizeInBits() == 64)
return &AArch64::GPR64RegClass;
return nullptr;
}

if (RB.getID() == AArch64::FPRRegBankID) {
if (Ty.getSizeInBits() == 32)
return &AArch64::FPR32RegClass;
if (Ty.getSizeInBits() == 64)
return &AArch64::FPR64RegClass;
if (Ty.getSizeInBits() == 128)
return &AArch64::FPR128RegClass;
return nullptr;
}

return nullptr;
}

/// Check whether \p I is a currently unsupported binary operation:
/// - it has an unsized type
/// - an operand is not a vreg
Expand Down Expand Up @@ -493,6 +519,42 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
I.eraseFromParent();
return true;
}

case TargetOpcode::G_INTTOPTR:
case TargetOpcode::G_PTRTOINT:
case TargetOpcode::G_BITCAST: {
const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
const LLT SrcTy = MRI.getType(I.getOperand(1).getReg());

const unsigned DstReg = I.getOperand(0).getReg();
const unsigned SrcReg = I.getOperand(1).getReg();

const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);

const TargetRegisterClass *DstRC =
getRegClassForTypeOnBank(DstTy, DstRB, RBI);
if (!DstRC)
return false;

const TargetRegisterClass *SrcRC =
getRegClassForTypeOnBank(SrcTy, SrcRB, RBI);
if (!SrcRC)
return false;

if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
DEBUG(dbgs() << "Failed to constrain G_BITCAST\n");
return false;
}

BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::COPY))
.addDef(DstReg)
.addUse(SrcReg);

I.eraseFromParent();
return true;
}
}

return false;
Expand Down
13 changes: 13 additions & 0 deletions lib/Target/AArch64/AArch64MachineLegalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,18 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() {
setAction({G_INTTOPTR, 0, p0}, Legal);
setAction({G_INTTOPTR, 1, s64}, Legal);

for (auto Ty : {s1, s8, s16, s32, s64}) {
setAction({G_BITCAST, 0, Ty}, Legal);
setAction({G_BITCAST, 1, Ty}, Legal);
}

for (int EltSize = 8; EltSize <= 64; EltSize *= 2) {
setAction({G_BITCAST, 0, LLT::vector(128/EltSize, EltSize)}, Legal);
if (EltSize == 64)
continue;

setAction({G_BITCAST, 0, LLT::vector(64/EltSize, EltSize)}, Legal);
}

computeTables();
}
31 changes: 31 additions & 0 deletions test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
define void @anyext_gpr() { ret void }
define void @zext_gpr() { ret void }
define void @sext_gpr() { ret void }

define void @casts() { ret void }
...

---
Expand Down Expand Up @@ -1423,3 +1425,32 @@ body: |
%2(s8) = COPY %w0
%3(s32) = G_SEXT %2
...

---
# CHECK-LABEL: name: casts
name: casts
legalized: true
regBankSelected: true

# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-NEXT: - { id: 1, class: fpr64 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: fpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }

# CHECK: body:
# CHECK: %0 = COPY %x0
# CHECK: %1 = COPY %0
# CHECK: %2 = COPY %0
# CHECK: %3 = COPY %2
body: |
bb.0:
liveins: %w0
%0(s64) = COPY %x0
%1(<8 x s8>) = G_BITCAST %0(s64)
%2(p0) = G_INTTOPTR %0
%3(s64) = G_PTRTOINT %2
...

0 comments on commit f8322a8

Please sign in to comment.