Skip to content

[DemandedBits] Track demanded bits for clmul instrinsics - #202415

Merged
dtcxzyw merged 1 commit into
llvm:mainfrom
8051Enthusiast:clmul-demanded-bits
Jul 4, 2026
Merged

[DemandedBits] Track demanded bits for clmul instrinsics#202415
dtcxzyw merged 1 commit into
llvm:mainfrom
8051Enthusiast:clmul-demanded-bits

Conversation

@8051Enthusiast

Copy link
Copy Markdown
Contributor

Similar to regular multiplication, carryless multiplication does not depend on bits in positions higher than the output bits.

No alive2 proof since clmul is not supported, but the implementation is the same as for Instruction::mul.

@llvmorg-github-actions llvmorg-github-actions Bot added the llvm:analysis Includes value tracking, cost tables and constant folding label Jun 8, 2026
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-llvm-analysis

Author: 8051Enthusiast

Changes

Similar to regular multiplication, carryless multiplication does not depend on bits in positions higher than the output bits.

No alive2 proof since clmul is not supported, but the implementation is the same as for Instruction::mul.


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

2 Files Affected:

  • (modified) llvm/lib/Analysis/DemandedBits.cpp (+5)
  • (modified) llvm/test/Analysis/DemandedBits/intrinsics.ll (+13)
diff --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp
index e0881751aef7e..35de778d9f093 100644
--- a/llvm/lib/Analysis/DemandedBits.cpp
+++ b/llvm/lib/Analysis/DemandedBits.cpp
@@ -114,6 +114,11 @@ void DemandedBits::determineLiveOperandBits(
         // the output.
         AB = AOut.reverseBits();
         break;
+      case Intrinsic::clmul:
+        // Output bits only depend on input bits with lower or
+        // equal bit index.
+        AB = APInt::getLowBitsSet(BitWidth, AOut.getActiveBits());
+        break;
       case Intrinsic::ctlz:
         if (OperandNo == 0) {
           // We need some output bits, so we need all bits of the
diff --git a/llvm/test/Analysis/DemandedBits/intrinsics.ll b/llvm/test/Analysis/DemandedBits/intrinsics.ll
index 0421b23202a2c..225c7cd4feef9 100644
--- a/llvm/test/Analysis/DemandedBits/intrinsics.ll
+++ b/llvm/test/Analysis/DemandedBits/intrinsics.ll
@@ -109,3 +109,16 @@ define i33 @test_fshr_non_pow2_bitwidth(i33 %x, i33 %y, i33 %z) {
   %r = and i33 %f, 65535
   ret i33 %r
 }
+
+; CHECK-LABEL: Printing analysis 'Demanded Bits Analysis' for function 'test_clmul':
+; CHECK-DAG: DemandedBits: 0xffff for   %x2 = or i32 %x, 1
+; CHECK-DAG: DemandedBits: 0xffff for   %y2 = or i32 %y, 1
+; CHECK-DAG: DemandedBits: 0xff00 for   %z = call i32 @llvm.clmul.i32(i32 %x2, i32 %y2)
+; CHECK-DAG: DemandedBits: 0xffffffff for   %r = and i32 %z, 65280
+define i32 @test_clmul(i32 %x, i32 %y) {
+  %x2 = or i32 %x, 1
+  %y2 = or i32 %y, 1
+  %z = call i32 @llvm.clmul.i32(i32 %x2, i32 %y2)
+  %r = and i32 %z, 65280
+  ret i32 %r
+}

Similar to regular multiplication, carryless multiplication does
not depend on bits in positions higher than the output bits.

No alive2 proof since clmul is not supported, but the
implementation is the same as for Instruction::mul.
@8051Enthusiast 8051Enthusiast changed the title [DemandedBits] Add clmul support [[DemandedBits] Track demanded bits for clmul instrinsics Jul 3, 2026
@8051Enthusiast 8051Enthusiast changed the title [[DemandedBits] Track demanded bits for clmul instrinsics [DemandedBits] Track demanded bits for clmul instrinsics Jul 3, 2026
@8051Enthusiast

Copy link
Copy Markdown
Contributor Author

CC @topperc @artagnon: Can someone of you review (and eventually merge), should hopefully be a simple change.

@artagnon
artagnon requested review from dtcxzyw and topperc July 4, 2026 07:17

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

@dtcxzyw

dtcxzyw commented Jul 4, 2026

Copy link
Copy Markdown
Member

The clmul support is available now (see AliveToolkit/alive2#1318). But it hasn't been deployed to alive2.llvm.org.

; ./alive-tv --disable-undef-input test.ll
define i8 @src(i8 %x, i8 %y, i8 range(i8 1, 0) %demanded) {
  %clmul = call i8 @llvm.clmul.i8(i8 %x, i8 %y)
  %masked = and i8 %clmul, %demanded
  ret i8 %masked
}

define i8 @tgt(i8 %x, i8 %y, i8 %demanded) {
  %lz = call i8 @llvm.ctlz.i8(i8 %demanded, i1 true)
  %mask = lshr i8 -1, %lz
  %masked_x = and i8 %x, %mask
  %masked_y = and i8 %y, %mask
  %clmul = call i8 @llvm.clmul.i8(i8 %masked_x, i8 %masked_y)
  %masked = and i8 %clmul, %demanded
  ret i8 %masked
}
----------------------------------------
define i8 @src(i8 %x, i8 %y, i8 %demanded) {
init:
  %#range_0_%demanded = !range i8 %demanded, i8 1, i8 0
  br label %#0

#0:
  %clmul = clmul i8 %x, %y
  %masked = and i8 %clmul, %#range_0_%demanded
  ret i8 %masked
}
=>
define i8 @tgt(i8 %x, i8 %y, i8 %demanded) {
#0:
  %lz = ctlz i8 %demanded, 1
  %mask = lshr i8 255, %lz
  %masked_x = and i8 %x, %mask
  %masked_y = and i8 %y, %mask
  %clmul = clmul i8 %masked_x, %masked_y
  %masked = and i8 %clmul, %demanded
  ret i8 %masked
}
Transformation seems to be correct!

@dtcxzyw
dtcxzyw merged commit 33be799 into llvm:main Jul 4, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:analysis Includes value tracking, cost tables and constant folding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants