Skip to content

[LSU] Redirect-killed Load Queue entries remain visible and train the no-speculation predictor #72

Description

@YzhDDDing

Summary

A load younger than a taken branch can remain valid in the Load Queue after branch-execute change-flow redirects it away. Although that load never retires, a later older-store address resolution still sees it as a RAW dependency. The false speculation-failure event propagates into ct_lsu_spec_fail_predict and changes the no-speculation predictor state.

I reproduced this on the current OpenC910 main revision b91c90914c19f114d35c8f6b73408eb241ed847c. The OpenC910 RTL was not modified. The architectural self-check passes, as expected for a microarchitectural recovery-state error.

Reproducer

The exact assembly and deterministic VCD checker are available here:

https://gist.github.com/YzhDDDing/cbdf92d06369fc40185b1867f0bf8395

The core sequence enables no-speculation-failure handling, delays an older store address, resolves a taken forward branch, and places three same-address loads on its fall-through path:

  csrr  x31, mhint
  li    x30, 0x40000
  or    x31, x31, x30
  csrw  mhint, x31
  BHT_INV

  divu  x24, x23, x15
  sub   x24, x24, x24
  add   x12, x9, x24
  sd    x10, 0(x12)          # older store, address resolves late

  # dependency-spacing instructions are in the full PoC
  beq   x5, x0, after_wrongpath
  ld    x13, 0(x9)           # wrong path
  ld    x18, 0(x9)           # wrong path
  ld    x19, 0(x9)           # wrong path
after_wrongpath:
  sync
  ld    x16, 0(x9)           # correct-path probe

Build lsu_wrongpath_raw.S with smart_run/tests/lib/Makefile, using CPU_ARCH_FLAG_0=c910 CASENAME=lsu_wrongpath_raw FILE=lsu_wrongpath_raw, then run the smart-run testbench with VCD dumping. For the hierarchy used in my replay:

python3 monitor_lsu_wrongpath_raw.py \
  test.vcd lsu_wrongpath_raw.obj run_case.report result.json

The checker fails closed if any required signal is missing.

Expected behavior

Once branch recovery kills the fall-through loads, their LQ entries must no longer participate in load/store dependence detection. They must not raise a RAW speculation failure or train future load scheduling.

Observed behavior

The replay produced this ordering (VCD time units are the checker's ps100 units):

Time Event
10493 iu_rtu_pipe2_bht_mispred=1 and iu_ifu_chgflw_vld=1
10509 lq_entry_raw_spec_fail=1, lq_st_dc_spec_fail=1, st_dc_spec_fail=1
10511 st_da_sf_no_spec_miss=1
10517 sf_start_success=1
10519 sf_spec_mark=1
10669 the correct-path probe load retires

None of the wrong-path load PCs retires. The monitor reports predicate=true, no missing signal groups, and wrongpath_retired=[].

RTL analysis

ct_lsu_lq_entry.v clears lq_entry_vld only on commit/pop or rtu_yy_xx_flush; branch execute change-flow is not represented at this validity boundary. The same still-valid entry participates in the store-vs-load RAW comparison.

The result is reduced into lq_st_dc_spec_fail, propagated through store DC/DA, and accepted by ct_lsu_spec_fail_predict.

Suggested fix direction

Make redirect recovery remove or mask younger killed LQ entries before they can contribute to RAW/RAR checks. This needs to be age-qualified; clearing every LQ entry on any frontend redirect could incorrectly discard older correct-path loads. A recovery generation tag, an IID-qualified kill, or a validity mask at the dependence comparator would all preserve that invariant.

It would also be useful to add an assertion that a non-retiring redirect-killed load can never cause lq_st_dc_spec_fail or sf_spec_mark.

Impact

The demonstrated effect is persistent corruption of memory-dependence prediction metadata and unnecessary recovery/no-speculation behavior. This PoC does not demonstrate an architectural result mismatch.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions