Skip to content

Commit

Permalink
[AArch64] Combine ISD::SETCC into AArch64ISD::ANDS
Browse files Browse the repository at this point in the history
When N > 12, (2^N -1) is not a legal add immediate (isLegalAddImmediate will return false).
ANd if SetCC input use this number, DAG combiner will generate one more SRL instruction.
So combine [setcc (srl x, imm), 0, ne] to [setcc (and x, (-1 << imm)), 0, ne] to get better optimization in emitComparison
Fix #54283

Reviewed By: paulwalker-arm

Differential Revision: https://reviews.llvm.org/D121449
  • Loading branch information
bcl5980 authored and paulwalker-arm committed Mar 19, 2022
1 parent f46fe36 commit dd3b90e
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
20 changes: 17 additions & 3 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Expand Up @@ -17363,14 +17363,14 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
ISD::CondCode Cond = cast<CondCodeSDNode>(N->getOperand(2))->get();
SDLoc DL(N);
EVT VT = N->getValueType(0);

// setcc (csel 0, 1, cond, X), 1, ne ==> csel 0, 1, !cond, X
if (Cond == ISD::SETNE && isOneConstant(RHS) &&
LHS->getOpcode() == AArch64ISD::CSEL &&
isNullConstant(LHS->getOperand(0)) && isOneConstant(LHS->getOperand(1)) &&
LHS->hasOneUse()) {
SDLoc DL(N);

// Invert CSEL's condition.
auto *OpCC = cast<ConstantSDNode>(LHS.getOperand(2));
auto OldCond = static_cast<AArch64CC::CondCode>(OpCC->getZExtValue());
Expand All @@ -17381,7 +17381,21 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
DAG.getNode(AArch64ISD::CSEL, DL, LHS.getValueType(), LHS.getOperand(0),
LHS.getOperand(1), DAG.getConstant(NewCond, DL, MVT::i32),
LHS.getOperand(3));
return DAG.getZExtOrTrunc(CSEL, DL, N->getValueType(0));
return DAG.getZExtOrTrunc(CSEL, DL, VT);
}

// setcc (srl x, imm), 0, ne ==> setcc (and x, (-1 << imm)), 0, ne
if (Cond == ISD::SETNE && isNullConstant(RHS) &&
LHS->getOpcode() == ISD::SRL && isa<ConstantSDNode>(LHS->getOperand(1)) &&
LHS->hasOneUse()) {
EVT TstVT = LHS->getValueType(0);
if (TstVT.isScalarInteger() && TstVT.getFixedSizeInBits() <= 64) {
// this pattern will get better opt in emitComparison
uint64_t TstImm = -1ULL << LHS->getConstantOperandVal(1);
SDValue TST = DAG.getNode(ISD::AND, DL, TstVT, LHS->getOperand(0),
DAG.getConstant(TstImm, DL, TstVT));
return DAG.getNode(ISD::SETCC, DL, VT, TST, RHS, N->getOperand(2));
}
}

return SDValue();
Expand Down
12 changes: 4 additions & 8 deletions llvm/test/CodeGen/AArch64/arm64-xaluo.ll
Expand Up @@ -1847,9 +1847,8 @@ define i8 @umulo.selectboth.i8(i8 %a, i8 %b) {
; SDAG-NEXT: and w8, w1, #0xff
; SDAG-NEXT: and w9, w0, #0xff
; SDAG-NEXT: mul w8, w9, w8
; SDAG-NEXT: lsr w9, w8, #8
; SDAG-NEXT: cmp w9, #0
; SDAG-NEXT: mov w9, #10
; SDAG-NEXT: tst w8, #0xff00
; SDAG-NEXT: csel w0, w8, w9, ne
; SDAG-NEXT: ret
;
Expand All @@ -1858,9 +1857,8 @@ define i8 @umulo.selectboth.i8(i8 %a, i8 %b) {
; FAST-NEXT: and w8, w1, #0xff
; FAST-NEXT: and w9, w0, #0xff
; FAST-NEXT: mul w8, w9, w8
; FAST-NEXT: lsr w9, w8, #8
; FAST-NEXT: cmp w9, #0
; FAST-NEXT: mov w9, #10
; FAST-NEXT: tst w8, #0xff00
; FAST-NEXT: csel w0, w8, w9, ne
; FAST-NEXT: ret
;
Expand Down Expand Up @@ -1925,9 +1923,8 @@ define i16 @umulo.selectboth.i16(i16 %a, i16 %b) {
; SDAG-NEXT: and w8, w1, #0xffff
; SDAG-NEXT: and w9, w0, #0xffff
; SDAG-NEXT: mul w8, w9, w8
; SDAG-NEXT: lsr w9, w8, #16
; SDAG-NEXT: cmp w9, #0
; SDAG-NEXT: mov w9, #10
; SDAG-NEXT: tst w8, #0xffff0000
; SDAG-NEXT: csel w0, w8, w9, ne
; SDAG-NEXT: ret
;
Expand All @@ -1936,9 +1933,8 @@ define i16 @umulo.selectboth.i16(i16 %a, i16 %b) {
; FAST-NEXT: and w8, w1, #0xffff
; FAST-NEXT: and w9, w0, #0xffff
; FAST-NEXT: mul w8, w9, w8
; FAST-NEXT: lsr w9, w8, #16
; FAST-NEXT: cmp w9, #0
; FAST-NEXT: mov w9, #10
; FAST-NEXT: tst w8, #0xffff0000
; FAST-NEXT: csel w0, w8, w9, ne
; FAST-NEXT: ret
;
Expand Down

0 comments on commit dd3b90e

Please sign in to comment.