[llvm-slicer] callback passed to bsearch is missliced (definition dropped, symbol unresolved)
Hi, thanks for maintaining dg and llvm-slicer.
We may have found a slicing correctness issue and wanted to report it with a
minimal reproducer below.
Summary
For a program using bsearch with a callback comparator, slicing with
-c __assert_fail changes module correctness: the sliced IR keeps the
bsearch(..., @cmp) use-site, but drops the cmp function body (leaving only
a declaration). The sliced program then fails to run due to unresolved symbol.
This is a semantic/runtime regression introduced by slicing
(orig PASS, unsliced-bc PASS, sliced FAIL).
Environment
- dg commit:
dc3615d03fedfce62f37604b45d22e31c9d7e557
- slicer:
llvm-slicer (built from this dg checkout)
- clang:
Ubuntu clang version 14.0.0-1ubuntu1.1
- lli:
Ubuntu LLVM version 14.0.0
- OS:
Linux x86_64 (WSL2)
Minimal Reproducer
#include <assert.h>
#include <stdlib.h>
static int cmp(const void *a, const void *b) {
int x = *(const int *)a, y = *(const int *)b;
return (x > y) - (x < y);
}
int main(void) {
int v[4] = {1, 2, 4, 9};
int key = 4;
int *p = (int *)bsearch(&key, v, 4, sizeof(int), cmp);
assert(p && *p == 4);
return 0;
}
Reproduction Steps
cat > /tmp/min_callback_escape_bsearch.c <<'EOF'
#include <assert.h>
#include <stdlib.h>
static int cmp(const void *a, const void *b) {
int x = *(const int *)a, y = *(const int *)b;
return (x > y) - (x < y);
}
int main(void) {
int v[4] = {1, 2, 4, 9};
int key = 4;
int *p = (int *)bsearch(&key, v, 4, sizeof(int), cmp);
assert(p && *p == 4);
return 0;
}
EOF
clang-14 -O0 -g -c -emit-llvm /tmp/min_callback_escape_bsearch.c -o /tmp/min_callback_escape_bsearch.bc
lli-14 /tmp/min_callback_escape_bsearch.bc
llvm-slicer -c __assert_fail /tmp/min_callback_escape_bsearch.bc -o /tmp/min_callback_escape_bsearch.sliced.bc
lli-14 /tmp/min_callback_escape_bsearch.sliced.bc
Actual Result
- Unsliced run passes.
- Sliced run fails:
JIT session error: Symbols not found: [ cmp ]
lli-14: Failed to materialize symbols: { (main, { main }) }
Expected Result
Slicing should preserve callback definitions that escape through function-pointer
arguments to external calls (here bsearch), or otherwise keep the sliced
module internally consistent and runnable.
IR Evidence
Sliced IR still uses @cmp at call site:
%9 = call i8* @bsearch(..., i32 (i8*, i8*)* noundef @cmp)
but only keeps declaration (definition dropped):
declare dso_local i32 @cmp(i8* noundef, i8* noundef)
This leads to unresolved symbol at runtime.
[llvm-slicer] callback passed to
bsearchis missliced (definition dropped, symbol unresolved)Hi, thanks for maintaining
dgandllvm-slicer.We may have found a slicing correctness issue and wanted to report it with a
minimal reproducer below.
Summary
For a program using
bsearchwith a callback comparator, slicing with-c __assert_failchanges module correctness: the sliced IR keeps thebsearch(..., @cmp)use-site, but drops thecmpfunction body (leaving onlya declaration). The sliced program then fails to run due to unresolved symbol.
This is a semantic/runtime regression introduced by slicing
(
orig PASS,unsliced-bc PASS,sliced FAIL).Environment
dc3615d03fedfce62f37604b45d22e31c9d7e557llvm-slicer(built from this dg checkout)Ubuntu clang version 14.0.0-1ubuntu1.1Ubuntu LLVM version 14.0.0Linux x86_64 (WSL2)Minimal Reproducer
Reproduction Steps
Actual Result
Expected Result
Slicing should preserve callback definitions that escape through function-pointer
arguments to external calls (here
bsearch), or otherwise keep the slicedmodule internally consistent and runnable.
IR Evidence
Sliced IR still uses
@cmpat call site:but only keeps declaration (definition dropped):
This leads to unresolved symbol at runtime.