GlobalISel: support selecting G_SELECT on AArch64.

llvm-svn: 286185
This commit is contained in:
Tim Northover 2016-11-08 00:45:29 +00:00
parent 96999de55d
commit 9ac0eba672
2 changed files with 84 additions and 0 deletions

View File

@ -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"
@ -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

View File

@ -150,6 +150,7 @@
define void @phi() { ret void }
define void @select() { ret void }
...
---
@ -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
...