Skip to content

topic28 docs - #26

Open
qingtargaryen wants to merge 2 commits into
ScratchV-Compiler:mainfrom
qingtargaryen:topic28/div
Open

topic28 docs#26
qingtargaryen wants to merge 2 commits into
ScratchV-Compiler:mainfrom
qingtargaryen:topic28/div

Conversation

@qingtargaryen

Copy link
Copy Markdown

No description provided.


| 操作 | 说明 | 本阶段 |
|------|------|--------|
| **div (浮点除)** | f32/f64 除法 | ✅ 实现 |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

浮点除法的精度如何保证


---

## 4. 测试策略

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ut中是否有简单的性能监控


### 4.1 测试矩阵

| 测试用例 | 输入 | 预期 | 验证点 |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

用软件仿真一下?


### 4.1 测试矩阵

| 测试用例 | 输入 | 预期 | 验证点 |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

浮点运算中的round是round to nearest还是round to even


### 1.1 目标

在 `ExtendedInstructionSelector` 中完善 **div 及相关运算** 的指令选择,支持所有数据类型的除法、取余运算,做到类型驱动的精确指令选择。

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以实现算子注册的功能


### 1.1 目标

在 `ExtendedInstructionSelector` 中完善 **div 及相关运算** 的指令选择,支持所有数据类型的除法、取余运算,做到类型驱动的精确指令选择。

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当一个算子可以用指令a实现,也可以用指令b实现,如何进行选择。这样的选择算法如何预留接口

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

🤖 AI Code Review

共审查 10 个变更文件
⚠️ 另有 3 个文件超过上限(最多 10 个)未审查

📁 docs/mydocs/28-扩展指令选择-开发文档.md

🔴 遗漏实施步骤 — 实施顺序(Step 1-6)未包含 constant_folding.pydsl_parser.py 的修改,但修改清单中明确列出了这两项。建议补充步骤或说明它们已在其他步骤中隐含完成(例如 Step 6 之后的独立任务)。

🟡 描述矛盾 — 2.1 节说 is_arith() 增加 SQRT, ABS, MIN, MAX, NEG,但 OpCode 枚举中并未新增 NEGNEG 可能为已有值)。建议确认 NEG 是否已存在,或补充说明 is_arith() 的修改范围。

🟡 依赖未声明_select_sqrt 中使用了 MachineOperand.reg("a0"),但未说明 MachineOperand 类的导入或定义方式(可能来自 machine_types.py)。建议添加引用或注释。

🟡 验证代码不完整 — 手动测试示例缺少 DataType 导入(from scratchv.ir.types import DataType 已写,但未导入 IRBuilder 等)。建议补充 from scratchv.ir.builder import IRBuilder 等完整示例。

💭 no-op 实现风险transpose/concat 作为 no-op 仅复制指针,但若后续有数据布局转换(如行主序 vs 列主序),可能产生错误。建议在文档中标注此假设或添加断言。

💭 use_hardware_sqrt 未定义 — 文档假设 self.use_hardware_sqrt 存在,但未说明该属性如何初始化(例如通过配置或后端标志)。建议在注意点中补充。


📁 docs/mydocs/28-扩展指令选择-测试输入输出.md

🔴 不正确的寄存器表示neg_i32 输出中 sub %y 0 %x0 不是合法寄存器,应改为 sub %y %zero %xsub %y x0 %x

🟡 max_i32 使用伪指令 MAX 但未定义 — 输出 max %y %a %b 是伪指令,而其他整数操作(如 min_i32)展开了分支无关序列。建议统一为序列,或显式说明 MAX 是伪指令并给出其展开。

🟡 test_mod 映射到 rem 但语义不同mod 通常返回非负余数,而 rem 是截断余数,对负数结果不同。若设计如此,请在文档中注明原因或别名关系。

💭 neg_i32 的 dispatch 路径写 super()._select_neg → SUB x0,rs — 路径中 SUB x0,rs 与输出 sub %y 0 %x 不一致(操作数顺序、零寄存器表示)。建议统一写法。

