GlobalISel: select G_[SU]MULH on AArch64.

Hopefully this'll be nuked by tablegen pretty soon, but until then it's
reasonably important for supporting C++ operator new[].

llvm-svn: 294520
This commit is contained in:
Tim Northover 2017-02-08 21:22:25 +00:00
parent 2ea0d1ebe3
commit 97b8d6d2b6
2 changed files with 58 additions and 0 deletions

View File

@ -715,6 +715,34 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
case TargetOpcode::G_SMULH:
case TargetOpcode::G_UMULH: {
// Reject the various things we don't support yet.
if (unsupportedBinOp(I, RBI, MRI, TRI))
return false;
const unsigned DefReg = I.getOperand(0).getReg();
const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
if (RB.getID() != AArch64::GPRRegBankID) {
DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n");
return false;
}
if (Ty != LLT::scalar(64)) {
DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty
<< ", expected: " << LLT::scalar(64) << '\n');
return false;
}
unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr
: AArch64::UMULHrr;
I.setDesc(TII.get(NewOpc));
// Now that we selected an opcode, we need to constrain the register
// operands to use appropriate classes.
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
case TargetOpcode::G_MUL: {
// Reject the various things we don't support yet.
if (unsupportedBinOp(I, RBI, MRI, TRI))

View File

@ -36,6 +36,8 @@
define void @mul_s32_gpr() { ret void }
define void @mul_s64_gpr() { ret void }
define void @mulh_s64_gpr() { ret void }
define void @sdiv_s32_gpr() { ret void }
define void @sdiv_s64_gpr() { ret void }
@ -698,6 +700,34 @@ body: |
%2(s64) = G_MUL %0, %1
...
---
# Same as mul_s32_gpr for the s64 type.
# CHECK-LABEL: name: mulh_s64_gpr
name: mulh_s64_gpr
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-NEXT: - { id: 1, class: gpr64 }
# CHECK-NEXT: - { id: 2, class: gpr64 }
# CHECK-NEXT: - { id: 3, class: gpr64 }
# CHECK: body:
# CHECK: %0 = COPY %x0
# CHECK: %1 = COPY %x1
# CHECK: %2 = SMULHrr %0, %1
# CHECK: %3 = UMULHrr %0, %1
body: |
bb.0:
liveins: %x0, %x1
%0:gpr(s64) = COPY %x0
%1:gpr(s64) = COPY %x1
%2:gpr(s64) = G_SMULH %0, %1
%3:gpr(s64) = G_UMULH %0, %1
...
---
# Same as add_s32_gpr, for G_SDIV operations.
# CHECK-LABEL: name: sdiv_s32_gpr