Skip to content

Commit

Permalink
GlobalISel: support selecting G_SELECT on AArch64.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286185 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
TNorthover committed Nov 8, 2016
1 parent e7ffbb5 commit 7b11189
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/Target/AArch64/AArch64InstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "AArch64RegisterInfo.h"
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
Expand Down Expand Up @@ -952,6 +953,45 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
case TargetOpcode::G_BITCAST:
return selectCopy(I, TII, MRI, TRI, RBI);

case TargetOpcode::G_SELECT: {
if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) {
DEBUG(dbgs() << "G_SELECT cond has type: " << Ty
<< ", expected: " << LLT::scalar(1) << '\n');
return false;
}

const unsigned CondReg = I.getOperand(1).getReg();
const unsigned TReg = I.getOperand(2).getReg();
const unsigned FReg = I.getOperand(3).getReg();

unsigned CSelOpc = 0;

if (Ty == LLT::scalar(32)) {
CSelOpc = AArch64::CSELWr;
} else if (Ty == LLT::scalar(64)) {
CSelOpc = AArch64::CSELXr;
} else {
return false;
}

MachineInstr &TstMI =
*BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri))
.addDef(AArch64::WZR)
.addUse(CondReg)
.addImm(AArch64_AM::encodeLogicalImmediate(1, 32));

MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc))
.addDef(I.getOperand(0).getReg())
.addUse(TReg)
.addUse(FReg)
.addImm(AArch64CC::NE);

constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI);
constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI);

I.eraseFromParent();
return true;
}
case TargetOpcode::G_ICMP: {
if (Ty != LLT::scalar(1)) {
DEBUG(dbgs() << "G_ICMP result has type: " << Ty
Expand Down
44 changes: 44 additions & 0 deletions test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@

define void @phi() { ret void }

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

---
Expand Down Expand Up @@ -2874,3 +2875,46 @@ body: |
%s0 = COPY %2
RET_ReallyLR implicit %s0
...

---
# CHECK-LABEL: name: select
name: select
legalized: true
regBankSelected: true
tracksRegLiveness: true

# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# CHECK-NEXT: - { id: 1, class: gpr32 }
# CHECK-NEXT: - { id: 2, class: gpr32 }
# CHECK-NEXT: - { id: 3, class: gpr32 }
# CHECK-NEXT: - { id: 4, class: gpr64 }
# CHECK-NEXT: - { id: 5, class: gpr64 }
# CHECK-NEXT: - { id: 6, class: gpr64 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
- { id: 4, class: gpr }
- { id: 5, class: gpr }
- { id: 6, class: gpr }

# CHECK: body:
# CHECK: %wzr = ANDSWri %0, 0, implicit-def %nzcv
# CHECK: %3 = CSELWr %1, %2, 1, implicit %nzcv
# CHECK: %wzr = ANDSWri %0, 0, implicit-def %nzcv
# CHECK: %6 = CSELXr %4, %5, 1, implicit %nzcv
body: |
bb.0:
liveins: %w0, %w1, %w2
%0(s1) = COPY %w0
%1(s32) = COPY %w1
%2(s32) = COPY %w2
%3(s32) = G_SELECT %0, %1, %2
%4(s64) = COPY %x0
%5(s64) = COPY %x1
%6(s64) = G_SELECT %0, %4, %5
...

0 comments on commit 7b11189

Please sign in to comment.