ConstraintEliminationPass incorrectly replaces a i256 ne with a constant false. #68751
Description
manual_min.ll is a llvm ir program that displays a miscompile.
This reproduces using llvm as of commit: ff5e2ba
Unfortunately due to not causing any crash I was unable to minimize it any more than this since whatever I tried bugpoint would either reduce it to nothing or not change anything.
Bug code is generated from an xls program below:
DSLX
fn main(x4: u51) -> bool {
let x5: u51 = bit_slice_update(x4, x4, x4);
let x6: uN[102] = x5 ++ x5;
let x9: uN[153] = x6 ++ x5;
let gate_src: bool = x6 as uN[153] != x9;
gate_src
}
XLS IR
package crasher_manual_min2
file_number 0 "xls/fuzzer/crashers/crasher_manual_min2.x"
fn __crasher_manual_min2__main(x4: bits[51]) -> bits[1] {
// bit_slice_update(a, b, c) returns 'a' with bits starting at index 'b' replaced with the bits of 'c'
x5: bits[51] = bit_slice_update(x4, x4, x4, id=2, pos=[(0,54,38)])
x6: bits[102] = concat(x5, x5, id=3, pos=[(0,55,29)])
zero_ext.5: bits[153] = zero_ext(x6, new_bit_count=153, id=5)
x9: bits[153] = concat(x6, x5, id=4, pos=[(0,56,29)])
ret gate_src: bits[1] = ne(zero_ext.5, x9, id=6, pos=[(0,58,43)])
}
This is compiled using the xls jit compiler to LLVM. This code is linked with a runner below which simply executes this program on the numbers [0, 256] and prints each result. This should result in a zero byte followed by all 0x1 bytes.
% cat manual_min_runner.bc | lli | hd
00000000 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
00000010 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|
*
00000100
Runner code
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
extern char __crasher_manual_min2__main(void* inputs, void* outputs, void* buf, void* events, void* user_data, void* rt, long long int cont);
typedef int64_t i64;
// returns a bool
char tryone(i64 v) {
void* inp_ptr[1];
i64 bit64 = v;
inp_ptr[0] = &bit64;
void* out_ptr[1];
char val = 0;
out_ptr[0] = &val;
void* temp_buf[1];
void* user_data[1];
__crasher_manual_min2__main(inp_ptr, out_ptr, temp_buf, 0, 0, 0, 0);
return val;
}
int main() {
// return (tryone(1) << 1) | tryone(0);
for (int i = 0; i < 256; ++i) {
char r = tryone(i);
write(1, &r, sizeof(char));
}
return 0;
}
% cat manual_min_runner.opt.bc | lli | hd
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000100
This is based on the investigation for google/xls#1146
Repro build process:
% opt manual_min.llvm.ir --O3 -opt-bisect-limit=$current_id > bisect_manual_min.llvm.opt.bc
% clang -S -emit-llvm manual_min_runner.c -o manual_min_runner.ll
% opt manual_min_runner.ll > manual_min_runner_driver.bc
% llvm-link bisect_manual_min.llvm.opt.bc manual_min_runner_driver.bc > bisect_manual_min_runner.opt.bc
The bitcode can be run by lli or compiled further. It doesn't seem to affect the miscompile.
Metadata
Assignees
Type
Projects
Status
Done