Skip to content

[GlobalISel] Add G_UDIV/G_SDIV computeKnownBits#181307

Merged
arsenm merged 2 commits into
llvm:mainfrom
aeft:feat/globalisel-known-bit-support-udiv-sdiv
Feb 18, 2026
Merged

[GlobalISel] Add G_UDIV/G_SDIV computeKnownBits#181307
arsenm merged 2 commits into
llvm:mainfrom
aeft:feat/globalisel-known-bit-support-udiv-sdiv

Conversation

@aeft

@aeft aeft commented Feb 13, 2026

Copy link
Copy Markdown
Member

Code ported from SelectionDAG::computeKnownBits.

Related: #150515

Code ported from SelectionDAG::computeKnownBits.
@llvmbot

llvmbot commented Feb 13, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-llvm-globalisel

@llvm/pr-subscribers-backend-aarch64

Author: Alex Wang (aeft)

Changes

Code ported from SelectionDAG::computeKnownBits.

Related: #150515


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

3 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+18)
  • (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sdiv.mir (+67)
  • (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-udiv.mir (+55)
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index fce06dfde0edc..6fe91406ce958 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -368,6 +368,24 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
     Known = KnownBits::mulhs(Known, Known2);
     break;
   }
+  case TargetOpcode::G_UDIV: {
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
+                         Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), Known2, DemandedElts,
+                         Depth + 1);
+    Known = KnownBits::udiv(Known, Known2,
+                            MI.getFlag(MachineInstr::MIFlag::IsExact));
+    break;
+  }
+  case TargetOpcode::G_SDIV: {
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
+                         Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), Known2, DemandedElts,
+                         Depth + 1);
+    Known = KnownBits::sdiv(Known, Known2,
+                            MI.getFlag(MachineInstr::MIFlag::IsExact));
+    break;
+  }
   case TargetOpcode::G_SELECT: {
     computeKnownBitsMin(MI.getOperand(2).getReg(), MI.getOperand(3).getReg(),
                         Known, DemandedElts, Depth + 1);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sdiv.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sdiv.mir
new file mode 100644
index 0000000000000..7b315205bc2e8
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sdiv.mir
@@ -0,0 +1,67 @@
+# 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:01100100 SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:000????? SignBits:3
+    %0:_(s8) = G_CONSTANT i8 100
+    %1:_(s8) = G_CONSTANT i8 4
+    %2:_(s8) = G_SDIV %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:000000?? SignBits:6
+    %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_SDIV %2, %3
+...
+---
+name: Exact
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @Exact
+  ; CHECK-NEXT: %0:_ KnownBits:00001100 SignBits:4
+  ; CHECK-NEXT: %1:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:000000?1 SignBits:6
+    %0:_(s8) = G_CONSTANT i8 12
+    %1:_(s8) = G_CONSTANT i8 4
+    %2:_(s8) = exact G_SDIV %0, %1
+...
+---
+name: NegDividend
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @NegDividend
+  ; CHECK-NEXT: %0:_ KnownBits:11110000 SignBits:4
+  ; CHECK-NEXT: %1:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:111111?? SignBits:6
+    %0:_(s8) = G_CONSTANT i8 -16
+    %1:_(s8) = G_CONSTANT i8 4
+    %2:_(s8) = G_SDIV %0, %1
+...
+---
+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_SDIV %0, %1
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-udiv.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-udiv.mir
new file mode 100644
index 0000000000000..dfbcd3f3c6188
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-udiv.mir
@@ -0,0 +1,55 @@
+# 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:01100100 SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:000????? SignBits:3
+    %0:_(s8) = G_CONSTANT i8 100
+    %1:_(s8) = G_CONSTANT i8 4
+    %2:_(s8) = G_UDIV %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:000000?? SignBits:6
+    %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_UDIV %2, %3
+...
+---
+name: Exact
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @Exact
+  ; CHECK-NEXT: %0:_ KnownBits:00001100 SignBits:4
+  ; CHECK-NEXT: %1:_ KnownBits:00000100 SignBits:5
+  ; CHECK-NEXT: %2:_ KnownBits:000000?1 SignBits:6
+    %0:_(s8) = G_CONSTANT i8 12
+    %1:_(s8) = G_CONSTANT i8 4
+    %2:_(s8) = exact G_UDIV %0, %1
+...
+---
+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_UDIV %0, %1
+...

@github-actions

github-actions Bot commented Feb 13, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 190016 tests passed
  • 5072 tests skipped

✅ The build succeeded and all tests passed.

@github-actions

github-actions Bot commented Feb 13, 2026

Copy link
Copy Markdown

🪟 Windows x64 Test Results

  • 130831 tests passed
  • 2937 tests skipped

✅ The build succeeded and all tests passed.

@aeft aeft temporarily deployed to main-branch-only February 13, 2026 05:51 — with GitHub Actions Inactive
@aeft

aeft commented Feb 13, 2026

Copy link
Copy Markdown
Member Author

Note three *.ll files are also updated.

After supporting computeKnownBits for G_UDIV, the compiler can now infer leading zeros of the udiv result. When the divisor is also known to be narrow (e.g., zero-extended from i8), the compiler selects narrower multiply-subtract instructions: mls -> umlsl (vector, in rem.ll and arm64-neon-mul-div.ll), msub -> umsubl (scalar, in funnel-shift.ll).

@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.

Sounds sensible. Thanks. LGTM.

@aeft

aeft commented Feb 17, 2026

Copy link
Copy Markdown
Member Author

@davemgreen Thanks for the review! Could you please land this when you have a chance?

@arsenm arsenm merged commit 4506982 into llvm:main Feb 18, 2026
10 checks passed
Michael137 pushed a commit to Michael137/llvm-project that referenced this pull request Feb 19, 2026
Code ported from `SelectionDAG::computeKnownBits`.

Related: llvm#150515
@aeft aeft deleted the feat/globalisel-known-bit-support-udiv-sdiv branch March 7, 2026 00:05
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.

4 participants