Description
Describe the bug
If you switch the multiprocess fuzzer to use p
as the gensym prefix instead of x
you observe a lot of problems quickly.
With this .x:
fn main(p0: u29, p1: u33, p2: u44, p3: u32, p4: u41, p5: u33, p6: u43) -> (u29, u45, u45, u29, u15, u32, u45, u33) {
{
let p7: u15 = u15:0x2000;
let p8: u44 = !p2;
let p9: u33 = -p5;
let p10: u29 = ctz(p0);
let p11: u44 = -p8;
let p12: u29 = bit_slice_update(p0, p8, p7);
let p13: u29 = signex(p1, p10);
let p14: u45 = u45:0x682_1b1c_101d;
let p15: u32 = p3[:];
let p16: u45 = p14[0+:u45];
(p10, p14, p14, p12, p7, p15, p16, p9)
}
}
We get the following opt IR:
package sample
file_number 0 "/tmp/temp_directory_8R9TAz/sample.x"
top fn __sample__main(p0: bits[29] id=1, p1: bits[33] id=2, p2: bits[44] id=3, p3: bits[32] id=4, p4: bits[41] id=5, p5: bits[33] id=6, p6: bits[43] id=7) -> (bits[29], bits[45], bits[45], bits[29], bits[15], bits[32], bits[45], bits[33]) {
one_hot.11: bits[30] = one_hot(p0, lsb_prio=true, id=11, pos=[(0,5,26)])
literal.29: bits[24] = literal(value=0, id=29, pos=[(0,5,26)])
encode.12: bits[5] = encode(one_hot.11, id=12)
p8: bits[44] = not(p2, id=9, pos=[(0,3,22)])
p7: bits[15] = literal(value=8192, id=8, pos=[(0,2,22)])
p10: bits[29] = concat(literal.29, encode.12, id=30, pos=[(0,5,26)])
p12: bits[29] = bit_slice_update(p0, p8, p7, id=15, pos=[(0,7,39)])
p14: bits[45] = literal(value=7155870339101, id=17, pos=[(0,9,23)])
p9: bits[33] = neg(p5, id=10, pos=[(0,4,22)])
ret tuple.21: (bits[29], bits[45], bits[45], bits[29], bits[15], bits[32], bits[45], bits[33]) = tuple(p10, p14, p14, p12, p7, p3, p14, p9, id=21, pos=[(0,12,8)])
}
and then we get the following in the .v:
// ===== Pipe stage 5:
wire [44:0] p5_p14_comb;
wire [44:0] p5__1_comb;
wire [14:0] p5__1_comb;
wire [44:0] p5__2_comb;
wire [272:0] p5_tuple_101_comb;
You can see there's a conflicting declaration for the width of p5__1_comb
, pretty sure this is due to some mix of non-hygeinic gensym and perhaps some attempt to preserve names across optimizations -- first step is likely to add a verifier/validator that we don't get any collisions in module wire namespace to crash on these instead of passing to downstream tools that are happy to do "something".
To Reproduce
diff --git a/xls/fuzzer/ast_generator.cc b/xls/fuzzer/ast_generator.cc
index cc784ee4b..203a9e3b7 100644
--- a/xls/fuzzer/ast_generator.cc
+++ b/xls/fuzzer/ast_generator.cc
@@ -196,7 +196,7 @@ AstGenerator::Unzip(absl::Span<const TypedExpr> typed_exprs) {
}
std::string AstGenerator::GenSym() {
- std::string result = absl::StrCat("x", next_name_index_++);
+ std::string result = absl::StrCat("p", next_name_index_++);
VLOG(10) << "generated fresh symbol: " << result << " @ "
<< GetSymbolizedStackTraceAsString();
return result;
at git ref d8b1db0
PiperOrigin-RevId: 759807560
bazel run -c opt //xls/fuzzer:run_fuzz_multiprocess -- --crash_path=/tmp/crashers-$(date +'%Y-%m-%d') --seed=0 --duration=12h --codegen=true --simulate=true --use_system_verilog=false
Environment (this can be helpful for troubleshooting):
- OS: Ubuntu 24.04