Skip to content

[GlobalISel] Add G_ABDU and G_ABDS to computeKnownBits.#186822

Merged
davemgreen merged 1 commit into
llvm:mainfrom
Xylecrack:gisel-abds-abdu
Mar 20, 2026
Merged

[GlobalISel] Add G_ABDU and G_ABDS to computeKnownBits.#186822
davemgreen merged 1 commit into
llvm:mainfrom
Xylecrack:gisel-abds-abdu

Conversation

@Xylecrack

Copy link
Copy Markdown
Contributor

This code is adapted from SelectionDAG::computeKnownBits
part of #150515
ticks off ABDS & ABDU

@llvmbot

llvmbot commented Mar 16, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-llvm-globalisel

Author: Dhruva (Xylecrack)

Changes

This code is adapted from SelectionDAG::computeKnownBits
part of #150515
ticks off ABDS & ABDU


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

4 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+26)
  • (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir (+76)
  • (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir (+88)
  • (modified) llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll (+9-20)
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 245ade77f736e..b8613aabe7fd1 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -372,6 +372,32 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
     Known = KnownBits::mulhs(Known, Known2);
     break;
   }
+  case TargetOpcode::G_ABDU: {
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), Known, DemandedElts,
+                         Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts,
+                         Depth + 1);
+    Known = KnownBits::abdu(Known, Known2);
+    break;
+  }
+  case TargetOpcode::G_ABDS: {
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), Known, DemandedElts,
+                         Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts,
+                         Depth + 1);
+    Known = KnownBits::abds(Known, Known2);
+
+    unsigned SignBits1 =
+        computeNumSignBits(MI.getOperand(2).getReg(), DemandedElts, Depth + 1);
+    if (SignBits1 == 1) {
+      break;
+    }
+    unsigned SignBits0 =
+        computeNumSignBits(MI.getOperand(1).getReg(), DemandedElts, Depth + 1);
+
+    Known.Zero.setHighBits(std::min(SignBits0, SignBits1) - 1);
+    break;
+  }
   case TargetOpcode::G_UDIV: {
     computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
                          Depth + 1);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir
