[llvm] [InstCombine] Narrow the ctpop when upper bits are known zero (PR #196537)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri May 8 07:18:49 PDT 2026


dtcxzyw wrote:

The following correctness issue was found by [llvm-hackme](https://github.com/dtcxzyw/llvm-hackme).

<!-- llvm-hackme-state: bug_found -->
<!-- llvm-hackme-baseline: 6d9c57ba52c9511eb82722c38bc23f7cd6fea6a3 -->
<!-- llvm-hackme-head-sha: ce67cdb53b2f64d8ab73c26e153760a8fd25c989 -->
<!-- llvm-hackme-patch-sha256: a8188e1a0abff22f10d9f4c128067e44cc39d08cbf6dbb7db8a28311ee6bf041 -->
<!-- llvm-hackme-kind: miscompilation -->

This comment is generated by an automated correctness checking service designed to help identify critical correctness bugs (opt crashes or Alive2 miscompilations) and improve PR review efficiency under limited reviewer bandwidth.

## Reproducer

**Kind**: miscompilation

**IR Reproducer**:
```llvm
; RUN: opt -passes=instcombine<no-verify-fixpoint> -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"


define i65 @f(i65 %x) {
  %masked = and i65 %x, 8589934591
  %pop = call i65 @llvm.ctpop.i65(i65 %masked)
  ret i65 %pop
}
```

**Alive2 Counterexample**:
```
----------------------------------------
define i65 @f(i65 %x) {
#0:
  %masked = and i65 %x, 8589934591
  %pop = ctpop i65 %masked
  ret i65 %pop
}
=>
define i65 @f(i65 %x) {
#0:
  %#1 = trunc i65 %x to i32
  %#2 = ctpop i32 %#1
  %#range_0_%#2 = !range i32 %#2, i32 0, i32 33
  %pop = zext nneg i32 %#range_0_%#2 to i65
  ret i65 %pop
}
Transformation doesn't verify!

ERROR: Value mismatch

Example:
i65 %x = #x00000000180e18a00 (6457231872)

Source:
i65 %masked = #x00000000180e18a00 (6457231872)
i65 %pop = #x00000000000000009 (9)

Target:
i32 %#1 = #x80e18a00 (2162264576, -2132702720)
i32 %#2 = #x00000008 (8)
i32 %#range_0_%#2 = #x00000008 (8)
i65 %pop = #x00000000000000008 (8)
Source value: #x00000000000000009 (9)
Target value: #x00000000000000008 (8)

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors
```

**Opt Output**:
```llvm
; ModuleID = '/tmp/tmp0218zoec.ll'
source_filename = "/tmp/tmp0218zoec.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare i65 @llvm.ctpop.i65(i65) #0

define i65 @f(i65 %x) {
  %1 = trunc i65 %x to i32
  %2 = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 %1)
  %pop = zext nneg i32 %2 to i65
  ret i65 %pop
}

; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.ctpop.i32(i32) #0

attributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
```


**Baseline Revision**: `6d9c57ba52c9511eb82722c38bc23f7cd6fea6a3`
**PR Head SHA**: `ce67cdb53b2f64d8ab73c26e153760a8fd25c989`
**Patch SHA256**: `a8188e1a0abff22f10d9f4c128067e44cc39d08cbf6dbb7db8a28311ee6bf041`


https://github.com/llvm/llvm-project/pull/196537


More information about the llvm-commits mailing list