Skip to content

Commit f0cd163

Browse files
author
dev-aditya-hub
committed
fix(testgen): separate cp_fpr_hazard generator from cp_gpr_hazard
cp_fpr_hazard was wired to the GPR generator, which only pinned integer registers — so FP instructions saw no real RAW/WAW/WAR dependency. Add a dedicated FP hazard generator that uses an fadd producer and pins fs1/fs2/ fs3/fd based on the consumer's required params.
1 parent 7bbc2d9 commit f0cd163

1 file changed

Lines changed: 79 additions & 1 deletion

File tree

  • generators/testgen/src/testgen/coverpoints

generators/testgen/src/testgen/coverpoints/hazards.py

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
from testgen.data.test_chunk import TestChunk
1313
from testgen.formatters import format_instruction
1414
from testgen.formatters.params import generate_random_params
15+
from testgen.formatters.registry import get_instr_type_config
1516

1617

17-
@add_coverpoint_generator("cp_gpr_hazard", "cp_fpr_hazard")
18+
@add_coverpoint_generator("cp_gpr_hazard")
1819
def make_cp_gpr_hazard(instr_name: str, instr_type: str, coverpoint: str, test_data: TestData) -> list[TestChunk]:
1920
"""Generate tests for register hazards (RAW, WAW, WAR)."""
2021
tc = test_data.begin_test_chunk()
@@ -85,3 +86,80 @@ def make_cp_gpr_hazard(instr_name: str, instr_type: str, coverpoint: str, test_d
8586

8687
tc.code = "\n".join(test_lines)
8788
return [test_data.end_test_chunk()]
89+
90+
91+
def _fp_producer_for(instr_name: str) -> tuple[str, str]:
92+
"""Pick an FP producer instruction whose precision matches the instruction under test."""
93+
if instr_name.endswith(".d"):
94+
return "fadd.d", "FR"
95+
if instr_name.endswith(".h"):
96+
return "fadd.h", "FR"
97+
if instr_name.endswith(".q"):
98+
return "fadd.q", "FR"
99+
return "fadd.s", "FR"
100+
101+
102+
@add_coverpoint_generator("cp_fpr_hazard")
103+
def make_cp_fpr_hazard(instr_name: str, instr_type: str, coverpoint: str, test_data: TestData) -> list[TestChunk]:
104+
"""Generate tests for FP register hazards (RAW, WAW, WAR)."""
105+
tc = test_data.begin_test_chunk()
106+
parts = coverpoint.split("_")
107+
haz_class = parts[-1] if len(parts) > 3 and parts[-1] in ["r", "w", "rw"] else "rw"
108+
109+
test_lines: list[str] = []
110+
hazard_types: list[str] = ["nohaz"]
111+
if "r" in haz_class:
112+
hazard_types.append("raw")
113+
if "w" in haz_class:
114+
hazard_types.extend(["waw", "war"])
115+
116+
producer_instr, producer_type = _fp_producer_for(instr_name)
117+
consumer_required = get_instr_type_config(instr_type).required_params or set()
118+
consumer_fp_srcs = [f for f in ("fs1", "fs2", "fs3") if f in consumer_required]
119+
consumer_has_fd = "fd" in consumer_required
120+
121+
for haz_type in hazard_types:
122+
for i in range(2):
123+
params_a = generate_random_params(test_data, producer_type)
124+
assert params_a.fs1 is not None and params_a.fs2 is not None and params_a.fd is not None
125+
126+
if haz_type == "raw":
127+
if consumer_fp_srcs:
128+
src_field = consumer_fp_srcs[i % len(consumer_fp_srcs)]
129+
params_b = generate_random_params(test_data, instr_type, **{src_field: params_a.fd})
130+
else:
131+
# Consumer reads no FP source register — skip this iteration's hazard
132+
# rather than emit a no-op test that pretends to cover RAW.
133+
continue
134+
elif haz_type == "waw":
135+
if not consumer_has_fd:
136+
continue
137+
params_b = generate_random_params(test_data, instr_type, fd=params_a.fd)
138+
elif haz_type == "war":
139+
if not consumer_has_fd:
140+
continue
141+
src_of_a = params_a.fs1 if i % 2 == 0 else params_a.fs2
142+
params_b = generate_random_params(test_data, instr_type, fd=src_of_a)
143+
elif haz_type == "nohaz":
144+
params_b = generate_random_params(test_data, instr_type)
145+
else:
146+
raise ValueError(f"Unknown hazard type: {haz_type}")
147+
148+
test_lines.append(f"\n# Testcase cp_fpr_hazard {haz_type} test")
149+
setup1, test1, check1 = format_instruction(producer_instr, producer_type, test_data, params_a)
150+
setup2, test2, check2 = format_instruction(instr_name, instr_type, test_data, params_b)
151+
152+
test_lines.extend([setup1, setup2])
153+
test_lines.extend([test1, test2])
154+
if haz_type == "waw":
155+
test_lines.append(check2)
156+
else:
157+
test_lines.extend([check1, check2])
158+
159+
test_data.float_regs.return_registers(params_a.used_float_regs)
160+
test_data.float_regs.return_registers(params_b.used_float_regs)
161+
test_data.int_regs.return_registers(params_a.used_int_regs)
162+
test_data.int_regs.return_registers(params_b.used_int_regs)
163+
164+
tc.code = "\n".join(test_lines)
165+
return [test_data.end_test_chunk()]

0 commit comments

Comments
 (0)