💭 sqrt 测试中 lib call 与 hardware 版本共存 — 缺少区分条件(如 CPU 特性)。建议为每个测试添加注释说明适用场景,或以配置项命名。

💭 .label 指令格式不标准 — 例如 .label # main 可能混淆,可考虑直接用 # main:main: 表示标签。


📁 docs/mydocs/28-扩展指令选择-设计文档.md

🔴 Bug: 整数 min 实现有溢出风险
第5.1节 slt/sub/and/add 方案中 sub diff, b, a 可能溢出(如 a = INT_MIN, b = INT_MAX),导致 diff 截断为错误值,最终 dst 不正确。建议改用无溢出的 branchless 比较选择方案,例如 slt + 掩码 + orxor 组合。

🟡 Bug: i64 abs 的 srai 位数错误
第6.1节 srai tmp, x, 31 仅适用于 i32。对于 i64 应为 srai 63。需明确或改用 sizeof 参数化。

🟡 矛盾: 出现未定义的 _select_neg
第2.5节提到 ExtendedInstructionSelector 重写 _select_neg,但范围表(1.2)和 OpCode 扩展中均未列出 neg 操作。如果 neg 是独立操作,应补充定义;若仅是 abs 的中间步骤,则不应以独立方法出现。

💭 整数 min 方案未区分有符号/无符号
文档中 slt 是有符号比较,但 RISC-V 的 sltsltu 不同。若后续支持无符号整数,应注明。

💭 i64 除法依赖 M 扩展,但 RV64 下 DIV 为 64 位
第2.2 矩阵中 i64 使用 DIV 正确,但建议在文档中注明 march 要求(如 rv64im),避免混淆。

💭 库调用 sqrt 未考虑 ABI 调用约定
第4.2 节 mv a0, src; call sqrtf; mv dst, a0 缺少保存/恢复调用者保存寄存器(a0-a7/t0-t6),但作为设计文档可简化,不过建议加注脚说明。

💭 2.5 节 _select_fdiv_d() 未在流程图中出现
该函数名在类层次中出现,但数据流图(2.1)中 f64 直接映射到 FDIV_D,未调用 _select_fdiv_d。建议统一或用注释说明内部委托。

💭 OpCode 扩展列表未包含 TRANSPOSE/CONCAT
尽管这些 opcode 可能已存在,但文档1.2范围表包含了它们,建议在 OpCode 扩展一节也列出,保持完整性。


📁 docs/topics/archive/backend_inst_select_ext.md

🟡 文档准确性:Integer abs 的 srai 31 可能不适用于 64-bit 架构
abs 节中 Integer abs 的描述为 srai 31 + xor + sub,但若目标架构为 RV64,srai 31 仅提取符号位到 32 位,会导致 64 位整数的绝对值计算错误。建议明确说明该序列针对 32-bit 整数,或修正为 srai 63(若支持 64-bit)。

💭 术语准确性:transpose / concat 中的 “no-op copies” 易误解
描述为 “no-op copies (mv)”,但 mv 指令本身并非 no-op(它产生寄存器移动)。建议改为 “zero-cost register copies” 或 “register copies using mv”,避免与真正的 no-op(如 nop)混淆。


📁 scratchv/backend/asm_emit.py

🟡 潜在不完整 — 仅添加了 fabs.sfneg.s 的助记符映射,但未确认指令解码器(decode 模块)和执行器(execute 模块)是否已同步支持这些新指令。缺失对应逻辑会导致运行时错误或未定义行为。


📁 scratchv/backend/inst_select_ext.py

🔴 Bug: 丢失连接操作的其余输入_select_concat 只取第一个操作数(self._op(instr, 0)),但 concat 通常需要合并多个缓冲区,仅复制第一个指针会导致数据丢失。建议:要么传递所有操作数给运行时,要么在 IR 层面处理多个输入。

🟡 潜在类型误判_has_f32_operand 同时检查 dest 和所有 operands,可能导致混合类型指令(如 dest 为 float32 但 operands 为 int)被错误地送入浮点分支。建议:只检查 operands 或要求所有操作数类型一致。

