[AArch64] Rewrite (add, csel) to cinc

Don't rewrite an add instruction with 2 SET_CC operands into a csel
instruction. The total instruction sequence uses an extra instruction and
register. Preventing this allows us to match a `(add, csel)` pattern and
rewrite this into a `cinc`.

Differential Revision: https://reviews.llvm.org/D98704
This commit is contained in:
Sjoerd Meijer 2021-03-16 11:53:43 +00:00
parent 3d0aed7936
commit 90ecb862a0
4 changed files with 59 additions and 6 deletions

View File

@ -13190,6 +13190,13 @@ static SDValue performSetccAddFolding(SDNode *Op, SelectionDAG &DAG) {
SDValue RHS = Op->getOperand(1);
SetCCInfoAndKind InfoAndKind;
// If both operands are a SET_CC, then we don't want to perform this
// folding and create another csel as this results in more instructions
// (and higher register usage).
if (isSetCCOrZExtSetCC(LHS, InfoAndKind) &&
isSetCCOrZExtSetCC(RHS, InfoAndKind))
return SDValue();
// If neither operand is a SET_CC, give up.
if (!isSetCCOrZExtSetCC(LHS, InfoAndKind)) {
std::swap(LHS, RHS);

View File

@ -2162,6 +2162,11 @@ def : Pat<(AArch64csel (i32 -1), GPR32:$fval, (i32 imm:$cc), NZCV),
def : Pat<(AArch64csel (i64 -1), GPR64:$fval, (i32 imm:$cc), NZCV),
(CSINVXr GPR64:$fval, XZR, (i32 (inv_cond_XFORM imm:$cc)))>;
def : Pat<(add GPR32:$val, (AArch64csel (i32 0), (i32 1), (i32 imm:$cc), NZCV)),
(CSINCWr GPR32:$val, GPR32:$val, (i32 imm:$cc))>;
def : Pat<(add GPR64:$val, (zext (AArch64csel (i32 0), (i32 1), (i32 imm:$cc), NZCV))),
(CSINCXr GPR64:$val, GPR64:$val, (i32 imm:$cc))>;
// The inverse of the condition code from the alias instruction is what is used
// in the aliased instruction. The parser all ready inverts the condition code
// for these aliases.

View File

@ -269,3 +269,44 @@ define i64 @foo23(i64 %x) {
%res = select i1 %cmp, i64 1, i64 6
ret i64 %res
}
define i16 @foo24(i8* nocapture readonly %A, i8* nocapture readonly %B) {
; CHECK-LABEL: foo24:
; CHECK: ldrb w[[W8:[0-9]+]], [x1]
; CHECK-NEXT: ldrb w[[W9:[0-9]+]], [x0]
; CHECK-NEXT: cmp w[[W8]], #33
; CHECK-NEXT: cset w[[W8]], hi
; CHECK-NEXT: cmp w[[W9]], #3
; CHECK-NEXT: cinc w0, w[[W8]], hi
; CHECK-NEXT: ret
entry:
%0 = load i8, i8* %A, align 1
%cmp = icmp ugt i8 %0, 3
%conv1 = zext i1 %cmp to i16
%1 = load i8, i8* %B, align 1
%cmp4 = icmp ugt i8 %1, 33
%conv5 = zext i1 %cmp4 to i16
%add = add nuw nsw i16 %conv5, %conv1
ret i16 %add
}
define i64 @foo25(i64* nocapture readonly %A, i64* nocapture readonly %B) {
; CHECK-LABEL: foo25:
; CHECK: ldr x[[X8:[0-9]+]], [x1]
; CHECK-NEXT: ldr x[[X9:[0-9]+]], [x0]
; CHECK-NEXT: cmp x[[X8]], #33
; CHECK-NEXT: cset w[[W8]], hi
; CHECK-NEXT: cmp x[[X9]], #3
; CHECK-NEXT: cinc x0, x[[X8]], hi
; CHECK-NEXT: ret
entry:
%0 = load i64, i64* %A, align 1
%cmp = icmp ugt i64 %0, 3
%conv1 = zext i1 %cmp to i64
%1 = load i64, i64* %B, align 1
%cmp4 = icmp ugt i64 %1, 33
%conv5 = zext i1 %cmp4 to i64
%add = add nuw nsw i64 %conv5, %conv1
ret i64 %add
}

View File

@ -107,12 +107,12 @@ define i16 @test_fccmp(i1 %a, i16 %in) {
; CHECK-NEXT: movk w9, #15428, lsl #16
; CHECK-NEXT: fmov s1, w8
; CHECK-NEXT: fcmp s0, s1
; CHECK-NEXT: fmov s1, w9
; CHECK-NEXT: cset w8, pl
; CHECK-NEXT: fccmp s0, s1, #8, pl
; CHECK-NEXT: mov w9, #4
; CHECK-NEXT: csinc w9, w9, wzr, mi
; CHECK-NEXT: add w0, w8, w9
; CHECK-NEXT: fmov s2, w9
; CHECK-NEXT: mov w10, #4
; CHECK-NEXT: fccmp s0, s2, #8, pl
; CHECK-NEXT: csinc w8, w10, wzr, mi
; CHECK-NEXT: fcmp s0, s1
; CHECK-NEXT: cinc w0, w8, pl
; CHECK-NEXT: ret
%f16 = bitcast i16 %in to half
%cmp0 = fcmp ogt half 0xH3333, %f16