fix(mlir): 浮点常量位模式原样直通,消除 %e 截断精度
MLIR FloatAttr 语法支持十六进制位模式(Builtin Dialect: `hexadecimal-literal ':' float-type`,按底层二进制位解释),故 ConstFloat 产出的 `0x…` 无需转十进制。此前 _MlirFloatLiteral 把它转成 `%e`(默认 7 位有效数字): 3.141592653589793 → 3.141593e+00,静默截断,与 __values.vp 选位模式的初衷相悖。 - _MlirFloatLiteral:hex 且 mt 为 f32/f64 → 原样返回(无损); f16/f128 仍响亮报错(ConstFloat 只产出 64 位位模式,宽度与该两类型不符) - 删除因此失效的 _MlirParseHexU64 - README §2.3 常量表 / §5 打印阶段转换说明同步
This commit is contained in:
1 parent
751e7e7ef7
commit
f813c0543b
2 files changed
+17
-43
No files matched your search
+2
-2
@@ -158,7 +158,7 @@ MLIR 的操作数不能是字面量。**扫描阶段**(pass 1)遍历函数
|
||||
| 常量 | 物化 op |
|
||||
|------|---------|
|
||||
| `i32 42` | `%c0 = llvm.mlir.constant(42 : i32) : i32` |
|
||||
| `f64 0x40091EB851EB851F` | `%c0 = llvm.mlir.constant(3.140000e+00 : f64) : f64`(位模式 → 十进制科学计数法) |
|
||||
| `f64 0x40091EB851EB851F` | `%c0 = llvm.mlir.constant(0x40091EB851EB851F : f64) : f64`(位模式**原样直通**:MLIR FloatAttr 支持十六进制位模式,按底层二进制位解释,无精度损失) |
|
||||
| `null` / `zeroinitializer` | `%c0 = llvm.mlir.zero : !llvm.ptr`(或 `: i32` 等) |
|
||||
| `@f` / `@"sha1.x"` | `%c0 = llvm.mlir.addressof @f : !llvm.ptr` |
|
||||
|
||||
@@ -552,7 +552,7 @@ packed"的组合,无需(也无处)为其单独报错。登记表每槽 16
|
||||
| 5 | `IRBuilder.build_bitcast(val,to_ty)` | 返回的 `Value` 名字仍会出现在中间文本里,但打印时若两端都是指针则**整个指令消失**、名字被别名替换(`Value` 对象本身不变) |
|
||||
| 6 | `IRBuilder.build_phi` / `build_br` | builder 语义不变(仍写 phi 行);MLIR 打印时 phi 行消失、br 追加实参 |
|
||||
| 7 | `IRBuilder.build_alloca` | 打印时个数按常量 `1`(i32)物化;`build_alloca_aligned` 的 `, align N` 转写为 `{alignment = N : i64}` 属性(N 必须是 2 的幂常量,否则响亮报错) |
|
||||
| 8 | `const_int` / `ConstFloat` | `Name` 文本仍是 llvmlite 形态(十进制 / `0x` 位模式);**转换发生在打印阶段**(浮点位模式→十进制科学计数法) |
|
||||
| 8 | `const_int` / `ConstFloat` | `Name` 文本仍是 llvmlite 形态(十进制 / `0x` 位模式);**转换发生在打印阶段**(浮点 `0x` 位模式**原样直通**,MLIR 按底层位解释;f16/f128 位模式宽度不符 → 响亮报错) |
|
||||
| 9 | `create_global_string` | `Initializer` 仍是 `c"…\00"`;打印时转成 `"…"`(**去掉尾随 `\00`**,见 §5 待确认) |
|
||||
| 10 | `verify_function` / `verify_module` | 校验内部模型 + 中间文本(与 llvmlite 完全一致);**不**校验 MLIR 文本合法性(交给 mlir-opt) |
|
||||
| 11 | `PrintStructDefinition` | 输出空串(MLIR 无类型定义行),llvmlite 版输出 `%"name" = type {…}`;具名结构体只在**使用处**内联出现(§2.10) |
|
||||
|
||||
+15
-41
@@ -1371,49 +1371,23 @@ def _MlirCxResName(resname: str, suffix: str) -> str:
|
||||
return nm
|
||||
|
||||
|
||||
def _MlirParseHexU64(s: str) -> t.CUInt64T:
|
||||
"""解析 0x 十六进制字面量为 u64"""
|
||||
p: str = s
|
||||
if p[0] == '0' and (p[1] == 'x' or p[1] == 'X'):
|
||||
p = p + 2
|
||||
v: t.CUInt64T = 0
|
||||
g: int = 0
|
||||
while p[0] != '\0' and g < 32:
|
||||
ch: int = p[0]
|
||||
d: int = -1
|
||||
if ch >= '0' and ch <= '9':
|
||||
d = ch - 48
|
||||
elif ch >= 'a' and ch <= 'f':
|
||||
d = ch - 87
|
||||
elif ch >= 'A' and ch <= 'F':
|
||||
d = ch - 55
|
||||
else:
|
||||
break
|
||||
v = v * 16 + t.CUInt64T(d)
|
||||
p = p + 1
|
||||
g += 1
|
||||
return v
|
||||
|
||||
|
||||
def _MlirFloatLiteral(val: str, mt: str) -> str:
|
||||
"""浮点常量文本 → MLIR 十进制科学计数法文本(f16/f128 不支持)"""
|
||||
"""浮点常量文本 → MLIR 浮点字面量文本
|
||||
|
||||
MLIR 的浮点字面量支持两种形态(Builtin Dialect「FloatAttr」语法:
|
||||
`float-literal (':' float-type)?` | `hexadecimal-literal ':' float-type`):
|
||||
- 十进制浮点字面量(如 `3.14 : f64`);
|
||||
- **十六进制位模式**(如 `0x40091EB851EB851F : f64`,按底层二进制位解释)。
|
||||
|
||||
故 ConstFloat 给出的 `0x…` 位模式**原样直通**:位模式无精度损失。
|
||||
此前把它转成 `%e`(默认 7 位有效数字)会截断
|
||||
(3.141592653589793 → 3.141593e+00),与 __values.vp 选位模式的初衷相悖。
|
||||
f16/f128 仍响亮报错:ConstFloat 只产出 64 位位模式,宽度与这两种类型不符。
|
||||
"""
|
||||
if val[0] == '0' and (val[1] == 'x' or val[1] == 'X'):
|
||||
bits: t.CUInt64T = _MlirParseHexU64(val)
|
||||
buf: str = _MLIR_Pool.alloc(64)
|
||||
if buf is None:
|
||||
MlirFail("MLIR 渲染: 浮点常量缓冲分配失败")
|
||||
if mt[1] == '3' and mt[2] == '2':
|
||||
f32v: t.CFloat = 0.0
|
||||
c.DerefAs((rawptr[t.CUInt32T])(c.Addr(f32v)), t.CUInt32T(bits))
|
||||
dv32: t.CDouble = t.CDouble(f32v)
|
||||
viperlib.snprintf(buf, 64, "%e", dv32)
|
||||
return buf
|
||||
if mt[1] == '6' and mt[2] == '4':
|
||||
f64v: t.CDouble = 0.0
|
||||
c.DerefAs((rawptr[t.CUInt64T])(c.Addr(f64v)), bits)
|
||||
viperlib.snprintf(buf, 64, "%e", f64v)
|
||||
return buf
|
||||
MlirFail("MLIR 渲染: v1 不支持 f16/f128 十六进制浮点常量物化")
|
||||
if string.strcmp(mt, "f32") == 0 or string.strcmp(mt, "f64") == 0:
|
||||
return val
|
||||
MlirFail("MLIR 渲染: v1 不支持 f16/f128 十六进制浮点常量物化(ConstFloat 只产出 64 位位模式)")
|
||||
# 已是十进制文本:原样使用
|
||||
return val
|
||||
|
||||
|
||||
Reference in new issue
Block a user