From 0c5a63d274cd964fe7127c6e9f2dd50f9e62c9d6 Mon Sep 17 00:00:00 2001 From: ningxinr Date: Fri, 12 Sep 2025 12:05:03 -0700 Subject: [PATCH 1/3] 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..f9c20b7ffaeab --- /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 + %2:_(s16) = COPY $h0 + %1:_(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 4faee5177dd6a6df0ad795cd2743dc1398c03f1c Mon Sep 17 00:00:00 2001 From: ningxinr Date: Fri, 12 Sep 2025 13:42:57 -0700 Subject: [PATCH 2/3] 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 e6ff80186d84f305ae239885e9ea2520cd87f00a Mon Sep 17 00:00:00 2001 From: ningxinr Date: Fri, 12 Sep 2025 16:19:38 -0700 Subject: [PATCH 3/3] 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 0cf44e02254de..294a76b885f06 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -1976,6 +1976,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 f9c20b7ffaeab..452c29a369179 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