Skip to content

Conversation

AZero13
Copy link
Contributor

@AZero13 AZero13 commented Aug 23, 2025

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Aug 23, 2025

@llvm/pr-subscribers-backend-arm

Author: AZero13 (AZero13)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/155122.diff

3 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+24)
  • (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (-3)
  • (modified) llvm/test/CodeGen/AArch64/rand.ll (+10-10)
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

@llvmbot
Copy link
Member

llvmbot commented Aug 23, 2025

@llvm/pr-subscribers-backend-aarch64

Author: AZero13 (AZero13)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/155122.diff

3 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+24)
  • (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (-3)
  • (modified) llvm/test/CodeGen/AArch64/rand.ll (+10-10)
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

Copy link

github-actions bot commented Aug 23, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@AZero13 AZero13 force-pushed the optimize-imm branch 4 times, most recently from 1d13927 to 8ab6164 Compare August 23, 2025 22:42
@AZero13
Copy link
Contributor Author

AZero13 commented Aug 26, 2025

@davemgreen Thoughts?

Copy link
Collaborator

@davemgreen davemgreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this sounds OK. We don't use these nodes very much, so they might be difficult to add tests for. Please make sure you have done a bootstrap or whatnot to make sure nothing goes wrong.

@AZero13
Copy link
Contributor Author

AZero13 commented Aug 27, 2025

I think this sounds OK. We don't use these nodes very much, so they might be difficult to add tests for. Please make sure you have done a bootstrap or whatnot to make sure nothing goes wrong.

Thank you and I have.

@AZero13
Copy link
Contributor Author

AZero13 commented Aug 27, 2025

@davemgreen Can we please merge?

@davemgreen davemgreen merged commit 40bf68f into llvm:main Aug 28, 2025
9 checks passed
@AZero13 AZero13 deleted the optimize-imm branch August 28, 2025 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants