[llvm] [DAG] isKnownToBeAPowerOfTwo - Power of 2 value is known to be power of 2 after BSWAP/BITREVERSE (PR #182207)

Manuel Dun via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 20 06:07:59 PST 2026


https://github.com/manueldun updated https://github.com/llvm/llvm-project/pull/182207

>From dc45e74f8ab930484cbf39946d3f45fc5d4f8794 Mon Sep 17 00:00:00 2001
From: Manuel Fernando Dun Jimenez <manueldun at gmail.com>
Date: Wed, 18 Feb 2026 16:03:09 -0400
Subject: [PATCH] [DAG] isKnownToBeAPowerOfTwo function now handle BSwap and
 BitReverse

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  5 ++--
 .../AArch64/AArch64SelectionDAGTest.cpp       | 26 +++++++++++++++++++
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 581553d41cb6d..be49fd223db6f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4733,8 +4733,9 @@ bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val,
 
   case ISD::ROTL:
   case ISD::ROTR:
-    return isKnownToBeAPowerOfTwo(Val.getOperand(0), /*OrZero=*/false,
-                                  Depth + 1);
+  case ISD::BSWAP:
+  case ISD::BITREVERSE:
+    return isKnownToBeAPowerOfTwo(Val.getOperand(0), OrZero, Depth + 1);
 
   case ISD::SMIN:
   case ISD::SMAX:
diff --git a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
index b2b8dfb0c21fc..f75896fd3d6a7 100644
--- a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
+++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp
@@ -914,6 +914,32 @@ TEST_F(AArch64SelectionDAGTest, KnownToBeAPowerOfTwo_Constants) {
   EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(SplatBig, /*OrZero=*/true));
 }
 
+TEST_F(AArch64SelectionDAGTest, KnownToBeAPowerOfTwo_BSWAP_BITREVERSE) {
+
+  SDLoc Loc;
+  SDValue Cst4 = DAG->getConstant(4, Loc, MVT::i32);
+  SDValue BSwapOp = DAG->getNode(ISD::BSWAP, Loc, MVT::i32, Cst4);
+  EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(BSwapOp, /*OrZero=*/false));
+
+  SDValue BReverseOp = DAG->getNode(ISD::BITREVERSE, Loc, MVT::i32, Cst4);
+  EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(BReverseOp, /*OrZero=*/false));
+
+  SDValue Vec44 = DAG->getBuildVector(MVT::v2i16, Loc, {Cst4, Cst4});
+  SDValue BReverseOpVec = DAG->getNode(ISD::BSWAP, Loc, MVT::v2i16, Vec44);
+  EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(BReverseOpVec, /*OrZero=*/true));
+
+  SDValue Cst0 = DAG->getConstant(0, Loc, MVT::i32);
+  SDValue Vec04 = DAG->getBuildVector(MVT::v2i16, Loc, {Cst0, Cst4});
+  SDValue BSwapOpVec = DAG->getNode(ISD::BSWAP, Loc, MVT::v2i16, Vec04);
+  EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(BSwapOpVec, /*OrZero=*/true));
+
+  SDValue BitReverseOpVec =
+      DAG->getNode(ISD::BITREVERSE, Loc, MVT::v2i16, Vec04);
+  APInt DemandLo(2, 1);
+  EXPECT_TRUE(
+      DAG->isKnownToBeAPowerOfTwo(BitReverseOpVec, DemandLo, /*OrZero=*/true));
+}
+
 TEST_F(AArch64SelectionDAGTest, KnownToBeAPowerOfTwo_Select) {
   SDLoc Loc;
   auto Cst0 = DAG->getConstant(0, Loc, MVT::i32);



More information about the llvm-commits mailing list