From 8819469b20e554680de572ec236877199fdb7065 Mon Sep 17 00:00:00 2001 From: ningxinr Date: Fri, 12 Sep 2025 12:05:03 -0700 Subject: [PATCH 1/8] Add tests for ISel and GlobalISel Sub --- .../AArch64/GlobalISel/knownbits-sub.mir | 234 ++++++++++++++++++ .../AArch64/AArch64SelectionDAGTest.cpp | 45 ++++ 2 files changed, 279 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir new file mode 100644 index 0000000000000..8051bd2d17812 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir @@ -0,0 +1,234 @@ +# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5 +# RUN: llc -mtriple aarch64 -passes="print" %s -o - 2>&1 | FileCheck %s + +--- +name: Cst +body: | + bb.1: + ; CHECK-LABEL: name: @Cst + ; CHECK-NEXT: %0:_ KnownBits:00000010 SignBits:6 + ; CHECK-NEXT: %1:_ KnownBits:11100000 SignBits:3 + ; CHECK-NEXT: %2:_ KnownBits:00100010 SignBits:2 + %0:_(s8) = G_CONSTANT i8 2 + %1:_(s8) = G_CONSTANT i8 224 + %2:_(s8) = G_SUB %0, %1 +... +--- +name: CstZero +body: | + bb.1: + ; CHECK-LABEL: name: @CstZero + ; CHECK-NEXT: %0:_ KnownBits:00000000 SignBits:8 + ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8 + ; CHECK-NEXT: %2:_ KnownBits:00000000 SignBits:8 + %0:_(s8) = G_CONSTANT i8 0 + %1:_(s8) = G_CONSTANT i8 0 + %2:_(s8) = G_SUB %0, %1 +... +--- +name: CstNegOne +body: | + bb.1: + ; CHECK-LABEL: name: @CstNegOne + ; CHECK-NEXT: %0:_ KnownBits:00000000 SignBits:8 + ; CHECK-NEXT: %1:_ KnownBits:00000001 SignBits:7 + ; CHECK-NEXT: %2:_ KnownBits:11111111 SignBits:8 + %0:_(s8) = G_CONSTANT i8 0 + %1:_(s8) = G_CONSTANT i8 1 + %2:_(s8) = G_SUB %0, %1 +... +--- +name: CstNeg +body: | + bb.1: + ; CHECK-LABEL: name: @CstNeg + ; CHECK-NEXT: %0:_ KnownBits:11100000 SignBits:3 + ; CHECK-NEXT: %1:_ KnownBits:00000010 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:11011110 SignBits:2 + %0:_(s8) = G_CONSTANT i8 224 + %1:_(s8) = G_CONSTANT i8 2 + %2:_(s8) = G_SUB %0, %1 +... +--- +name: ScalarVar +body: | + bb.1: + ; CHECK-LABEL: name: @ScalarVar + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 + %0:_(s8) = COPY $b0 + %1:_(s8) = COPY $b1 + %2:_(s8) = G_SUB %0, %1 +... +--- +name: ScalarRhsEarlyOut +body: | + bb.1: + ; CHECK-LABEL: name: @ScalarRhsEarlyOut + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 + %0:_(s8) = COPY $b0 + %1:_(s8) = G_CONSTANT i8 3 + %2:_(s8) = G_SUB %0, %1 +... +--- +name: ScalarNonNegative +body: | + bb.1: + ; CHECK-LABEL: name: @ScalarNonNegative + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:00000000 SignBits:8 + ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:1 + %0:_(s8) = COPY $b0 + %1:_(s8) = G_CONSTANT i8 15 + %2:_(s8) = G_AND %0, %1 + %3:_(s8) = G_CONSTANT i8 0 + %4:_(s8) = G_SUB %3, %2 +... +--- +name: ScalarLhsEarlyOut +body: | + bb.1: + ; CHECK-LABEL: name: @ScalarLhsEarlyOut + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 + %0:_(s8) = COPY $b0 + %1:_(s8) = G_CONSTANT i8 3 + %2:_(s8) = G_SUB %1, %0 +... +--- +name: ScalarPartKnown +body: | + bb.1: + ; CHECK-LABEL: name: @ScalarPartKnown + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:00000101 SignBits:5 + ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:1 + %0:_(s8) = COPY $b0 + %1:_(s8) = G_CONSTANT i8 15 + %2:_(s8) = G_AND %0, %1 + %3:_(s8) = G_CONSTANT i8 5 + %4:_(s8) = G_SUB %2, %3 +... +--- +name: VectorVar +body: | + bb.1: + ; CHECK-LABEL: name: @VectorVar + ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????? SignBits:1 + %0:_(<4 x s16>) = COPY $d0 + %1:_(<4 x s16>) = COPY $d1 + %2:_(<4 x s16>) = G_SUB %0, %1 +... +--- +name: VectorRhsEarlyOut +body: | + bb.1: + ; CHECK-LABEL: name: @VectorRhsEarlyOut + ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:0000000000000011 SignBits:14 + ; CHECK-NEXT: %2:_ KnownBits:0000000000000011 SignBits:14 + ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1 + %0:_(<4 x s16>) = COPY $d0 + %1:_(s16) = G_CONSTANT i16 3 + %2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 + %3:_(<4 x s16>) = G_SUB %2, %0 +... +--- +name: VectorNonNegative +body: | + bb.1: + ; CHECK-LABEL: name: @VectorNonNegative + ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:0000000011111111 SignBits:8 + ; CHECK-NEXT: %2:_ KnownBits:0000000011111111 SignBits:8 + ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8 + ; CHECK-NEXT: %4:_ KnownBits:0000000000000000 SignBits:16 + ; CHECK-NEXT: %5:_ KnownBits:0000000000000000 SignBits:16 + ; CHECK-NEXT: %6:_ KnownBits:???????????????? SignBits:1 + %0:_(<4 x s16>) = COPY $d0 + %1:_(s16) = G_CONSTANT i16 255 + %2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 + %3:_(<4 x s16>) = G_AND %0, %2 + %4:_(s16) = G_CONSTANT i16 0 + %5:_(<4 x s16>) = G_BUILD_VECTOR %4, %4, %4, %4 + %6:_(<4 x s16>) = G_SUB %5, %3 +... +--- +name: VectorLhsEarlyOut +body: | + bb.1: + ; CHECK-LABEL: name: @VectorLhsEarlyOut + ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:0000000000000011 SignBits:14 + ; CHECK-NEXT: %2:_ KnownBits:0000000000000011 SignBits:14 + ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1 + %0:_(<4 x s16>) = COPY $d0 + %1:_(s16) = G_CONSTANT i16 3 + %2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 + %3:_(<4 x s16>) = G_SUB %0, %2 +... +--- +name: VectorPartKnown +body: | + bb.1: + ; CHECK-LABEL: name: @VectorPartKnown + ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:0000000011111111 SignBits:8 + ; CHECK-NEXT: %2:_ KnownBits:0000000011111111 SignBits:8 + ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8 + ; CHECK-NEXT: %4:_ KnownBits:0000000000101010 SignBits:10 + ; CHECK-NEXT: %5:_ KnownBits:0000000001001010 SignBits:9 + ; CHECK-NEXT: %6:_ KnownBits:000000000??01010 SignBits:9 + ; CHECK-NEXT: %7:_ KnownBits:???????????????? SignBits:1 + %0:_(<4 x s16>) = COPY $d0 + %1:_(s16) = G_CONSTANT i16 255 + %2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 + %3:_(<4 x s16>) = G_AND %0, %2 + %4:_(s16) = G_CONSTANT i16 42 + %5:_(s16) = G_CONSTANT i16 74 + %6:_(<4 x s16>) = G_BUILD_VECTOR %4, %5, %5, %4 + %7:_(<4 x s16>) = G_SUB %6, %3 +... +--- +name: VectorCst36 +body: | + bb.1: + ; CHECK-LABEL: name: @VectorCst36 + ; CHECK-NEXT: %0:_ KnownBits:0000000000000011 SignBits:14 + ; CHECK-NEXT: %1:_ KnownBits:0000000000000110 SignBits:13 + ; CHECK-NEXT: %2:_ KnownBits:0000000000000?1? SignBits:13 + ; CHECK-NEXT: %3:_ KnownBits:0000000000000?1? SignBits:13 + ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1 + %0:_(s16) = G_CONSTANT i16 3 + %1:_(s16) = G_CONSTANT i16 6 + %2:_(<4 x s16>) = G_BUILD_VECTOR %0, %1, %1, %0 + %3:_(<4 x s16>) = G_BUILD_VECTOR %0, %1, %1, %0 + %4:_(<4 x s16>) = G_SUB %2, %3 +... + +--- +name: VectorCst3unknown +body: | + bb.1: + ; CHECK-LABEL: name: @VectorCst3unknown + ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:0000000000000011 SignBits:14 + ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1 + %0:_(<4 x s16>) = COPY $d0 + %1:_(s16) = COPY $h0 + %2:_(s16) = G_CONSTANT i16 3 + %3:_(<4 x s16>) = G_BUILD_VECTOR %1, %2, %2, %1 + %4:_(<4 x s16>) = G_SUB %0, %3 +... diff --git a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp index c74d15782398a..b56e3ec53c18c 100644 --- a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp +++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp @@ -177,6 +177,51 @@ TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_VASHR) { EXPECT_EQ(DAG->ComputeNumSignBits(Fr2), 5u); } +TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SUB) { + SDLoc Loc; + auto IntVT = EVT::getIntegerVT(Context, 8); + auto N0 = DAG->getConstant(0x00, Loc, IntVT); + auto N1 = DAG->getConstant(0x01, Loc, IntVT); + auto N5 = DAG->getConstant(0x05, Loc, IntVT); + auto Nsign1 = DAG->getConstant(0x55, Loc, IntVT); + auto UnknownOp = DAG->getRegister(0, IntVT); + auto Mask = DAG->getConstant(0x1e, Loc, IntVT); + auto Nsign3 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp); + // RHS early out + // Nsign1 = 01010101 + // Nsign3 = 000????0 + auto OpRhsEo = DAG->getNode(ISD::SUB, Loc, IntVT, Nsign3, Nsign1); + EXPECT_EQ(DAG->ComputeNumSignBits(OpRhsEo), 1u); + + // Neg 0 + // N0 = 00000000 + auto OpNegZero = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N0); + EXPECT_EQ(DAG->ComputeNumSignBits(OpNegZero), 8u); + + // Neg 1 + // N0 = 00000000 + // N1 = 00000001 + auto OpNegOne = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1); + EXPECT_EQ(DAG->ComputeNumSignBits(OpNegOne), 8u); + + // Non negative + // N0 = 00000000 + // Nsign3 = 000????0 + auto OpNonNeg = DAG->getNode(ISD::SUB, Loc, IntVT, N0, Nsign3); + EXPECT_EQ(DAG->ComputeNumSignBits(OpNonNeg), 3u); + + // LHS early out + // Nsign1 = 01010101 + // Nsign3 = 000????0 + auto OpLhsEo = DAG->getNode(ISD::SUB, Loc, IntVT, Nsign1, Nsign3); + EXPECT_EQ(DAG->ComputeNumSignBits(OpLhsEo), 1u); + + // Nsign3 = 000????0 + // N5 = 00000101 + auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, Nsign3, N5); + EXPECT_EQ(DAG->ComputeNumSignBits(Op), 2u); +} + TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { TargetLowering TL(*TM); From 16dd8182ff97ae3ffd8d8f65746ad7f893960acd Mon Sep 17 00:00:00 2001 From: ningxinr Date: Fri, 12 Sep 2025 13:42:57 -0700 Subject: [PATCH 2/8] Fix typo --- llvm/test/CodeGen/AArch64/GlobalISel/knownbits-ashr.mir | 4 ++-- llvm/test/CodeGen/AArch64/GlobalISel/knownbits-shl.mir | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-ashr.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-ashr.mir index 8552931c1f4c0..ee354479d603c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-ashr.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-ashr.mir @@ -102,8 +102,8 @@ body: | ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1 ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1 %0:_(<4 x s16>) = COPY $d0 - %2:_(s16) = COPY $h0 - %1:_(s16) = G_CONSTANT i16 3 + %1:_(s16) = COPY $h0 + %2:_(s16) = G_CONSTANT i16 3 %3:_(<4 x s16>) = G_BUILD_VECTOR %1, %2, %2, %1 %4:_(<4 x s16>) = G_ASHR %0, %3 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-shl.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-shl.mir index 61d1c4375bd6e..97bcb80503d8d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-shl.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-shl.mir @@ -135,8 +135,8 @@ body: | ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:1 ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1 %0:_(<4 x s16>) = COPY $d0 - %2:_(s16) = COPY $h0 - %1:_(s16) = G_CONSTANT i16 3 + %1:_(s16) = COPY $h0 + %2:_(s16) = G_CONSTANT i16 3 %3:_(<4 x s16>) = G_BUILD_VECTOR %1, %2, %2, %1 %4:_(<4 x s16>) = G_SHL %0, %3 ... From ab98b8cff12edb980421976a9b45e7eeccc9487a Mon Sep 17 00:00:00 2001 From: ningxinr Date: Fri, 12 Sep 2025 16:19:38 -0700 Subject: [PATCH 3/8] Initial attemp for sub --- llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp | 14 ++++++++++++++ .../CodeGen/AArch64/GlobalISel/knownbits-sub.mir | 10 +++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index 3f6813e52a1cc..8b278bba66c58 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -1959,6 +1959,20 @@ unsigned GISelValueTracking::computeNumSignBits(Register R, break; } + case TargetOpcode::G_SUB: { + Register Src1 = MI.getOperand(1).getReg(); + unsigned Src1NumSignBits = + computeNumSignBits(Src1, DemandedElts, Depth + 1); + if (Src1NumSignBits != 1) { + Register Src2 = MI.getOperand(2).getReg(); + unsigned Src2NumSignBits = + computeNumSignBits(Src2, DemandedElts, Depth + 1); + if (Src2NumSignBits == 1) + return 1; // Early out. + FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1; + } + break; + } case TargetOpcode::G_FCMP: case TargetOpcode::G_ICMP: { bool IsFP = Opcode == TargetOpcode::G_FCMP; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir index 8051bd2d17812..d91c39508d5de 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir @@ -82,7 +82,7 @@ body: | ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4 ; CHECK-NEXT: %3:_ KnownBits:00000000 SignBits:8 - ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:3 %0:_(s8) = COPY $b0 %1:_(s8) = G_CONSTANT i8 15 %2:_(s8) = G_AND %0, %1 @@ -110,7 +110,7 @@ body: | ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4 ; CHECK-NEXT: %3:_ KnownBits:00000101 SignBits:5 - ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:3 %0:_(s8) = COPY $b0 %1:_(s8) = G_CONSTANT i8 15 %2:_(s8) = G_AND %0, %1 @@ -154,7 +154,7 @@ body: | ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8 ; CHECK-NEXT: %4:_ KnownBits:0000000000000000 SignBits:16 ; CHECK-NEXT: %5:_ KnownBits:0000000000000000 SignBits:16 - ; CHECK-NEXT: %6:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %6:_ KnownBits:???????????????? SignBits:7 %0:_(<4 x s16>) = COPY $d0 %1:_(s16) = G_CONSTANT i16 255 %2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 @@ -189,7 +189,7 @@ body: | ; CHECK-NEXT: %4:_ KnownBits:0000000000101010 SignBits:10 ; CHECK-NEXT: %5:_ KnownBits:0000000001001010 SignBits:9 ; CHECK-NEXT: %6:_ KnownBits:000000000??01010 SignBits:9 - ; CHECK-NEXT: %7:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %7:_ KnownBits:???????????????? SignBits:7 %0:_(<4 x s16>) = COPY $d0 %1:_(s16) = G_CONSTANT i16 255 %2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 @@ -208,7 +208,7 @@ body: | ; CHECK-NEXT: %1:_ KnownBits:0000000000000110 SignBits:13 ; CHECK-NEXT: %2:_ KnownBits:0000000000000?1? SignBits:13 ; CHECK-NEXT: %3:_ KnownBits:0000000000000?1? SignBits:13 - ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %4:_ KnownBits:???????????????? SignBits:12 %0:_(s16) = G_CONSTANT i16 3 %1:_(s16) = G_CONSTANT i16 6 %2:_(<4 x s16>) = G_BUILD_VECTOR %0, %1, %1, %0 From 294002ada90096de3e017459be95dba098652185 Mon Sep 17 00:00:00 2001 From: ningxinr Date: Mon, 15 Sep 2025 11:07:33 -0700 Subject: [PATCH 4/8] Fix lit test CodeGen/ARM/GlobalISel/arm-legalize-bitcounts.mir --- .../test/CodeGen/ARM/GlobalISel/arm-legalize-bitcounts.mir | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-bitcounts.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-bitcounts.mir index c8fee5d334429..7cbe5de22debc 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-bitcounts.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-bitcounts.mir @@ -119,9 +119,10 @@ body: | ; CHECK: [[R32:%[0-9]+]]:_(s32) = G_SUB [[COUNT]], [[BITDIFF]] %2(s16) = G_CTLZ %1 - ; CHECK: [[SHIFTEDR:%[0-9]+]]:_(s32) = G_SHL [[R32]], [[BITDIFF]] - ; CHECK: [[R:%[0-9]+]]:_(s32) = G_ASHR [[SHIFTEDR]], [[BITDIFF]] - ; CHECK: $r0 = COPY [[R]] + ; LIBCALLS: [[SHIFTEDR:%[0-9]+]]:_(s32) = G_SHL [[R32]], [[BITDIFF]] + ; LIBCALLS: [[R:%[0-9]+]]:_(s32) = G_ASHR [[SHIFTEDR]], [[BITDIFF]] + ; LIBCALLS: $r0 = COPY [[R]] + ; CLZ: $r0 = COPY [[R32]] %3(s32) = G_SEXT %2(s16) $r0 = COPY %3(s32) BX_RET 14, $noreg, implicit $r0 From 12970b301e611d0d2d53382b234930d972be50c9 Mon Sep 17 00:00:00 2001 From: ningxinr Date: Mon, 15 Sep 2025 11:10:05 -0700 Subject: [PATCH 5/8] Handle Non Neg --- .../CodeGen/GlobalISel/GISelValueTracking.cpp | 37 +++++++++++++++---- .../AArch64/GlobalISel/knownbits-sub.mir | 4 +- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index 8b278bba66c58..a024b3b5755fa 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -1960,17 +1960,38 @@ unsigned GISelValueTracking::computeNumSignBits(Register R, break; } case TargetOpcode::G_SUB: { + Register Src2 = MI.getOperand(2).getReg(); + unsigned Src2NumSignBits = + computeNumSignBits(Src2, DemandedElts, Depth + 1); + if (Src2NumSignBits == 1) + return 1; // Early out. + + // Handle NEG. Register Src1 = MI.getOperand(1).getReg(); + KnownBits Known1 = getKnownBits(Src1, DemandedElts, Depth); + if (Known1.isZero()) { + KnownBits Known2 = getKnownBits(Src2, DemandedElts, Depth); + // If the input is known to be 0 or 1, the output is 0/-1, which is all + // sign bits set. + if ((Known2.Zero | 1).isAllOnes()) + return TyBits; + + // If the input is known to be positive (the sign bit is known clear), + // the output of the NEG has the same number of sign bits as the input. + if (Known2.isNonNegative()) + return Src2NumSignBits; + + // Otherwise, we treat this like a SUB. + } + unsigned Src1NumSignBits = computeNumSignBits(Src1, DemandedElts, Depth + 1); - if (Src1NumSignBits != 1) { - Register Src2 = MI.getOperand(2).getReg(); - unsigned Src2NumSignBits = - computeNumSignBits(Src2, DemandedElts, Depth + 1); - if (Src2NumSignBits == 1) - return 1; // Early out. - FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1; - } + if (Src1NumSignBits == 1) + return 1; // Early Out. + + // Sub can have at most one carry bit. Thus we know that the output + // is, at worst, one more bit than the inputs. + FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1; break; } case TargetOpcode::G_FCMP: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir index d91c39508d5de..7fdfb18dafeb2 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir @@ -82,7 +82,7 @@ body: | ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4 ; CHECK-NEXT: %3:_ KnownBits:00000000 SignBits:8 - ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:3 + ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:4 %0:_(s8) = COPY $b0 %1:_(s8) = G_CONSTANT i8 15 %2:_(s8) = G_AND %0, %1 @@ -154,7 +154,7 @@ body: | ; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8 ; CHECK-NEXT: %4:_ KnownBits:0000000000000000 SignBits:16 ; CHECK-NEXT: %5:_ KnownBits:0000000000000000 SignBits:16 - ; CHECK-NEXT: %6:_ KnownBits:???????????????? SignBits:7 + ; CHECK-NEXT: %6:_ KnownBits:???????????????? SignBits:8 %0:_(<4 x s16>) = COPY $d0 %1:_(s16) = G_CONSTANT i16 255 %2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 From 73f8bbd66500f23d326e23b1468e949d5cdcb937 Mon Sep 17 00:00:00 2001 From: Yatao Wang Date: Mon, 29 Sep 2025 15:02:23 -0700 Subject: [PATCH 6/8] Apply suggestions from code review Co-authored-by: Matt Arsenault --- llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir index 7fdfb18dafeb2..87a529eee635f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir @@ -1,5 +1,5 @@ # NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5 -# RUN: llc -mtriple aarch64 -passes="print" %s -o - 2>&1 | FileCheck %s +# RUN: llc -mtriple=aarch64 -passes='print' -filetype=null %s 2>&1 | FileCheck %s --- name: Cst From 0fb698779b717f0fbec215bb3b5160eafbc6d56b Mon Sep 17 00:00:00 2001 From: ningxinr Date: Mon, 29 Sep 2025 15:36:13 -0700 Subject: [PATCH 7/8] Added Cst Zero test and Cst Neg One test for vector --- .../AArch64/GlobalISel/knownbits-sub.mir | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir index 87a529eee635f..d498314694666 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir @@ -118,6 +118,36 @@ body: | %4:_(s8) = G_SUB %2, %3 ... --- +name: VectorCstZero +body: | + bb.1: + ; CHECK-LABEL: name: @VectorCstZero + ; CHECK-NEXT: %0:_ KnownBits:0000000000000000 SignBits:16 + ; CHECK-NEXT: %1:_ KnownBits:0000000000000000 SignBits:16 + ; CHECK-NEXT: %2:_ KnownBits:0000000000000000 SignBits:16 + ; CHECK-NEXT: %3:_ KnownBits:0000000000000000 SignBits:16 + %0:_(s16) = G_CONSTANT i16 0 + %1:_(<4 x s16>) = G_BUILD_VECTOR %0, %0, %0, %0 + %2:_(<4 x s16>) = G_BUILD_VECTOR %0, %0, %0, %0 + %3:_(<4 x s16>) = G_SUB %1, %2 +... +--- +name: VectorCstNegOne +body: | + bb.1: + ; CHECK-LABEL: name: @VectorCstNegOne + ; CHECK-NEXT: %0:_ KnownBits:0000000000000000 SignBits:16 + ; CHECK-NEXT: %1:_ KnownBits:0000000000000001 SignBits:15 + ; CHECK-NEXT: %2:_ KnownBits:0000000000000000 SignBits:16 + ; CHECK-NEXT: %3:_ KnownBits:0000000000000001 SignBits:15 + ; CHECK-NEXT: %4:_ KnownBits:1111111111111111 SignBits:16 + %0:_(s16) = G_CONSTANT i16 0 + %1:_(s16) = G_CONSTANT i16 1 + %2:_(<4 x s16>) = G_BUILD_VECTOR %0, %0, %0, %0 + %3:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1 + %4:_(<4 x s16>) = G_SUB %2, %3 +... +--- name: VectorVar body: | bb.1: From 18e79841d1630d362c807db125a9d0b2a4720485 Mon Sep 17 00:00:00 2001 From: ningxinr Date: Wed, 1 Oct 2025 08:58:51 -0700 Subject: [PATCH 8/8] Addressed feedback --- llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir index d498314694666..42ea007df19ca 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir @@ -1,5 +1,5 @@ # NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5 -# RUN: llc -mtriple=aarch64 -passes='print' -filetype=null %s 2>&1 | FileCheck %s +# RUN: llc -mtriple=aarch64 -passes="print" -filetype=null %s 2>&1 | FileCheck %s --- name: Cst