Skip to content

Commit

Permalink
[AArch64][GlobalISel] Select G_MUL.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278810 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
ahmedbougacha committed Aug 16, 2016
1 parent c57071e commit cefc0d3
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/CodeGen/GlobalISel/InstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ bool InstructionSelector::constrainSelectedInstRegOperands(
DEBUG(dbgs() << "Converting operand: " << MO << '\n');
assert(MO.isReg() && "Unsupported non-reg operand");

// Physical registers don't need to be constrained.
if (TRI.isPhysicalRegister(MO.getReg()))
continue;

const TargetRegisterClass *RC = TII.getRegClass(I.getDesc(), OpI, &TRI, MF);
assert(RC && "Selected inst should have regclass operand");

Expand Down
37 changes: 37 additions & 0 deletions lib/Target/AArch64/AArch64InstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,43 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
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))
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_MUL on bank: " << RB << ", expected: GPR\n");
return false;
}

unsigned ZeroReg;
unsigned NewOpc;
if (Ty == LLT::scalar(32)) {
NewOpc = AArch64::MADDWrrr;
ZeroReg = AArch64::WZR;
} else if (Ty == LLT::scalar(64)) {
NewOpc = AArch64::MADDXrrr;
ZeroReg = AArch64::XZR;
} else {
DEBUG(dbgs() << "G_MUL has type: " << Ty << ", expected: "
<< LLT::scalar(32) << " or " << LLT::scalar(64) << '\n');
return false;
}

I.setDesc(TII.get(NewOpc));
I.removeTypes();

I.addOperand(MachineOperand::CreateReg(ZeroReg, /*isDef=*/false));

// 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_OR:
case TargetOpcode::G_XOR:
case TargetOpcode::G_AND:
Expand Down
63 changes: 63 additions & 0 deletions test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
define void @ashr_s32_gpr() { ret void }
define void @ashr_s64_gpr() { ret void }

define void @mul_s32_gpr() { ret void }
define void @mul_s64_gpr() { ret void }

define void @unconditional_br() { ret void }

define void @load_s64_gpr(i64* %addr) { ret void }
Expand Down Expand Up @@ -529,6 +532,66 @@ body: |
%2(64) = G_ASHR s64 %0, %1
...

# Check that we select s32 GPR G_MUL. This is trickier than other binops because
# there is only MADDWrrr, and we have to use the WZR physreg.
# CHECK-LABEL: name: mul_s32_gpr
name: mul_s32_gpr
isSSA: true
legalized: true
regBankSelected: true

# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# CHECK-NEXT: - { id: 1, class: gpr32 }
# CHECK-NEXT: - { id: 2, class: gpr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }

# CHECK: body:
# CHECK: %0 = COPY %w0
# CHECK: %1 = COPY %w1
# CHECK: %2 = MADDWrrr %0, %1, %wzr
body: |
bb.0:
liveins: %w0, %w1
%0(32) = COPY %w0
%1(32) = COPY %w1
%2(32) = G_MUL s32 %0, %1
...

---
# Same as mul_s32_gpr for the s64 type.
# CHECK-LABEL: name: mul_s64_gpr
name: mul_s64_gpr
isSSA: true
legalized: true
regBankSelected: true

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

# CHECK: body:
# CHECK: %0 = COPY %x0
# CHECK: %1 = COPY %x1
# CHECK: %2 = MADDXrrr %0, %1, %xzr
body: |
bb.0:
liveins: %x0, %x1
%0(64) = COPY %x0
%1(64) = COPY %x1
%2(64) = G_MUL s64 %0, %1
...

---
# CHECK-LABEL: name: unconditional_br
name: unconditional_br
Expand Down

0 comments on commit cefc0d3

Please sign in to comment.