Folding into CSEL when there is ZEXT between SETCC and ADD
authorWeiming Zhao <weimingz@codeaurora.org>
Tue, 13 May 2014 00:40:58 +0000 (00:40 +0000)
committerWeiming Zhao <weimingz@codeaurora.org>
Tue, 13 May 2014 00:40:58 +0000 (00:40 +0000)
Normally, patterns like (add x, (setcc cc ...)) will be folded into
(csel x, x+1, not cc). However, if there is a ZEXT after SETCC, they
won't be folded. This patch recognizes the ZEXT and allows the
generation of CSINC.

This patch fixes bug 19680.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208660 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM64/ARM64ISelLowering.cpp
test/CodeGen/ARM64/csel.ll

index 1d27e86e215be87d368591212fff56466879c5a5..546343a0feb3a36291f6ad7dd56039956bc080d0 100644 (file)
@@ -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();
   }
 
index 975056bfa2cb720675e174773eacb7e2ad1c9c33..98eba30f119d14d165c32e610229a4b56ae36301 100644 (file)
@@ -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
+}