🟡 “no-op” 描述不准确_select_transpose_select_concat 注释称“no-op”,但实际发射了 MV 指令。若运行时完全接管,可考虑不发射指令(直接返回),或修正注释说明“仅复制指针”。

💭 确认 _select_idiv 存在_select_divelif has_int_operand 分支调用了 _select_idiv,需确保该方法已在类中定义(或从基类继承),否则会引发 AttributeError

💭 浮点 NaN 行为未说明_select_min_select_max 的浮点分支使用 fmin.s/fmax.s,其 NaN 传播语义与整数分支不同,建议在注释中简要说明,避免误解。


📁 scratchv/backend/instruction_select.py

🔴 Bug: _select_concat只取了第一个操作数,忽略其余输入 — 拼接操作通常需要多个源张量,此处只调用self._op(instr, 0),丢失了其他操作数,严重错误。
建议:遍历所有操作数并发射多个MV或使用MultiMV/Concat指令,确保所有输入数据被合并。

🔴 Bug: _select_transpose仅做MV,可能丢失转置语义 — 转置需要改变数据排列顺序,除非底层布局描述符已隐含处理,否则简单拷贝不会实现转置。
建议:确认MachineOp是否有专门的转置操作,或验证布局描述符确实能处理此情况。若不能,应实现显式数据重排。

🟡 重复代码模式_select_transpose_select_concat_select_reshape逻辑完全一致,仅注释不同。
建议:考虑提取公共方法,如_emit_mv_with_comment(instr, comment),以减少重复。

💭 注释可能误导 — "no-op copy" 在 transpose 和 concat 中通常不是 no-op,除非确实由上游处理。
建议:更新注释说明实际依赖的布局或运行时机制,或明确标记为临时占位。


📁 scratchv/backend/machine_types.py

🟡 Suggestion: Missing handling in switch/match — New enum values FABS_S and FNEG_S are added. Ensure all places that pattern-match on MachineOp (e.g., instruction decoding, execution, disassembly) have corresponding branches to handle them. Otherwise, the new operations may silently fall through or cause runtime errors.


📁 scratchv/frontend/dsl_parser.py

🟡 语义模糊remmod 在数学上通常不同(如负数处理),建议确认 builder 的实现是否区分二者,若相同则删除其中一个避免混淆。

🟡 缺少输入验证 — 若 resolved 长度不足或含非数字,lambda 会抛出未捕获异常,但现有模式已有此问题,建议在 _dispatch_op 统一校验。

💭 注释语言不一致 — 使用中文“新增”,建议统一为英文如 # new operation 或直接移除注释。


📁 scratchv/ir/builder.py

🔴 类型硬编码idivrem 固定 dtype=DataType.INT32,但输入 lhs/rhs 可能是 INT64 或其他整数类型,导致截断或类型不匹配。建议使用输入的类型或做类型提升。

🔴 mod 语义错误 — 文档说“取余别名,同 rem”,但 rem 是截断向零余数,mod 通常指 Euclidean 模(结果非负)。直接别名会导致错误数学结果。建议:要么移除 mod,要么实现正确的 Euclidean 模。

🔴 concat 参数不足 — 方法签名只接受一个 val,但拼接操作通常需要至少两个值。可能是设计缺陷(如自身拼接?),但不符合直觉。建议:改为接受多个参数或序列。

🟡 min/max 类型假设 — 使用 a.dtype 作为结果类型,但 b 可能为不同 dtype(如 FLOAT32 vs INT32),未做类型提升检查。建议:考虑类型提升,或要求输入类型一致。

🟡 neg 修复不一致neg 改为指定 dtype=val.dtype,但 explog 等已有方法仍使用无参数的 make_value(),导致类型可能丢失。建议:统一修复所有一元操作。

💭 缺少输入校验 — 未检查 idiv/remrhs 是否为零,可能导致运行时错误。建议:在 builder 层或指令定义层添加校验。

💭 transpose 文档笼统 — “数据布局操作”未说明具体含义(如矩阵转置?),建议明确语义。



⚠️ 未审查的文件

  • scratchv/ir/types.py
  • scratchv/optimizer/constant_folding.py
  • tests/test_inst_select_ext.py

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants