diff --git a/lib/Target/ARM64/ARM64ISelLowering.cpp b/lib/Target/ARM64/ARM64ISelLowering.cpp index 1d27e86e215..546343a0feb 100644 --- a/lib/Target/ARM64/ARM64ISelLowering.cpp +++ b/lib/Target/ARM64/ARM64ISelLowering.cpp @@ -6600,8 +6600,16 @@ static bool isSetCC(SDValue Op, SetCCInfoAndKind &SetCCInfo) { return TValue->isOne() && FValue->isNullValue(); } +// Returns true if Op is setcc or zext of setcc. +static bool isSetCCOrZExtSetCC(const SDValue& Op, SetCCInfoAndKind &Info) { + if (isSetCC(Op, Info)) + return true; + return ((Op.getOpcode() == ISD::ZERO_EXTEND) && + isSetCC(Op->getOperand(0), Info)); +} + // The folding we want to perform is: -// (add x, (setcc cc ...) ) +// (add x, [zext] (setcc cc ...) ) // --> // (csel x, (add x, 1), !cc ...) // @@ -6613,9 +6621,9 @@ static SDValue performSetccAddFolding(SDNode *Op, SelectionDAG &DAG) { SetCCInfoAndKind InfoAndKind; // If neither operand is a SET_CC, give up. - if (!isSetCC(LHS, InfoAndKind)) { + if (!isSetCCOrZExtSetCC(LHS, InfoAndKind)) { std::swap(LHS, RHS); - if (!isSetCC(LHS, InfoAndKind)) + if (!isSetCCOrZExtSetCC(LHS, InfoAndKind)) return SDValue(); } diff --git a/test/CodeGen/ARM64/csel.ll b/test/CodeGen/ARM64/csel.ll index 975056bfa2c..98eba30f119 100644 --- a/test/CodeGen/ARM64/csel.ll +++ b/test/CodeGen/ARM64/csel.ll @@ -217,3 +217,14 @@ entry: %. = select i1 %cmp, i64 1, i64 2 ret i64 %. } + +define i64 @foo19(i64 %a, i64 %b, i64 %c) { +entry: +; CHECK-LABEL: foo19: +; CHECK: cinc x0, x2 +; CHECK-NOT: add + %cmp = icmp ult i64 %a, %b + %inc = zext i1 %cmp to i64 + %inc.c = add i64 %inc, %c + ret i64 %inc.c +}