[AArch64][GlobalISel] Select csinc if a select has a 1 on RHS.

Differential Revision: https://reviews.llvm.org/D89513
This commit is contained in:
Amara Emerson 2020-10-15 15:44:27 -07:00
parent d4aac67859
commit 4ad459997e
2 changed files with 53 additions and 1 deletions

View File

@ -4119,7 +4119,8 @@ bool AArch64InstructionSelector::tryOptSelect(MachineInstr &I) const {
MachineIRBuilder MIB(I);
MachineRegisterInfo &MRI = *MIB.getMRI();
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
Register SrcReg1 = I.getOperand(2).getReg();
Register SrcReg2 = I.getOperand(3).getReg();
// We want to recognize this pattern:
//
// $z = G_FCMP pred, $x, $y
@ -4208,6 +4209,31 @@ bool AArch64InstructionSelector::tryOptSelect(MachineInstr &I) const {
}
// Emit the select.
// We may also be able to emit a CSINC if the RHS operand is a 1.
const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg1, MRI, TRI);
auto ValAndVReg =
getConstantVRegValWithLookThrough(SrcReg2, MRI);
if (SrcRB.getID() == AArch64::GPRRegBankID && ValAndVReg &&
ValAndVReg->Value == 1) {
unsigned Size = MRI.getType(SrcReg1).getSizeInBits();
unsigned Opc = 0;
Register Zero;
if (Size == 64) {
Opc = AArch64::CSINCXr;
Zero = AArch64::XZR;
} else {
Opc = AArch64::CSINCWr;
Zero = AArch64::WZR;
}
auto CSINC =
MIB.buildInstr(Opc, {I.getOperand(0).getReg()}, {SrcReg1, Zero})
.addImm(CondCode);
constrainSelectedInstRegOperands(*CSINC, TII, TRI, RBI);
I.eraseFromParent();
return true;
}
unsigned CSelOpc = selectSelectOpc(I, MRI, RBI);
auto CSel =
MIB.buildInstr(CSelOpc, {I.getOperand(0).getReg()},

View File

@ -97,3 +97,29 @@ body: |
$w0 = COPY %select(s32)
RET_ReallyLR implicit $w0
...
---
name: csinc
alignment: 4
legalized: true
regBankSelected: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0, $w1
; CHECK-LABEL: name: csinc
; CHECK: liveins: $w0, $w1
; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY $w0
; CHECK: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri [[COPY]], 1, 0, implicit-def $nzcv
; CHECK: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr [[COPY]], $wzr, 0, implicit $nzcv
; CHECK: $w0 = COPY [[CSINCWr]]
; CHECK: RET_ReallyLR implicit $w0
%0:gpr(s32) = COPY $w0
%1:gpr(s32) = COPY $w1
%2:gpr(s32) = G_CONSTANT i32 1
%5:gpr(s32) = G_ICMP intpred(eq), %0(s32), %2
%3:gpr(s1) = G_TRUNC %5(s32)
%4:gpr(s32) = G_SELECT %3(s1), %0, %2
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...