[llvm] 53ec484 - [SelectionDAG] Add CTLS to FoldConstantArithmetic and optimize i1 CTLS to 0. (#178552)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 29 08:00:14 PST 2026
Author: Craig Topper
Date: 2026-01-29T08:00:10-08:00
New Revision: 53ec484ebf6c1b08c68bb449c728f8845fecf7d7
URL: https://github.com/llvm/llvm-project/commit/53ec484ebf6c1b08c68bb449c728f8845fecf7d7
DIFF: https://github.com/llvm/llvm-project/commit/53ec484ebf6c1b08c68bb449c728f8845fecf7d7.diff
LOG: [SelectionDAG] Add CTLS to FoldConstantArithmetic and optimize i1 CTLS to 0. (#178552)
Since we don't have a CTLS intrinsic, it likely gets constant folded
while it is still a CTLZ pattern so I'm using a unittest to test it.
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b92b35feb53e3..349a3fbd41b9c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6559,6 +6559,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
case ISD::CTTZ:
case ISD::CTTZ_ZERO_UNDEF:
case ISD::CTPOP:
+ case ISD::CTLS:
case ISD::STEP_VECTOR: {
SDValue Ops = {N1};
if (SDValue Fold = FoldConstantArithmetic(Opcode, DL, VT, Ops))
@@ -6844,6 +6845,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
if (N1.getValueType().getScalarType() == MVT::i1)
return getNOT(DL, N1, N1.getValueType());
break;
+ case ISD::CTLS:
+ if (N1.getValueType().getScalarType() == MVT::i1)
+ return getConstant(0, DL, VT);
+ break;
case ISD::VECREDUCE_ADD:
if (N1.getValueType().getScalarType() == MVT::i1)
return getNode(ISD::VECREDUCE_XOR, DL, VT, N1);
@@ -7094,6 +7099,10 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
case ISD::CTTZ_ZERO_UNDEF:
return getConstant(Val.countr_zero(), DL, VT, C->isTargetOpcode(),
C->isOpaque());
+ case ISD::CTLS:
+ // CTLS returns the number of extra sign bits so subtract one.
+ return getConstant(Val.getNumSignBits() - 1, DL, VT,
+ C->isTargetOpcode(), C->isOpaque());
case ISD::UINT_TO_FP:
case ISD::SINT_TO_FP: {
APFloat FPV(VT.getFltSemantics(), APInt::getZero(VT.getSizeInBits()));
diff --git a/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp b/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp
index b2c1420215c3f..a99f10c522fed 100644
--- a/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp
+++ b/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp
@@ -315,3 +315,26 @@ TEST_F(SelectionDAGNodeConstructionTest, XOR) {
EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Undef, Op), Undef);
EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Undef, Undef), Zero);
}
+
+TEST_F(SelectionDAGNodeConstructionTest, CTLS) {
+ SDLoc DL;
+ SDValue Zero = DAG->getConstant(0, DL, MVT::i32);
+ SDValue MaxInt = DAG->getConstant(0x7fffffff, DL, MVT::i32);
+ SDValue MinInt = DAG->getConstant(0x80000000, DL, MVT::i32);
+ SDValue MinShort = DAG->getConstant(0xffff8000, DL, MVT::i32);
+
+ SDValue CtlsZero = DAG->getNode(ISD::CTLS, DL, MVT::i32, Zero);
+ SDValue CtlsMinInt = DAG->getNode(ISD::CTLS, DL, MVT::i32, MinInt);
+ SDValue CtlsMaxInt = DAG->getNode(ISD::CTLS, DL, MVT::i32, MaxInt);
+ SDValue CtlsMinShort = DAG->getNode(ISD::CTLS, DL, MVT::i32, MinShort);
+ EXPECT_TRUE(isa<ConstantSDNode>(CtlsZero) &&
+ cast<ConstantSDNode>(CtlsZero)->getZExtValue() == 31);
+ EXPECT_TRUE(isNullConstant(CtlsMinInt));
+ EXPECT_TRUE(isNullConstant(CtlsMaxInt));
+ EXPECT_TRUE(isa<ConstantSDNode>(CtlsMinShort) &&
+ cast<ConstantSDNode>(CtlsMinShort)->getZExtValue() == 16);
+
+ SDValue i1Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i1);
+ SDValue Ctlsi1 = DAG->getNode(ISD::CTLS, DL, MVT::i32, i1Op);
+ EXPECT_TRUE(isNullConstant(Ctlsi1));
+}
More information about the llvm-commits
mailing list