From 26ab794dc8ad7c45559e6998ac4d4ca123bd38b0 Mon Sep 17 00:00:00 2001 From: AZero13 Date: Sat, 23 Aug 2025 17:45:00 -0400 Subject: [PATCH] [AArch64] Copy CSNEG, CSINV, and CSINC computeKnownBitsForTargetNode from ARM --- .../Target/AArch64/AArch64ISelLowering.cpp | 24 +++++++++++++++++++ llvm/test/CodeGen/AArch64/rand.ll | 20 ++++++++-------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index c80bac02f41af..8826b38dbd487 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/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