[llvm] [AArch64] AArch64TargetLowering::computeKnownBitsForTargetNode - add support for AArch64ISD::MOV/MVN constants (PR #154039)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 17 14:43:44 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Yatao Wang (ningxinr)

<details>
<summary>Changes</summary>

Add support for the following constant nodes in `AArch64TargetLowering::computeKnownBitsForTargetNode`:
```
  case AArch64ISD::MOVIedit:
  case AArch64ISD::MOVImsl:
  case AArch64ISD::MVNIshift:
  case AArch64ISD::MVNImsl:
```

Also add `AArch64TargetLowering::computeKnownBitsForTargetNode` tests for all the MOVI constant nodes in `llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp`

Issue: #<!-- -->153159 

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


3 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+30) 
- (modified) llvm/test/CodeGen/AArch64/urem-vector-lkk.ll (+8-8) 
- (modified) llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp (+58) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index aefbbe2534be2..958410588996c 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2619,6 +2619,32 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
                                        << Op->getConstantOperandVal(1)));
     break;
   }
+  case AArch64ISD::MOVImsl: {
+    Known = KnownBits::makeConstant(
+        APInt(Known.getBitWidth(), ~(~Op->getConstantOperandVal(0)
+                                     << Op->getConstantOperandVal(1))));
+    break;
+  }
+  case AArch64ISD::MOVIedit: {
+    Known = KnownBits::makeConstant(APInt(
+        Known.getBitWidth(),
+        AArch64_AM::decodeAdvSIMDModImmType10(Op->getConstantOperandVal(0))));
+    break;
+  }
+  case AArch64ISD::MVNIshift: {
+    Known = KnownBits::makeConstant(
+        APInt(Known.getBitWidth(),
+              (~Op->getConstantOperandVal(0) << Op->getConstantOperandVal(1)),
+              false, true));
+    break;
+  }
+  case AArch64ISD::MVNImsl: {
+    Known = KnownBits::makeConstant(
+        APInt(Known.getBitWidth(),
+              ~(Op->getConstantOperandVal(0) << Op->getConstantOperandVal(1)),
+              false, true));
+    break;
+  }
   case AArch64ISD::LOADgot:
   case AArch64ISD::ADDlow: {
     if (!Subtarget->isTargetILP32())
@@ -30624,6 +30650,10 @@ bool AArch64TargetLowering::isTargetCanonicalConstantNode(SDValue Op) const {
   return Op.getOpcode() == AArch64ISD::DUP ||
          Op.getOpcode() == AArch64ISD::MOVI ||
          Op.getOpcode() == AArch64ISD::MOVIshift ||
+         Op.getOpcode() == AArch64ISD::MOVImsl ||
+         Op.getOpcode() == AArch64ISD::MOVIedit ||
+         Op.getOpcode() == AArch64ISD::MVNIshift ||
+         Op.getOpcode() == AArch64ISD::MVNImsl ||
          (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
           Op.getOperand(0).getOpcode() == AArch64ISD::DUP) ||
          TargetLowering::isTargetCanonicalConstantNode(Op);
diff --git a/llvm/test/CodeGen/AArch64/urem-vector-lkk.ll b/llvm/test/CodeGen/AArch64/urem-vector-lkk.ll
index 468a33ce5bfcf..4dd86769c1dd5 100644
--- a/llvm/test/CodeGen/AArch64/urem-vector-lkk.ll
+++ b/llvm/test/CodeGen/AArch64/urem-vector-lkk.ll
@@ -8,14 +8,14 @@ define <4 x i16> @fold_urem_vec_1(<4 x i16> %x) {
 ; CHECK-NEXT:    ldr d1, [x8, :lo12:.LCPI0_0]
 ; CHECK-NEXT:    adrp x8, .LCPI0_1
 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI0_1]
-; CHECK-NEXT:    adrp x8, .LCPI0_2
-; CHECK-NEXT:    ushl v1.4h, v0.4h, v1.4h
-; CHECK-NEXT:    umull v1.4s, v1.4h, v2.4h
-; CHECK-NEXT:    movi d2, #0000000000000000
-; CHECK-NEXT:    shrn v1.4h, v1.4s, #16
-; CHECK-NEXT:    fneg d2, d2
-; CHECK-NEXT:    sub v3.4h, v0.4h, v1.4h
-; CHECK-NEXT:    umull v2.4s, v3.4h, v2.4h
+; CHECK-NEXT:    mov     x8, #-9223372036854775808       // =0x8000000000000000
+; CHECK-NEXT:    ushl    v1.4h, v0.4h, v1.4h
+; CHECK-NEXT:    fmov    d3, x8
+; CHECK-NEXT:    adrp    x8, .LCPI0_2
+; CHECK-NEXT:    umull   v1.4s, v1.4h, v2.4h
+; CHECK-NEXT:    shrn    v1.4h, v1.4s, #16
+; CHECK-NEXT:    sub     v2.4h, v0.4h, v1.4h
+; CHECK-NEXT:    umull   v2.4s, v2.4h, v3.4h
 ; CHECK-NEXT:    shrn v2.4h, v2.4s, #16
 ; CHECK-NEXT:    add v1.4h, v2.4h, v1.4h
 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI0_2]
diff --git a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
index f06f03bb35a5d..131b7eca942d0 100644
--- a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
+++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
@@ -318,6 +318,64 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) {
   EXPECT_EQ(Known.One, APInt(8, 0x86));
 }
 
+// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
+TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
+  SDLoc Loc;
+  auto Int8VT = EVT::getIntegerVT(Context, 8);
+  auto Int16VT = EVT::getIntegerVT(Context, 16);
+  auto Int32VT = EVT::getIntegerVT(Context, 32);
+  auto Int64VT = EVT::getIntegerVT(Context, 64);
+  auto N0 = DAG->getConstant(0xA5, Loc, Int8VT);
+  KnownBits Known;
+
+  auto OpMOVIedit = DAG->getNode(AArch64ISD::MOVIedit, Loc, Int64VT, N0);
+  Known = DAG->computeKnownBits(OpMOVIedit);
+  EXPECT_EQ(Known.Zero, APInt(64, 0x00FF00FFFF00FF00));
+  EXPECT_EQ(Known.One, APInt(64, 0xFF00FF0000FF00FF));
+
+  auto N1 = DAG->getConstant(16, Loc, Int8VT);
+  auto OpMOVImsl = DAG->getNode(AArch64ISD::MOVImsl, Loc, Int32VT, N0, N1);
+  Known = DAG->computeKnownBits(OpMOVImsl);
+  EXPECT_EQ(Known.Zero, APInt(32, 0xFF5A0000));
+  EXPECT_EQ(Known.One, APInt(32, 0x00A5FFFF));
+
+  auto OpMVNImsl = DAG->getNode(AArch64ISD::MVNImsl, Loc, Int32VT, N0, N1);
+  Known = DAG->computeKnownBits(OpMVNImsl);
+  EXPECT_EQ(Known.Zero, APInt(32, 0x00A50000));
+  EXPECT_EQ(Known.One, APInt(32, 0xFF5AFFFF));
+
+  auto N2 = DAG->getConstant(16, Loc, Int8VT);
+  auto OpMOVIshift32 =
+      DAG->getNode(AArch64ISD::MOVIshift, Loc, Int32VT, N0, N2);
+  Known = DAG->computeKnownBits(OpMOVIshift32);
+  EXPECT_EQ(Known.Zero, APInt(32, 0xFF5AFFFF));
+  EXPECT_EQ(Known.One, APInt(32, 0x00A50000));
+
+  auto OpMVNIshift32 =
+      DAG->getNode(AArch64ISD::MVNIshift, Loc, Int32VT, N0, N2);
+  Known = DAG->computeKnownBits(OpMVNIshift32);
+  EXPECT_EQ(Known.Zero, APInt(32, 0x00A5FFFF));
+  EXPECT_EQ(Known.One, APInt(32, 0xFF5A0000));
+
+  auto N3 = DAG->getConstant(8, Loc, Int8VT);
+  auto OpMOVIshift16 =
+      DAG->getNode(AArch64ISD::MOVIshift, Loc, Int16VT, N0, N3);
+  Known = DAG->computeKnownBits(OpMOVIshift16);
+  EXPECT_EQ(Known.One, APInt(16, 0xA500));
+  EXPECT_EQ(Known.Zero, APInt(16, 0x5AFF));
+
+  auto OpMVNIshift16 =
+      DAG->getNode(AArch64ISD::MVNIshift, Loc, Int16VT, N0, N3);
+  Known = DAG->computeKnownBits(OpMVNIshift16);
+  EXPECT_EQ(Known.Zero, APInt(16, 0xA5FF));
+  EXPECT_EQ(Known.One, APInt(16, 0x5A00));
+
+  auto OpMOVI = DAG->getNode(AArch64ISD::MOVI, Loc, Int8VT, N0);
+  Known = DAG->computeKnownBits(OpMOVI);
+  EXPECT_EQ(Known.Zero, APInt(8, 0x5A));
+  EXPECT_EQ(Known.One, APInt(8, 0xA5));
+}
+
 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
 TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
   SDLoc Loc;

``````````

</details>


https://github.com/llvm/llvm-project/pull/154039


More information about the llvm-commits mailing list