new file mode 100644
index 0000000000000..02cbc98af950a
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir
@@ -0,0 +1,76 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=aarch64 -passes="print<gisel-value-tracking>" -filetype=null %s 2>&1 | FileCheck %s
+
+---
+name: Cst
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @Cst
+  ; CHECK-NEXT: %0:_ KnownBits:00001010 SignBits:4
+  ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6
+  ; CHECK-NEXT: %2:_ KnownBits:00000111 SignBits:5
+    %0:_(s8) = G_CONSTANT i8 10
+    %1:_(s8) = G_CONSTANT i8 3
+    %2:_(s8) = G_ABDS %0, %1
+...
+---
+name: PartialKnown
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @PartialKnown
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %3:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4
+    %0:_(s8) = G_IMPLICIT_DEF
+    %1:_(s8) = G_CONSTANT i8 15
+    %2:_(s8) = G_AND %0, %1
+    %3:_(s8) = G_CONSTANT i8 4
+    %4:_(s8) = G_ABDS %2, %3
+...
+
+---
+name: SignBits
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @SignBits
+  ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:25
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:25
+  ; CHECK-NEXT: %4:_ KnownBits:000000000000000000000000???????? SignBits:24
+    %0:_(s32) = COPY $w0
+    %1:_(s32) = COPY $w1
+    %2:_(s32) = G_SEXT_INREG %0, 8
+    %3:_(s32) = G_SEXT_INREG %1, 8
+    %4:_(s32) = G_ABDS %2, %3
+...
+---
+name: SignBitsAsymmetric
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @SignBitsAsymmetric
+  ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:25
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:17
+  ; CHECK-NEXT: %4:_ KnownBits:0000000000000000???????????????? SignBits:16
+    %0:_(s32) = COPY $w0
+    %1:_(s32) = COPY $w1
+    %2:_(s32) = G_SEXT_INREG %0, 8
+    %3:_(s32) = G_SEXT_INREG %1, 16
+    %4:_(s32) = G_ABDS %2, %3
+...
+---
+name: Unknown
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @Unknown
+  ; 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_ABDS %0, %1
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir
new file mode 100644
index 0000000000000..aa624bf377e46
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir
@@ -0,0 +1,88 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s
+
+---
+name: Cst
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @Cst
+  ; CHECK-NEXT: %0:_ KnownBits:00000101 SignBits:5
+  ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6
+  ; CHECK-NEXT: %2:_ KnownBits:00000010 SignBits:6
+    %0:_(s8) = G_CONSTANT i8 5
+    %1:_(s8) = G_CONSTANT i8 3
+    %2:_(s8) = G_ABDU %0, %1
+...
+---
+name: CstZero
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @CstZero
+  ; CHECK-NEXT: %0:_ KnownBits:11111111 SignBits:8
+  ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %2:_ KnownBits:11111111 SignBits:8
+    %0:_(s8) = G_CONSTANT i8 255
+    %1:_(s8) = G_CONSTANT i8 0
+    %2:_(s8) = G_ABDU %0, %1
+...
+---
+name: ScalarZero
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarZero
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1
+    %0:_(s8) = COPY $b0
+    %1:_(s8) = G_CONSTANT i8 0
+    %2:_(s8) = G_ABDU %0, %1
+...
+---
+name: PartialKnown
+body: |
+  bb.0:
+
+  ; CHECK-LABEL: name: @PartialKnown
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4
+  ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4
+  ; CHECK-NEXT: %3:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4
+    %0:_(s8) = G_IMPLICIT_DEF
+    %1:_(s8) = G_CONSTANT i8 15
+    %2:_(s8) = G_AND %0, %1
+    %3:_(s8) = G_CONSTANT i8 4
+    %4:_(s8) = G_ABDU %2, %3
+...
+---
+name: NoSignBitsPath
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @NoSignBitsPath
+  ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:25
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:25
+  ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????? SignBits:1
+    %0:_(s32) = COPY $w0
+    %1:_(s32) = COPY $w1
+    %2:_(s32) = G_SEXT_INREG %0, 8
+    %3:_(s32) = G_SEXT_INREG %1, 8
+    %4:_(s32) = G_ABDU %2, %3
+...
+---
+name: VecCst
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @VecCst
+  ; CHECK-NEXT: %0:_ KnownBits:00000101 SignBits:5
+  ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6
+  ; CHECK-NEXT: %2:_ KnownBits:00000??1 SignBits:5
+  ; CHECK-NEXT: %3:_ KnownBits:00000??1 SignBits:5
+  ; CHECK-NEXT: %4:_ KnownBits:00000??0 SignBits:5
+    %0:_(s8) = G_CONSTANT i8 5
+    %1:_(s8) = G_CONSTANT i8 3
+    %2:_(<2 x s8>) = G_BUILD_VECTOR %0, %1
+    %3:_(<2 x s8>) = G_BUILD_VECTOR %0, %1
+    %4:_(<2 x s8>) = G_ABDU %2, %3
+...
diff --git a/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll b/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll
index ccd1917ae3d85..062f5de38c45b 100644
--- a/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll
@@ -303,26 +303,15 @@ define <2 x double> @test_fabd_v2f64(<2 x double> %lhs, <2 x double> %rhs) {
 }
 
 define <8 x i16> @test_uabd_knownbits_vec8i16(<8 x i16> %lhs, <8 x i16> %rhs) {
-; CHECK-SD-LABEL: test_uabd_knownbits_vec8i16:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    movi v2.8h, #15
-; CHECK-SD-NEXT:    and v0.16b, v0.16b, v2.16b
-; CHECK-SD-NEXT:    and v1.16b, v1.16b, v2.16b
-; CHECK-SD-NEXT:    uabd v0.8h, v0.8h, v1.8h
-; CHECK-SD-NEXT:    rev64 v0.8h, v0.8h
-; CHECK-SD-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: test_uabd_knownbits_vec8i16:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    movi v2.8h, #15
-; CHECK-GI-NEXT:    and v0.16b, v0.16b, v2.16b
-; CHECK-GI-NEXT:    and v1.16b, v1.16b, v2.16b
-; CHECK-GI-NEXT:    uabd v0.8h, v0.8h, v1.8h
-; CHECK-GI-NEXT:    rev64 v0.8h, v0.8h
-; CHECK-GI-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
-; CHECK-GI-NEXT:    and v0.16b, v0.16b, v2.16b
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: test_uabd_knownbits_vec8i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    movi v2.8h, #15
+; CHECK-NEXT:    and v0.16b, v0.16b, v2.16b
+; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
+; CHECK-NEXT:    uabd v0.8h, v0.8h, v1.8h
+; CHECK-NEXT:    rev64 v0.8h, v0.8h
+; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT:    ret
   %and1 = and <8 x i16> %lhs, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
   %and2 = and <8 x i16> %rhs, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
   %uabd = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %and1, <8 x i16> %and2)

@github-actions

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 3166 tests passed
  • 7 tests skipped

All executed tests passed, but another part of the build failed. Click on a failure below to see the details.

lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/VPlanAnalysis.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/VPlanAnalysis.cpp.o
sccache /opt/llvm/bin/clang++ -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/Transforms/Vectorize -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Transforms/Vectorize -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -std=c++17 -UNDEBUG -fno-exceptions -funwind-tables -fno-rtti -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/VPlanAnalysis.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/VPlanAnalysis.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/VPlanAnalysis.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp:458:19: error: variable 'DefR' set but not used [-Werror,-Wunused-but-set-variable]
458 |         if (auto *DefR = U->getDefiningRecipe()) {
|                   ^
1 error generated.

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@davemgreen davemgreen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - thanks for the patch.

@Xylecrack

Copy link
Copy Markdown
Contributor Author

@davemgreen hi, if there are no further changes required from my side, can the PR be merged?

@davemgreen

Copy link
Copy Markdown
Contributor

Sound good - the failure was unrelated. Pushing now.

@davemgreen davemgreen enabled auto-merge (squash) March 20, 2026 17:08
@davemgreen davemgreen disabled auto-merge March 20, 2026 17:08
@davemgreen davemgreen merged commit 68a9e9c into llvm:main Mar 20, 2026
12 of 13 checks passed
@Xylecrack Xylecrack deleted the gisel-abds-abdu branch March 24, 2026 16:05
Aadarsh-Keshri pushed a commit to Aadarsh-Keshri/llvm-project that referenced this pull request Mar 28, 2026
This code is adapted from `SelectionDAG::computeKnownBits`
part of llvm#150515 
ticks off ABDS & ABDU
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants