[clang] [llvm] [InstCombine] Relax singleUse for GEP(p,add(x,constant)) to 2 GEPs (PR #209551)
Yingwei Zheng via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 23 13:47:26 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: 8b0eab156025a55819868daf76ff32e28829d06a -->
<!-- llvm-hackme-head-sha: d5ccac53702f3668fb7a297045ae74b22c7a939f -->
<!-- llvm-hackme-patch-sha256: aae8da0294910f3e24d24f7fd1972684030409a96c138fef550ccd00bcded50a -->
<!-- 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.
The reproducer was generated by LLM.
This bug is a regression introduced by this PR. It does not reproduce on the baseline commit.
## Reproducer
**Kind**: miscompilation
**IR Reproducer**:
```llvm
; RUN: opt -passes=instcombine<no-verify-fixpoint> -S
target datalayout = "p:64:64:64:32"
declare void @use(i32)
define i64 @f(ptr %p, i32 %x) {
%idx = add i32 %x, 1
call void @use(i32 %idx)
%gep = getelementptr i32, ptr %p, i32 %idx
%res = ptrtoint ptr %gep to i64
ret i64 %res
}
```
**Alive2 Counterexample**:
```
----------------------------------------
declare void @use(i32)
define i64 @f(ptr %p, i32 %x) {
#0:
%idx = add i32 %x, 1
call void @use(i32 %idx)
%gep = gep ptr %p, 4 x i32 %idx
%res = ptrtoint ptr %gep to i64
ret i64 %res
}
=>
declare void @use(i32)
define i64 @f(ptr %p, i32 %x) {
#0:
%idx = add i32 %x, 1
call void @use(i32 %idx)
%#1 = gep ptr %p, 4 x i32 %x
%gep = gep ptr %#1, 1 x i32 4
%res = ptrtoint ptr %gep to i64
ret i64 %res
}
Transformation doesn't verify!
ERROR: Value mismatch
Example:
ptr %p = null
i32 %x = #x7fffffff (2147483647)
Source:
i32 %idx = #x80000000 (2147483648, -2147483648)
Function @use returned
ptr %gep = pointer(non-local, block_id=0, offset=-8589934592) / Address=#xfffffffe00000000
i64 %res = #xfffffffe00000000 (18446744065119617024, -8589934592)
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0 alive: false address: #x0000000000000000
Block 1 > size: 0 align: 1 alloc type: 4 alive: true address: #x0000000000000008
Block 2 > size: 0 align: 1 alloc type: 1 alive: true address: #x0000000000000002
Target:
i32 %idx = #x80000000 (2147483648, -2147483648)
Function @use returned
ptr %#1 = pointer(non-local, block_id=0, offset=8589934588) / Address=#x00000001fffffffc
ptr %gep = pointer(non-local, block_id=0, offset=8589934592) / Address=#x0000000200000000
i64 %res = #x0000000200000000 (8589934592)
TARGET MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0 alive: false address: #x0000000000000000
Block 1 > size: 0 align: 1 alloc type: 4 alive: true address: #x0000000000000008
Block 2 > size: 0 align: 1 alloc type: 1 alive: true address: #x0000000000000002
Source value: #xfffffffe00000000 (18446744065119617024, -8589934592)
Target value: #x0000000200000000 (8589934592)
Summary:
0 correct transformations
1 incorrect transformations
0 failed-to-prove transformations
0 Alive2 errors
```
**Opt Output**:
```llvm
; ModuleID = '/tmp/tmp6cuwkikb.ll'
source_filename = "/tmp/tmp6cuwkikb.ll"
target datalayout = "p:64:64:64:32"
declare void @use(i32)
define i64 @f(ptr %p, i32 %x) {
%idx = add i32 %x, 1
call void @use(i32 %idx)
%1 = getelementptr [4 x i8], ptr %p, i32 %x
%gep = getelementptr i8, ptr %1, i32 4
%res = ptrtoint ptr %gep to i64
ret i64 %res
}
```
**Baseline Revision**: `8b0eab156025a55819868daf76ff32e28829d06a`
**PR Head SHA**: `d5ccac53702f3668fb7a297045ae74b22c7a939f`
**Patch SHA256**: `aae8da0294910f3e24d24f7fd1972684030409a96c138fef550ccd00bcded50a`
https://github.com/llvm/llvm-project/pull/209551
More information about the cfe-commits
mailing list