// Input domain for the Structured ExecutionShape generator stage // (loom-raise-opt --loom-materialize-fmuladd=shape=...). // // The generator consumes a finite set of exact Structured Program references // (linked-input-61), so each sample is a finite module holding one to four // complete Structured parents (callables). Two parent shapes are sampled: // // * parents with no unresolved selected-Spatial execution-shape choice, // which the generator must pass through unchanged (linked-input-61); // * parents holding one or more unresolved, exactly representable // `llvm.intr.fmuladd` operations (linked-input-101, linked-input-127). // // Exact representability is an input well-formedness requirement of the // sampled claim, so every sampled callable states only a floating environment // the standard `math`/`arith` spellings can restate: either no floating // attribute at all, or the ordinary non-constrained Clang envelope // (`fp_contract = "off"`, IEEE denormal environment, code-generation-only // passthrough strings, `no-trapping-math = "true"`). Operand and result // types stay exact standard numeric types (floats and fixed-shape vectors of // floats). // // One execution-shape decision applies uniformly to every unresolved fmuladd // of a complete parent (linked-input-165), so the shape itself is a single // subject-command option and is never sampled per operation here. The // grammar samples only inputs: it never spells math.fma, arith.mulf or // arith.addf as an expected result. // // Nested callables are sampled too (linked-input-165 names operations owned // by nested callables), as a native func.func parent holding an inner // imported llvm.func. start: {new COUNT = random.randint(1, 4); new I = 0} parents; parents: (I < COUNT) parent {I += 1} parents | (I == COUNT) ''; parent: plain_fma_func | typed_fma_func | envelope_fma_func | mixed_fma_func | native_fma_func | nested_callable_func | no_choice_func; // ------------------------------------------------------- unresolved parents // An imported callable stating no floating-point environment of its own. plain_fma_func: {new NAME = 'plain_' + str(I); new TY = 'f32'; new N = random.randint(1, 3); new K = 0; new SRC = '%x'; new FM = ''} 'llvm.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ') -> ' [TY] ' {\n' fma_chain ' llvm.return ' [SRC] ' : ' [TY] '\n' '}\n\n'; // The exact floating type and fast-math contract are part of the sampled // input (linked-input-101), so both vary over exact standard numeric types // and over the imported fast-math flag sets. typed_fma_func: {new NAME = 'typed_' + str(I); new TY = random.choice(['f32', 'f64', 'f16', 'vector<4xf32>', 'vector<8xf64>']); new N = random.randint(1, 3); new K = 0; new SRC = '%x'; new FM = ''} fastmath_choice 'llvm.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ') -> ' [TY] ' {\n' fma_chain ' llvm.return ' [SRC] ' : ' [TY] '\n' '}\n\n'; // An ordinary Clang function envelope that states no environment a standard // operation cannot restate: the choice is still unresolved and representable. envelope_fma_func: {new NAME = 'envelope_' + str(I); new TY = random.choice(['f32', 'f64']); new N = random.randint(1, 2); new K = 0; new SRC = '%x'; new FM = ''} fastmath_choice 'llvm.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ') -> ' [TY] '\n' ' attributes {' benign_envelope '} {\n' fma_chain ' llvm.return ' [SRC] ' : ' [TY] '\n' '}\n\n'; // A parent whose selected-Spatial ownership also holds ordinary floating and // integer computation next to the unresolved choice. mixed_fma_func: {new NAME = 'mixed_' + str(I); new TY = random.choice(['f32', 'f64']); new N = random.randint(1, 2); new K = 0; new SRC = '%x'; new FM = ''} 'llvm.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ', %i: i32) -> ' [TY] ' {\n' ' %scaled = llvm.fmul %x, %y : ' [TY] '\n' ' %counted = llvm.add %i, %i : i32\n' fma_chain ' %blended = llvm.fadd ' [SRC] ', %scaled : ' [TY] '\n' ' llvm.return %blended : ' [TY] '\n' '}\n\n'; // A genuinely standard-MLIR-native callable parent. native_fma_func: {new NAME = 'native_' + str(I); new TY = random.choice(['f32', 'f64']); new N = random.randint(1, 2); new K = 0; new SRC = '%x'; new FM = ''} 'func.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ') -> ' [TY] ' {\n' fma_chain ' return ' [SRC] ' : ' [TY] '\n' '}\n\n'; // A native parent owning a nested imported callable: the unresolved choice // lives in the nested callable's own ownership. nested_callable_func: {new NAME = 'nested_' + str(I); new TY = 'f32'; new N = random.randint(1, 2); new K = 0; new SRC = '%x'; new FM = ''} 'func.func @' [NAME] '(%a: ' [TY] ') -> ' [TY] ' {\n' ' builtin.module {\n' ' llvm.func @inner_' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ') -> ' [TY] ' {\n' fma_chain ' llvm.return ' [SRC] ' : ' [TY] '\n' ' }\n' ' }\n' ' return %a : ' [TY] '\n' '}\n\n'; // ------------------------------------------------------- unresolved chain fma_chain: (K < N) fma_stmt {K += 1} fma_chain | (K == N) ''; fma_stmt: ' %r' [str(K)] ' = llvm.intr.fmuladd(' [SRC] ', %y, %z)' [FM] ' : (' [TY] ', ' [TY] ', ' [TY] ') -> ' [TY] '\n' {SRC = '%r' + str(K)}; fastmath_choice: {FM = random.choice(['', ' {fastmathFlags = #llvm.fastmath}', ' {fastmathFlags = #llvm.fastmath}', ' {fastmathFlags = #llvm.fastmath}', ' {fastmathFlags = #llvm.fastmath}'])} ''; benign_envelope: 'fp_contract = "off"' | 'denormal_fpenv = #llvm.denormal_fpenv' | 'passthrough = ["nofree", "norecurse", "nosync", ["min-legal-vector-width", "0"], ["no-trapping-math", "true"], ["stack-protector-buffer-size", "8"], ["target-cpu", "generic-rv64"]]'; // ------------------------------------------- parents with no pending choice // "A parent with no unresolved selected-Spatial execution-shape choice passes // through unchanged" (linked-input-61): sampled as callables holding ordinary // floating computation, an already-fused math.fma, or an already-split // multiply/add pair, and as an empty module. no_choice_func: ordinary_func | already_fused_func | already_split_func | empty_parent; ordinary_func: {new NAME = 'ordinary_' + str(I); new TY = random.choice(['f32', 'f64'])} 'llvm.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ') -> ' [TY] ' {\n' ' %sum = llvm.fadd %x, %y : ' [TY] '\n' ' llvm.return %sum : ' [TY] '\n' '}\n\n'; already_fused_func: {new NAME = 'fused_' + str(I); new TY = random.choice(['f32', 'f64'])} 'llvm.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ') -> ' [TY] ' {\n' ' %fma = math.fma %x, %y, %z : ' [TY] '\n' ' llvm.return %fma : ' [TY] '\n' '}\n\n'; already_split_func: {new NAME = 'split_' + str(I); new TY = random.choice(['f32', 'f64'])} 'llvm.func @' [NAME] '(%x: ' [TY] ', %y: ' [TY] ', %z: ' [TY] ') -> ' [TY] ' {\n' ' %prod = arith.mulf %x, %y : ' [TY] '\n' ' %sum = arith.addf %prod, %z : ' [TY] '\n' ' llvm.return %sum : ' [TY] '\n' '}\n\n'; empty_parent: '';