docs: fix vmi-isa docs - #1449
Conversation
| # 1. Load / Store | ||
|
|
||
| > **Category:** A (+B on `unpack`). **Mask:** load none (A5 loads are unpredicated), store `Pg`. | ||
| > **Category:** A (+B on `dintlv`/`intlv`). **Mask:** load none (A5 loads are unpredicated), store `Pg`. |
There was a problem hiding this comment.
#1401
The "unpack" has been discontinued and has been replaced by "dintlv" and "intlv".
| | Attribute | Values | Default | Description | | ||
| |---|---|---|---| | ||
| | `pmode` | `"zero"`, `"merge"` | `"zero"` | Inactive-lane behavior: `"zero"` (default) skips the write on inactive blocks; `"merge"` retains prior UB contents on inactive blocks | | ||
| | `pmode` | `"zero"` | `"zero"` | Inactive-lane behavior: `"zero"` skips the write on inactive blocks | |
There was a problem hiding this comment.
// VMI.cpp pmode "merge" is not supported for stores
LogicalResult VMIVsstbOp::verify() {
// ......
if (auto pmode = getPmode(); pmode && *pmode != "zero") {
return emitOpError("pmode \"merge\" is not supported for stores: the "
"legacy store lowering is mask-governed only and "
"cannot retain prior destination contents on inactive "
"blocks; omit pmode (defaults to \"zero\")");
}
// ......
}| | Operand | Type | Description | | ||
| |---|---|---| | ||
| | `base` | integer or float scalar | Starting value | | ||
| | `base` | scalar (`i8`/`i16`/`i32`, `f16`/`f32`) | Starting value | |
There was a problem hiding this comment.
// VMI.cpp i64 f64 is not supported
LogicalResult VMIVciOp::verify() {
auto resultType = cast<VMIVRegType>(getResult().getType());
Type elementType = resultType.getElementType();
if (!isVMIIotaElementType(elementType)) {
return emitOpError("requires result element type to be integer 8/16/32 "
"or f16/f32");
}
// ......
}| | `pmode` | `"zero"`, `"merge"` | `"zero"` | Inactive-result behavior | | ||
|
|
||
| - **datatypes:** `i8`–`i32`, `f16`, `f32` | ||
| - **datatypes:** full reduce — `i32`, `f16`/`f32`; grouped reduce — `i8`/`i16`/`i32`, `f16`/`f32` |
There was a problem hiding this comment.
LogicalResult VMIReduceAddIOp::verify() {
// ......
auto sourceIntegerType = dyn_cast<IntegerType>(sourceType.getElementType());
if (!sourceIntegerType || sourceIntegerType.getWidth() != mlir::pto::kValue32) {
return emitOpError("requires 32-bit integer source element type");
}
// ......
}Signed-off-by: wangchen <wangchen965@huawei.com>
| - **results:** Same as `vcadd`. | ||
| - **attributes:** `group`, `pmode` (same as `vcadd`, no `reassoc`). | ||
| - **datatypes:** `i16`–`i32`, `f16`, `f32` | ||
| - **datatypes:** `i8`/`i16`/`i32`, `f16`/`f32`. |
There was a problem hiding this comment.
template <typename OpTy> LogicalResult verifyReduceMinMaxIOp(OpTy op) {
// ......
auto sourceIntegerType = dyn_cast<IntegerType>(sourceType.getElementType());
if (!sourceIntegerType ||
!isVMIAnyI8I16I32Type(sourceType.getElementType())) {
return op.emitOpError(
"requires 8-bit, 16-bit, or 32-bit integer source element type");
}
// ......
}| 3. **FpToSi** — `fp → signed int`. Supported pairs follow the contract | ||
| table `lookupVMIFpToSiContract`: `f32→s32`, `f16→s16`, `f32→s16`, | ||
| `f16→s8`, `f16→s32` (nosat), `bf16→s32`. | ||
| table `lookupVMIFpToSiContract`: `f32→si32`, `f16→si16`, `f32→si16`, |
There was a problem hiding this comment.
s32 and si32 are the same, but si32 is more standardized.
| table `lookupVMIFpToUIContract`: currently `f16→u8`. | ||
|
|
||
| 5. **SiToFp** — `int → fp` (e.g. `i32 → f32`, `i8 → f16`). | ||
| 5. **SiToFp** — `signed int → fp` (e.g. `si32 → f32`, `si8 → f16`). |
There was a problem hiding this comment.
LogicalResult VMICvtOp::verify() {
// ...
else if (srcInt && dstFp) {
if (!isVMISignedIntegerType(srcElem)) {
return emitOpError(
"int-to-fp conversion requires explicitly signed integer source "
"element type");
}
dir = CvtDirection::SiToFp;
// .....| |---|---|---|---| | ||
| | `rounding` | `"R"` (nearest-even), `"A"` (away-from-zero), `"H"` (half-up), `"Z"` (toward-zero); for the `bf16x2→f4x2` contract pair the allowed set is `"R"`,`"A"`,`"F"` (floor), `"C"` (ceil), `"Z"` (toward-zero) — `"H"` is **rejected** | fp narrowing | Rounding mode | | ||
| | `saturate` | `"SAT"`, `"NOSAT"` | required for fp-narrow / int-narrow; for fp→si / fp→ui the requirement follows the vcvt contract's `requiresSat` (e.g. `f16→s8` required, `f16→s32` **forbidden** — no overflow possible; same-width `bf16→f16` required, same-width `f16→bf16` **forbidden**); the `bf16x2→f4x2` narrow has `requiresSat=false` — any `saturate` is **forbidden** | `SAT` clamps to ±max of the destination type; `NOSAT` performs a direct bit truncation of the result representation. | | ||
| | `saturate` | `"SAT"`, `"NOSAT"` | required for fp-narrow / int-narrow; for fp→si / fp→ui the requirement follows the vcvt contract's `requiresSat` (e.g. `f16→si8` required, `f16→si32` **forbidden** — no overflow possible; same-width `bf16→f16` required, same-width `f16→bf16` **forbidden**); the `bf16x2→f4x2` narrow has `requiresSat=false` — any `saturate` is **forbidden**; `si32→si8` int-narrow accepts only `"NOSAT"` | `SAT` clamps to ±max of the destination type; `NOSAT` performs a direct bit truncation of the result representation. | |
There was a problem hiding this comment.
LogicalResult VMICvtOp::verify() {
// ......
// si32 -> si8 IntNarrow has no native hardware form. Lowering aliases
// it through ui32 -> ui8 (bit-pattern equal ONLY under NOSAT). Reject
// SAT here because ui32 -> ui8 SAT clamps to [0, 255], which does NOT
// match the expected si32 -> si8 SAT clamp to [-128, 127].
if (dir == CvtDirection::IntNarrow && satVal == "SAT" &&
srcBits == 32 && dstBits == 8 &&
isa<IntegerType>(srcElem) &&
cast<IntegerType>(srcElem).isSigned() &&
isa<IntegerType>(dstElem) &&
cast<IntegerType>(dstElem).isSigned()) {
return emitOpError("si32 -> si8 int-narrow does not support "
"saturate=\"SAT\" (no native hardware form; "
"only saturate=\"NOSAT\" is allowed)");
// ......
}| |---|---|---| | ||
| | `src` | `!pto.ptr<T, ub>` | UB base pointer | | ||
| | `offsets` | `!pto.vmi.vreg<L×i32>` | Per-lane element offset | | ||
| | `offsets` | `!pto.vmi.vreg<L×i32>` or `!pto.vmi.vreg<L×ui16>` | Per-lane element offset | |
There was a problem hiding this comment.
LogicalResult VMIVgatherOp::verify() {
// ......
auto indexElementType =
dyn_cast<IntegerType>(offsetsType.getElementType());
if (!indexElementType || indexElementType.isSigned() ||
(indexElementType.getWidth() != mlir::pto::kValue32 && indexElementType.getWidth() != 16)) {
return emitOpError(
"requires signless or unsigned 16-bit or 32-bit integer offsets");
}
// ......
}| |---|---|---| | ||
| | `src` | `!pto.ptr<T, ub>` | UB base pointer | | ||
| | `offsets` | `!pto.vmi.vreg<L×i32>` | Per-lane element offset | | ||
| | `offsets` | `!pto.vmi.vreg<L×i32>` or `!pto.vmi.vreg<L×ui16>` | Per-lane element offset | |
There was a problem hiding this comment.
LogicalResult VMIVgatherOp::verify() {
// ......
auto indexElementType =
dyn_cast<IntegerType>(offsetsType.getElementType());
if (!indexElementType || indexElementType.isSigned() ||
(indexElementType.getWidth() != mlir::pto::kValue32 && indexElementType.getWidth() != 16)) {
return emitOpError(
"requires signless or unsigned 16-bit or 32-bit integer offsets");
}
// ......
}| | `value` | `!pto.vmi.vreg<L×T>` | Values to scatter | | ||
| | `dest` | `!pto.ptr<T, ub>` | UB destination base pointer | | ||
| | `offsets` | `!pto.vmi.vreg<L×i32>` | Per-lane element offset | | ||
| | `offsets` | `!pto.vmi.vreg<L×i32>` or `!pto.vmi.vreg<L×ui16>` | Per-lane element offset | |
There was a problem hiding this comment.
LogicalResult VMIVgatherbOp::verify() {
// ......
auto indexElementType =
dyn_cast<IntegerType>(offsetsType.getElementType());
if (!indexElementType || indexElementType.isSigned() ||
(indexElementType.getWidth() != mlir::pto::kValue32 && indexElementType.getWidth() != 16)) {
return emitOpError(
"requires signless or unsigned 16-bit or 32-bit integer offsets");
}
// ......
}| - **datatypes:** `i8`/`i16`/`i32`, `f16`, `f32`; the result element type also | ||
| fixes `L` (`i32`/`f32` -> 64, `i16`/`f16` -> 128, `i8` -> 256). | ||
| - **datatypes:** `i8`/`i16`/`i32`, `f16`, `f32`; the result element type | ||
| does not constrain `L` — `1, 2, 4, 8, 64, 128, 256` lane counts |
There was a problem hiding this comment.
The original statement is incorrect. Here are examples of the opposite situation
| File(test/lit/vmi_new/) | vci | Violation of binding |
|---|---|---|
| vmi_to_vpto_iota_group2.pto:18 | : i32 -> vreg<128xi32> | i32→64 |
| vmi_to_vpto_iota.pto | : i32 -> vreg<128xi32, contiguous> | i32→64 |
| vmi_to_vpto_iota_group_deint.pto | : i32 -> vreg<128xsi32, deinterleaved=2> | i32→64 |
| vmi_to_vpto_iota_group_logical_tail.pto | vreg<32xi32>、vreg<96xi32> | i32→64 |
| vmi_to_vpto_iota_group_deint_assign.pto:24 | : f32 -> vreg<128xf32> | f32→64 |
| vmi_layout_assignment_iota_remat.pto:20 | : f32 -> vreg<128xf32> | f32→64 |
fix vmi-isa docs