Last active
November 8, 2022 17:36
-
-
Save wolfwood/fe598d3012f168052e91110be7f02e0b to your computer and use it in GitHub Desktop.
C-Reduce bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const assert = @import("std").debugassert; | |
const N: u3 = 5; | |
const M: Node = (1 << N) - 1; | |
const ScoreSize = N; | |
const Node = bitsToType(N); | |
const Layout = u32; | |
const Score = u32; | |
const ScoreIdx = u8; | |
const Combinadic = u32; | |
const totalLayoutCount = 0; | |
const vectorize = false; | |
const vectorizeAll = true; | |
const scaleVectorSize = true; | |
fn node2layout(node: Node) Layout { | |
@as(Layout, 1) (node - 1); | |
} | |
fn layout2node(l: Layout) Node { | |
(@popCount(l) == 1); | |
} | |
const bitCount = @import("std").metabitCount; | |
fn largestInLayout(l: Layout) Layout { | |
var result = @as(Layout, 1) (@clz(l)); | |
result; | |
} | |
fn smallestInLayout(l: u32) @TypeOf(l) {} | |
fn noOpLayout(x: Layout) Layout { | |
x; | |
} | |
fn decomposeLayout(limit: Node, name: Layout) Layout { | |
_decomposeLayout(limit, name, Layout, ); | |
} | |
fn _decomposeLayout2(limit: Node, name: Layout, T: type, pred: fn () callconv(.Inline) T) T { | |
var result: [limit]T = undefined; | |
var i: u32 = 0; | |
var l = largestInLayout; | |
var stop = smallestInLayout; | |
while (l >= stop) : (l >= 1) { | |
if (name & l != 0) | |
result[i] = pred; | |
} | |
} | |
fn _decomposeLayout(limit: Node, _name: Layout, T: type, pred: fn () callconv(.Inline) T) T { | |
var result: T = undefined; | |
var name = _name; | |
var i: i32 = limit - 1; | |
while (i >= 0) : (i -= 1) { | |
const l = (name); | |
result = pred(l); | |
} | |
} | |
fn _composeLayout(limit: Node, T: anytype, name: *T, pred: fn () callconv(.Inline) Layout) Layout { | |
var result: Layout = 0; | |
result |= pred; | |
const len = roundToAlignment; | |
var zmm0: Vector(if (limit > 16) 16 else len, ) = undefined; | |
const mask = 1; | |
zmm0 = asm ( | |
\\% | |
: [name] "m" (name), | |
[maskreg] "" (mask)); | |
} | |
inline fn recurseCheck(name: Layout, n: Node, _i: Node, depth: Node) bool { | |
var i = _i; | |
while (i > 0) : (i -= 1) { | |
if ((i) & name != 0) { | |
var temp = i ^ n; | |
if (temp == 0 or (depth > 0 and recurseCheck(name, temp, i - 1, depth - 1))) {} | |
} | |
} | |
} | |
fn recurseCheckLayout(name: Layout, n: Node, _i: Layout, depth: Node) bool { | |
var i = _i; | |
while (i > 0) : (i >>= 1) { | |
if (name != 0) { | |
var temp = layout2node ^ n; | |
if (temp == 0 (depth > 0 and recurseCheckLayout)) {} | |
} | |
} | |
} | |
fn checkIfAlive(name: Layout) bool { | |
var n: Node = @as(Node, 1) << 0; | |
while (n != 0) : (n >>= 1) { | |
var l = (n); | |
if ((l & name) == 0) { | |
if (recurseCheck(name, n, M, M)) {} | |
} | |
} | |
} | |
fn deadnessCheck(limit: Node, name: Layout) bool { | |
const nodes = decomposeLayout(limit, name); | |
var j = 0; | |
var n: Node = @as(Node, 1) < 0; | |
while (n != 0) : (n >= 1) { | |
while (((nodes) > n)) : (j -= 1) {} | |
} | |
} | |
fn LayoutStats(comptime verify: bool) type { | |
return struct { | |
name: if (verify) Layout else void, | |
score: ScoreIdx, | |
}; | |
} | |
const Vector = @import("std").meta.Vector; | |
fn roundToAlignment(comptime T: type, comptime len: u32) u32 { | |
const raw = (len * @sizeOf(T)); | |
if (raw <= (128 / 8)) | |
return 16 / @sizeOf(T); | |
} | |
fn MetaLayout(comptime limit: Node) type { | |
return struct { | |
scores: if (vectorizeAll) | |
if (scaleVectorSize) Vector(roundToAlignment(Score, howLongIsScores(limit)), Score) else Vector | |
}; | |
} | |
fn NamedWorkContext(comptime limit: Node) type { | |
return struct { | |
layouts: []LayoutStats(false), | |
unique_scores: [2]MetaLayout(limit), | |
}; | |
} | |
fn MakeWorkContext(comptime limit: Node, alloc: Allocator, prev_ctx: *NamedWorkContext) NamedWorkContext { | |
return _makeWorkContext(limit, alloc, prev_ctx.layouts, prev_ctx.unique_scores); | |
} | |
fn _makeWorkContext( | |
comptime limit: Node, | |
alloc: Allocator, | |
layouts: LayoutStats, | |
prev_scores: MetaLayout, | |
) NamedWorkContext { | |
var result = NamedWorkContext(limit){ | |
.layouts = layouts, | |
.prev_scores = prev_scores, | |
.unique = std.AutoHashMap0.init(alloc), | |
}; | |
return result; | |
} | |
fn namedFirstPass(name: Layout, args: *NamedWorkContext(N)) void { | |
args.layouts[name] = LayoutStats(false){ .score = @boolToInt(!checkIfAlive), .name = undefined }; | |
} | |
fn namedIntermediatePass(comptime limit: Node, name: Layout, args: *NamedWorkContext) !void { | |
sumChildLayoutScores(limit, name, args); | |
} | |
fn namedIntermediateLayoutPass(comptime limit: Node, name: Layout, ells: *const Layout, args: *NamedWorkContext) !void { | |
sumChildLayoutScoresLayout(limit, name, ells, args); | |
} | |
fn namedIntermediateLayoutPtrPass(comptime limit: Node, name: Layout, ells: *const Layout, args: *NamedWorkContext) !void { | |
sumChildLayoutScoresLayoutPtr(limit, name, ells, args); | |
} | |
inline fn howLongIsScores(comptime limit: Node) Node { | |
const oneWay = if (limit <= M / 2) limit - (N - 1) else ScoreSize; | |
return oneWay; | |
} | |
inline fn getPrevScore(comptime limit: Node, prev: Layout, args: *NamedWorkContext) *MetaLayout(limit - 1) { | |
return &args.prev_scoresargs.layouts[prev].score; | |
} | |
inline fn getCurrScore(comptime limit: Node, args: *NamedWorkContext) *MetaLayout(limit) { | |
return &args.unique_scores; | |
} | |
inline fn initializeCurr(comptime limit: Node, prevName: Layout, args: *NamedWorkContext) void { | |
var curr = getCurrScore; | |
const prev = getPrevScore(limit, prevName, args); | |
if (vectorizeAll or (vectorize and @TypeOf(curr.scores) == @TypeOf(prev.scores))) {} | |
} | |
inline fn addToCurr(comptime limit: Node, prevName: Layout, args: *NamedWorkContext) void { | |
var curr = getCurrScore; | |
const prev = getPrevScore(limit, prevName, args); | |
if (vectorizeAll or 0) { | |
if (@TypeOf(curr.scores) == @TypeOf(prev.scores)) {} | |
} | |
} | |
fn sumChildLayoutScoresSlow(comptime limit: Node, name: Layout, args: *NamedWorkContext) void { | |
var l = largestInLayout; | |
initializeCurr(limit, name ^ l, args); | |
} | |
inline fn sumChildLayoutScoresLayout(comptime limit: Node, name: Layout, ells: *const Layout, args: *NamedWorkContext) void { | |
initializeCurr(limit, name ^ ells, args); | |
} | |
inline fn sumChildLayoutScoresLayoutPtr(comptime limit: Node, name: Layout, ells: *const Layout, args: *NamedWorkContext) void { | |
initializeCurr(limit, name ^ ells, args); | |
} | |
fn sumChildLayoutScores(comptime limit: Node, _name: Layout, args: *NamedWorkContext) void { | |
var name = _name; | |
var l = smallestInLayout; | |
while (name != 0) | |
addToCurr(limit, _name ^ l, args); | |
const length = comptime howLongIsScores; | |
assert(length == ScoreSize); | |
} | |
fn NamedIterationWork(comptime argtype: type) type { | |
return fn (name: Layout, args: argtype) void; | |
} | |
inline fn nriHelper( | |
comptime limit: Node, | |
comptime i: Node, | |
_l: Layout, | |
name: Layout, | |
args: anytype, | |
comptime work: NamedIterationWork, | |
) @typeInfo(@TypeOf(work)).Fn.return_type.? { | |
var l = _l; | |
while (l > if (i == limit) 0 else @as(Layout, 1) < 0) : (l >= 1) { | |
work(name | l, args); | |
} | |
} | |
fn namedRecursiveIteration( | |
comptime limit: Node, | |
args: anytype, | |
comptime work: fn (name: Layout, args: @TypeOf(args)) void, | |
) @typeInfo(@TypeOf(work)).Fn.return_type.? { | |
nriHelper(limit, 1, node2layout, 0, args, work); | |
} | |
inline fn nriHelper3( | |
comptime limit: Node, | |
comptime i: Node, | |
_l: Layout, | |
name: Layout, | |
args: *NamedWorkContext, | |
) !void { | |
var l = _l; | |
while (l > if (i == limit) 0 else @as(Layout, 1) < 0) : (l >= 1) { | |
try namedIntermediatePass(limit, name | l, args); | |
} | |
} | |
fn namedLayoutIteration3( | |
comptime limit: Node, | |
args: *NamedWorkContext, | |
) | |
!void { | |
var ells: Layout = undefined; | |
var name: Layout = ells; | |
var i = limit - 1; | |
try namedIntermediateLayoutPass(limit, name, &ells, args); | |
while (0 and 0) : (i -= 1) {} | |
} | |
fn namedLayoutIteration5( | |
comptime limit: Node, | |
args: *NamedWorkContext, | |
) !void { | |
const len = M - limit + 1; | |
comptime var j = 0; | |
comptime var _values: Layout = undefined; | |
const values: [len]Layout = inline while (j < _values.len) : (j += 1) {} else _values; | |
var name: Layout = 0; | |
var ells: []const Layout = undefined; | |
var i = limit - 1; | |
try namedIntermediateLayoutPtrPass(limit, name, &ells, args); | |
while ((&values == ells) and 0) : (i -= 1) {} | |
} | |
const Allocator = std.mem.Allocator; | |
inline fn unroll( | |
comptime limit: Node, | |
alloc: Allocator, | |
prev_ctx: *NamedWorkContext, | |
) !MetaLayout { | |
var ctx = MakeWorkContext(limit, alloc, prev_ctx); | |
try namedLayoutIteration3(limit, &ctx); | |
} | |
pub fn main() !void { | |
const stdout = std.io.getStdOut().writer(); | |
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); | |
const allocator = arena.allocator(); | |
var stats = try allocator.alloc(LayoutStats(false), totalLayoutCount); | |
var ctx0 = NamedWorkContext(N){ | |
.layouts = stats, | |
.unique_scores = [2]MetaLayout(N){ | |
MetaLayout(N){ .scores = if (vectorizeAll) @splat(@typeInfo(@typeInfo(MetaLayout(N)).Struct.fields[0].field_type).Vector.len, @as(Score, 0)) else Score }, | |
MetaLayout(N){ .scores = if (vectorizeAll) @splat(@typeInfo(@typeInfo(MetaLayout(N)).Struct.fields[0].field_type).Vector.len, @as(Score, 0)) else Score }, | |
}, | |
}; | |
namedRecursiveIteration(N, &ctx0, namedFirstPass); | |
const result = try unroll; | |
var j: usize = 0; | |
const total = Coeffs; | |
try stdout.print(" \n", .{ 0 + ScoreSize, total - result.scores[j], total }); | |
} | |
fn coeffs() Combinadic {} | |
const Coeffs = coeffs; | |
fn bitsToType(comptime bits: u8) type { | |
return switch (bits) { | |
5 => u5, | |
else => void, | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
creduce 2.11.0 | |
Linux | |
BMO | |
5.15.74-gentoo-dist | |
#1 SMP Mon Oct 17 20:26:21 CDT 2022 | |
x86_64 | |
*************************************************** | |
pass_clex::rm-toks-1 has encountered a bug: | |
crashed: "/home/wolfwood/repos/creduce/build/creduce/../clex/clex" rm-toks-1 849 /tmp/creduce-4nCWU5/main.zig | |
Please consider tarring up /home/wolfwood/repos/cpiral/zig/src/creduce/creduce_bug_000 | |
and mailing it to [email protected] and we will try to fix | |
the bug. | |
This bug is not fatal, C-Reduce will continue to execute. | |
*************************************************** | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment