Misoptimization of case with string compares
I have (simplified) code like this:
logic [2:0] counter; function void with_case(); string mystr; case (counter) 3'b000: mystr = "case-0"; 3'b001: mystr = "case-1"; 3'b010: mystr = "case-2"; 3'b100: mystr = "case-4"; 3'b101: mystr = "case-5"; `ifdef WITH_DEFAULT default: mystr = "bad-default"; `endif endcase $display("with_case: %d = %s", counter, mystr); return; endfunction always_ff @(posedge clk_i) begin counter <= counter + 1; if (counter == 3'b111) begin $finish; end end always_comb begin with_case(); end
When I compile without WITH_DEFAULT being set, everything works as expected, and I get output like this:
with_case: 0 = case-0 with_case: 1 = case-1 with_case: 2 = case-2 with_case: 3 = case-2 with_case: 4 = case-4 with_case: 5 = case-5 with_case: 6 = case-5 with_case: 7 = case-5 with_case: 0 = case-0But if I compile with WITH_DEFAULT set, I get this output; effectively, the default label is always taken.
with_case: 0 = case-default with_case: 1 = case-default with_case: 2 = case-default ...
The same behavior can be observed if I switch from case to if statements. I put together a full testcase at https://github.com/imphil/verilator-case, it can be run by typing make. The full code where we observed this behavior is at https://github.com/lowRISC/ibex/blob/2acb497d22a5da877a9c4350ef5693d0c767cc61/rtl/ibex_tracer.sv#L584
Looking at the generated C code, it looks like somehow the if/case statements get optimized out when compiling with default/else branches. I'd appreciate any pointers on how to debug this further.
#1 Updated by Wilson Snyder 2 months ago
- Subject changed from Misoptimization in if and case with default statement inside a function to Misoptimization of case with string compares
- Status changed from New to Resolved
- Assignee set to Wilson Snyder
Thanks for the good test case. What's going on is when the case statement is getting optimized it treated the different result strings as matching when they shouldn't.
Also added a boat-load of assertions to check for similar missing string cases, but nothing turned up in existing regressions.
Fixed in git towards eventual 4.020 release.
Also available in: Atom