{"entries":[{"file_sha256":"bfc1e646e91fe0ba6d7d16e43994100b05c3b8ff79c2e07288e8955c43d9d79d","kind":"documentation_input","lines":"254-258","path":"docs/spec-compiler-part-2-scf.md","roles":["applicability","context","input_construction"],"text":"LLVM leading- and trailing-zero count intrinsics with\n`is_zero_poison = false` normalize mechanically to `math.ctlz` and\n`math.cttz`. The poison-flagged forms retain their LLVM spelling and project\nthat flag through the registered typed semantic case; the standard Math ops\ncannot carry the poison-on-zero contract.","why":"Governing context and sampled obligation: zero-count intrinsics with is_zero_poison = false normalize to math.ctlz/math.cttz, while the poison-flagged forms retain their LLVM spelling. Selects both the applicable inputs (llvm.intr.ctlz/cttz with either flag value) and the terminology of the output condition."},{"file_sha256":"bfc1e646e91fe0ba6d7d16e43994100b05c3b8ff79c2e07288e8955c43d9d79d","kind":"documentation_input","lines":"141-146","path":"docs/spec-compiler-part-2-scf.md","roles":["input_construction","input_well_formedness"],"text":"Mechanical raising uses the standard `arith` or `math` operation schema when\nit exactly represents an LLVM computation under the complete operation type,\noperation attributes, overflow and exact flags, fast-math policy, rounding\nmode, enclosing function floating-point environment, and DataLayout. An\napparent LLVM alias does not normalize merely because it has a familiar\nopcode. Exact normalization gives Canonical Dataflow one operation-schema","why":"Linked input passage: a standard arith/math spelling applies only under the complete operation type, attributes, and flags, so sampled operand/result types and the intrinsic's attribute must be exact and complete."},{"file_sha256":"bfc1e646e91fe0ba6d7d16e43994100b05c3b8ff79c2e07288e8955c43d9d79d","kind":"documentation_input","lines":"150-154","path":"docs/spec-compiler-part-2-scf.md","roles":["input_construction"],"text":"An LLVM-dialect compute intrinsic may remain only when no exact standard MLIR\noperation represents it and it later satisfies the canonical actor contract.\nTarget-specific intrinsics should be normalized to target-neutral scalar or\nvector operations when such a representation exists. Otherwise, preserving\nthe registered LLVM operation is preferable to weakening its semantics.","why":"Linked input passage: registered LLVM operations are preserved rather than weakened when no exact standard operation exists; motivates sampling the poison-flagged intrinsic form."},{"file_sha256":"bfc1e646e91fe0ba6d7d16e43994100b05c3b8ff79c2e07288e8955c43d9d79d","kind":"documentation_input","lines":"166-173","path":"docs/spec-compiler-part-2-scf.md","roles":["input_construction","input_well_formedness"],"text":"The LLVM dialect `passthrough` function attribute is an importer-owned lossless\ncontainer, not a floating-point-environment authority. Mechanical raising uses\none closed classifier owned by the exact-spelling projection. Typed LLVM\nfloating environment attributes, `strictfp`, incompatible exception policy,\nand unknown string attributes block standard spelling. LLVM enum function\nattributes and explicitly classified code-generation-only strings do not.\nClang's default `no-trapping-math=true` is compatible with the ordinary\nnon-constrained floating operation spelling; any other value fails closed.","why":"Linked input passage on the passthrough function-attribute classifier; drives sampling of enclosing llvm.func passthrough attributes (nounwind, strictfp, no-trapping-math=true, target-cpu) on the generated callables."},{"file_sha256":"bfc1e646e91fe0ba6d7d16e43994100b05c3b8ff79c2e07288e8955c43d9d79d","kind":"documentation_input","lines":"177-178","path":"docs/spec-compiler-part-2-scf.md","roles":["context"],"text":"FMA normalization is semantic rather than name based. An exact fused LLVM FMA\nbecomes `math.fma`. `llvm.intr.fmuladd` remains unchanged in S0 until one typed","why":"Linked input passage on semantic (non-name-based) normalization; establishes that spelling retention is decided by stated semantics, not opcode names."},{"file_sha256":"bfc1e646e91fe0ba6d7d16e43994100b05c3b8ff79c2e07288e8955c43d9d79d","kind":"documentation_input","lines":"266-268","path":"docs/spec-compiler-part-2-scf.md","roles":["input_well_formedness"],"text":"Fixed vectors may carry exceptional state per lane. A normalization is legal\nonly when it preserves the operation-specific rules for propagation,\nnon-observation, and undefined behavior.","why":"Linked input passage: a normalization is legal only when it preserves propagation, non-observation, and undefined-behavior rules; this is why a poison-on-zero input must stay well-formed as the registered LLVM operation."},{"file_sha256":"af4923a40d1fab8c6bbfe8bd954175a6ecefd8e6a9a3fc1e1d1f7a7221660da5","kind":"verifier","lines":"238-252","path":"lib/Frontend/Raising/LLVMArithToArithPass.cpp","roles":["applicability"],"text":"// The math zero-count operations define zero to return the operand width.\n// That is exactly the non-poisoning LLVM form. The poisoning form retains its\n// LLVM spelling because math has no attribute that can carry that contract.\ntemplate \nstruct CountZerosAlias : public ::mlir::OpRewritePattern {\n using ::mlir::OpRewritePattern::OpRewritePattern;\n\n ::mlir::LogicalResult\n matchAndRewrite(LLVMOp op, ::mlir::PatternRewriter &rewriter) const override {\n if (op.getIsZeroPoison() || !restatesExactly(op, /*floating=*/false))\n return ::mlir::failure();\n rewriter.replaceOpWithNewOp(op, op.getRes().getType(), op.getIn());\n return ::mlir::success();\n }\n};","why":"CountZerosAlias acceptance implementation: the rewrite bails out when getIsZeroPoison() holds, confirming which sampled inputs fall under the retained-spelling case and which are rewritten."},{"file_sha256":"af4923a40d1fab8c6bbfe8bd954175a6ecefd8e6a9a3fc1e1d1f7a7221660da5","kind":"implementation","lines":"568-573","path":"lib/Frontend/Raising/LLVMArithToArithPass.cpp","roles":["applicability"],"text":"// zero-count aliases whose zero behavior is fully defined\n CountZerosAlias<::mlir::LLVM::CountLeadingZerosOp,\n ::mlir::math::CountLeadingZerosOp>,\n CountZerosAlias<::mlir::LLVM::CountTrailingZerosOp,\n ::mlir::math::CountTrailingZerosOp>,","why":"Pattern registration binding LLVM::CountLeadingZerosOp/CountTrailingZerosOp to the math counterparts, establishing that this stage is the owner of the sampled obligation."},{"file_sha256":"af4923a40d1fab8c6bbfe8bd954175a6ecefd8e6a9a3fc1e1d1f7a7221660da5","kind":"implementation","lines":"480-492","path":"lib/Frontend/Raising/LLVMArithToArithPass.cpp","roles":["applicability","input_construction"],"text":"struct LLVMArithToArithPass\n : public ::mlir::PassWrapper> {\n MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(LLVMArithToArithPass)\n\n ::llvm::StringRef getArgument() const final {\n return \"loom-llvm-arith-to-arith\";\n }\n ::llvm::StringRef getDescription() const final {\n return \"Rewrite each llvm computation whose complete semantics an arith \"\n \"or math operation restates exactly into that standard operation, \"\n \"scoped to callable regions.\";\n }","why":"Pass declaration giving the --loom-llvm-arith-to-arith argument and its callable-region scoping, which is why generated intrinsics are placed inside llvm.func bodies."},{"file_sha256":"fc8794a0235430f2ab7b87b0fb63e4991acfa052ab630501b484fce956154a56","kind":"verifier","lines":"26-52","path":"lib/Frontend/Raising/ExactStandardSpelling.h","roles":["input_well_formedness","input_construction"],"text":"// True when `type` has an exact standard counterpart: a signless integer of\n// non-zero width, `index`, a float, or a fixed-shape vector of those.\n//\n// arith rejects zero-width and signed integers. A scalable vector's element\n// count is a runtime `vscale` multiple rather than a shape, so it fails closed\n// here and keeps its operations in llvm form: only once a typed structured\n// transform has materialized the computation as fixed-width chunks, loops, and\n// masks or tails do the resulting operations hold a fixed shape that these\n// aliases accept.\ninline bool isExactNumericType(::mlir::Type type) {\n if (auto vectorType = ::mlir::dyn_cast<::mlir::VectorType>(type)) {\n if (vectorType.isScalable())\n return false;\n type = vectorType.getElementType();\n }\n if (auto integerType = ::mlir::dyn_cast<::mlir::IntegerType>(type))\n return integerType.isSignless() && integerType.getWidth() > 0;\n return ::mlir::isa<::mlir::IndexType, ::mlir::FloatType>(type);\n}\n\ninline bool allExactNumericTypes(::mlir::ValueRange values) {\n for (::mlir::Value value : values) {\n if (!isExactNumericType(value.getType()))\n return false;\n }\n return true;\n}","why":"isExactNumericType defines the exact standard counterpart types (signless non-zero-width integers, index, float, fixed-shape vectors); the grammar samples only such types so type exactness never masks the poison-flag behavior."},{"file_sha256":"fc8794a0235430f2ab7b87b0fb63e4991acfa052ab630501b484fce956154a56","kind":"verifier","lines":"142-161","path":"lib/Frontend/Raising/ExactStandardSpelling.h","roles":["input_well_formedness"],"text":"// True when the enclosing callable states a floating-point environment the\n// standard operation cannot restate.\ninline bool enclosingFloatingPolicyBlocksRewrite(::mlir::Operation *op) {\n auto funcOp = ::mlir::dyn_cast_or_null<::mlir::LLVM::LLVMFuncOp>(\n getNearestCallableOp(op));\n return funcOp && statesFloatingPolicy(funcOp);\n}\n\n// True when every operand and the single result of `op` have an exact standard\n// counterpart and, for a computation that reads or produces a floating value,\n// the enclosing callable states no environment the standard operation cannot\n// restate. An integer computation is independent of that environment and is\n// never blocked by it.\ninline bool restatesExactly(::mlir::Operation *op, bool floating) {\n if (!allExactNumericTypes(op->getOperands()))\n return false;\n if (!isExactNumericType(op->getResult(0).getType()))\n return false;\n return !floating || !enclosingFloatingPolicyBlocksRewrite(op);\n}","why":"restatesExactly states that an integer computation is never blocked by the enclosing floating-point environment, so sampled passthrough attributes do not confound the poison-flag case."},{"file_sha256":"fc8794a0235430f2ab7b87b0fb63e4991acfa052ab630501b484fce956154a56","kind":"verifier","lines":"74-140","path":"lib/Frontend/Raising/ExactStandardSpelling.h","roles":["input_construction"],"text":"inline bool passthroughEntryStatesFloatingPolicy(::mlir::Attribute entry) {\n ::llvm::StringRef name;\n ::std::optional<::llvm::StringRef> value;\n if (auto nameAttr = ::mlir::dyn_cast<::mlir::StringAttr>(entry)) {\n name = nameAttr.getValue();\n } else if (auto pair = ::mlir::dyn_cast<::mlir::ArrayAttr>(entry);\n pair && pair.size() == 2) {\n auto nameAttr = ::mlir::dyn_cast<::mlir::StringAttr>(pair[0]);\n auto valueAttr = ::mlir::dyn_cast<::mlir::StringAttr>(pair[1]);\n if (!nameAttr || !valueAttr)\n return true;\n name = nameAttr.getValue();\n value = valueAttr.getValue();\n } else {\n return true;\n }\n\n // The LLVM importer places every function attribute that LLVMFuncOp does\n // not model explicitly in one passthrough array. LLVM enum attributes still\n // retain their stable native spelling there. Of those function attributes,\n // strictfp alone changes the floating execution environment; the others\n // describe effects, control, ABI, or code generation without changing the\n // meaning of an ordinary floating instruction.\n const ::llvm::Attribute::AttrKind kind =\n ::llvm::Attribute::getAttrKindFromName(name);\n if (kind != ::llvm::Attribute::None)\n return kind == ::llvm::Attribute::StrictFP;\n\n // These string attributes are emitted by ordinary Clang compilation but\n // are not all modeled as typed LLVMFuncOp fields by the pinned importer.\n // Keep this list closed: an unknown string attribute may carry target\n // floating semantics and therefore fails closed.\n const bool codegenOnly = ::llvm::StringSwitch(name)\n .Cases({\"min-legal-vector-width\",\n \"stack-protector-buffer-size\",\n \"target-cpu\"},\n true)\n .Default(false);\n if (codegenOnly)\n return false;\n\n // Clang's default -ffp-exception-behavior=ignore spelling. A false or\n // malformed value cannot be represented by an unconstrained arith/math op.\n if (name == \"no-trapping-math\")\n return !value || *value != \"true\";\n\n return true;\n}\n\ninline bool statesFloatingPolicy(::mlir::LLVM::LLVMFuncOp funcOp) {\n if (auto env = funcOp.getDenormalFpenvAttr())\n if (!statesDefaultDenormalEnvironment(env))\n return true;\n if (auto noSignedZeros = funcOp.getNoSignedZerosFpMathAttr())\n if (noSignedZeros.getValue())\n return true;\n if (auto contraction = funcOp.getFpContractAttr())\n if (contraction.getValue() != \"off\")\n return true;\n if (funcOp.getReciprocalEstimatesAttr())\n return true;\n if (auto passthrough = funcOp.getPassthroughAttr())\n for (::mlir::Attribute entry : passthrough)\n if (passthroughEntryStatesFloatingPolicy(entry))\n return true;\n return false;\n}","why":"Closed passthrough/floating-policy classifier; fixes the concrete accepted spellings of the function attributes the grammar samples on the enclosing llvm.func."},{"file_sha256":"cccfb541a40fcf45a23917c929f75862b06c996af3a8e06caa4533d971720279","kind":"test","lines":"1-13,376-388","path":"test/raise/llvm-arith-to-arith.mlir","roles":["input_construction","input_well_formedness"],"text":"// RUN: loom-raise-opt --loom-llvm-arith-to-arith %s | FileCheck %s\n\n// Verify that each LLVM computation whose complete semantics an arith or math\n// operation restates exactly is rewritten into that standard operation, and\n// that every source fact the standard operation cannot carry keeps its\n// operation in llvm form. Pointer-typed ops (gep/load/store/alloca) stay in\n// the llvm dialect on purpose.\n//\n// The pass rewrites every callable region in place, so an imported llvm.func\n// is normalized where it stands and stays the sole owner of its ABI envelope.\n// A case whose values are only observable as several results states its\n// container as a func.func, which anchors the same rewrite on the other\n// callable kind.\n\n// CHECK-LABEL: llvm.func @zero_count_aliases\nllvm.func @zero_count_aliases(%value: i32) -> i32 {\n // CHECK: %[[CTLZ:.*]] = math.ctlz %arg0 : i32\n %ctlz = \"llvm.intr.ctlz\"(%value) <{is_zero_poison = false}> : (i32) -> i32\n // CHECK: %[[CTTZ:.*]] = math.cttz %arg0 : i32\n %cttz = \"llvm.intr.cttz\"(%value) <{is_zero_poison = false}> : (i32) -> i32\n // CHECK: %[[CTLZ_POISON:.*]] = \"llvm.intr.ctlz\"(%arg0) <{is_zero_poison = true}> : (i32) -> i32\n %ctlz_poison = \"llvm.intr.ctlz\"(%value) <{is_zero_poison = true}> : (i32) -> i32\n // CHECK: %[[CTTZ_POISON:.*]] = \"llvm.intr.cttz\"(%arg0) <{is_zero_poison = true}> : (i32) -> i32\n %cttz_poison = \"llvm.intr.cttz\"(%value) <{is_zero_poison = true}> : (i32) -> i32\n llvm.return %ctlz : i32\n}","why":"Accepted concrete input spelling for the zero-count intrinsics (generic form with the is_zero_poison property inside an llvm.func) and the pass invocation used for this stage; non-normative evidence of syntax only."}],"primary_bundle_sha256":"4748aa2894227784ac5cec7ed36d55b8fcde2e8fd4980afd13601f599d5f63e5","project":"PolyArch/loom","revision":"48615bc5925ef4b9db8b4550b5d4322933cf4b7b","schema":"spectriad.authoring-context/v1","selection_sha256":"31ccf46b27fcc8366d175267a6bf6c666d3e6462ef32554a9b26e325f50e4455"}