summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-02-08 21:22:25 +0000
committerTim Northover <tnorthover@apple.com>2017-02-08 21:22:25 +0000
commit9dd78f8a6d37a4c3a66ea79eaec1830cc8edf55e (patch)
tree013b14020663c2c4343caa0f0e318f0743f8ac92
parent0a9b27933a7aa84d04f133096727e94300dfc3be (diff)
downloadbcm5719-llvm-9dd78f8a6d37a4c3a66ea79eaec1830cc8edf55e.tar.gz
bcm5719-llvm-9dd78f8a6d37a4c3a66ea79eaec1830cc8edf55e.zip
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
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp28
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir30
2 files changed, 58 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 6981194525f..42b4daf2318 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -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))
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
index 6b8a9900039..c07dd60ee6a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
@@ -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 }
@@ -699,6 +701,34 @@ body: |
...
---
+# 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
name: sdiv_s32_gpr
OpenPOWER on IntegriCloud