[llvm] [AArch64] Copy CSNEG, CSINV, and CSINC computeKnownBitsForTargetNode from ARM (PR #155122)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 23 15:38:32 PDT 2025


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/155122

>From bc36a77db138c220d1e101450b5a907cd4a6389b Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 23 Aug 2025 17:45:00 -0400
Subject: [PATCH 1/2] [AArch64] Copy CSNEG, CSINV, and CSINC
 computeKnownBitsForTargetNode from ARM

---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 24 +++++++++++++++++++
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |  3 ---
 llvm/test/CodeGen/AArch64/rand.ll             | 20 ++++++++--------
 3 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index fbd8f7a979d66..68a1d9a33dffc 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2585,6 +2585,30 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
     Known = Known.intersectWith(Known2);
     break;
   }
+  case AArch64ISD::CSNEG:
+  case AArch64ISD::CSINC:
+  case AArch64ISD::CSINV: {
+    KnownBits KnownOp0 = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
+    KnownBits KnownOp1 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
+
+    // The result is either:
+    // CSINC: KnownOp0 or KnownOp1 + 1
+    // CSINV: KnownOp0 or ~KnownOp1
+    // CSNEG: KnownOp0 or KnownOp1 * -1
+    if (Op.getOpcode() == AArch64ISD::CSINC)
+      KnownOp1 = KnownBits::add(
+          KnownOp1,
+          KnownBits::makeConstant(APInt(Op.getScalarValueSizeInBits(), 1)));
+    else if (Op.getOpcode() == AArch64ISD::CSINV)
+      std::swap(KnownOp1.Zero, KnownOp1.One);
+    else if (Op.getOpcode() == AArch64ISD::CSNEG)
+      KnownOp1 =
+          KnownBits::mul(KnownOp1, KnownBits::makeConstant(APInt::getAllOnes(
+                                       Op.getScalarValueSizeInBits())));
+
+    Known = KnownOp0.intersectWith(KnownOp1);
+    break;
+  }
   case AArch64ISD::BICi: {
     // Compute the bit cleared value.
     APInt Mask =
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 12d2d678ff63a..d6bba9909cced 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -19985,9 +19985,6 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
   case ARMISD::CMOV: {
     // Bits are known zero/one if known on the LHS and RHS.
     Known = DAG.computeKnownBits(Op.getOperand(0), Depth+1);
-    if (Known.isUnknown())
-      return;
-
     KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
     Known = Known.intersectWith(KnownRHS);
     return;
diff --git a/llvm/test/CodeGen/AArch64/rand.ll b/llvm/test/CodeGen/AArch64/rand.ll
index 706774d83b187..ed6d4b26ba56c 100644
--- a/llvm/test/CodeGen/AArch64/rand.ll
+++ b/llvm/test/CodeGen/AArch64/rand.ll
@@ -4,11 +4,11 @@
 define  i32 @rndr(ptr %__addr) {
 ; CHECK-LABEL: rndr:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mrs x9, RNDR
-; CHECK-NEXT:    mov x8, x0
-; CHECK-NEXT:    cset w10, eq
-; CHECK-NEXT:    str x9, [x8]
-; CHECK-NEXT:    and w0, w10, #0x1
+; CHECK-NEXT:    mrs x10, RNDR
+; CHECK-NEXT:    mov x9, x0
+; CHECK-NEXT:    cset w8, eq
+; CHECK-NEXT:    str x10, [x9]
+; CHECK-NEXT:    mov w0, w8
 ; CHECK-NEXT:    ret
   %1 = tail call { i64, i1 } @llvm.aarch64.rndr()
   %2 = extractvalue { i64, i1 } %1, 0
@@ -22,11 +22,11 @@ define  i32 @rndr(ptr %__addr) {
 define  i32 @rndrrs(ptr  %__addr) {
 ; CHECK-LABEL: rndrrs:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mrs x9, RNDRRS
-; CHECK-NEXT:    mov x8, x0
-; CHECK-NEXT:    cset w10, eq
-; CHECK-NEXT:    str x9, [x8]
-; CHECK-NEXT:    and w0, w10, #0x1
+; CHECK-NEXT:    mrs x10, RNDRRS
+; CHECK-NEXT:    mov x9, x0
+; CHECK-NEXT:    cset w8, eq
+; CHECK-NEXT:    str x10, [x9]
+; CHECK-NEXT:    mov w0, w8
 ; CHECK-NEXT:    ret
   %1 = tail call { i64, i1 } @llvm.aarch64.rndrrs()
   %2 = extractvalue { i64, i1 } %1, 0

>From 6072f4b2e4560c36bb5e8c4ea39dfea06c0dacc2 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 23 Aug 2025 18:38:13 -0400
Subject: [PATCH 2/2] Update ARMISelLowering.cpp

---
 llvm/lib/Target/ARM/ARMISelLowering.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index d6bba9909cced..650fb9e128d86 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -19985,6 +19985,8 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
   case ARMISD::CMOV: {
     // Bits are known zero/one if known on the LHS and RHS.
     Known = DAG.computeKnownBits(Op.getOperand(0), Depth+1);
+    if (Known.isUnknown())
+      return;
     KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
     Known = Known.intersectWith(KnownRHS);
     return;



More information about the llvm-commits mailing list