Skip to content

Instantly share code, notes, and snippets.

@wolfwood
Last active November 8, 2022 17:36
Show Gist options
  • Save wolfwood/fe598d3012f168052e91110be7f02e0b to your computer and use it in GitHub Desktop.
Save wolfwood/fe598d3012f168052e91110be7f02e0b to your computer and use it in GitHub Desktop.
C-Reduce bug
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,
};
}
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