Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/Antigen/Antigen/Antigen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Utils;
using System.Linq;
using System.Runtime.CompilerServices;
using Antigen.Compilation;
using Antigen.Execution;
using System.Reflection;
using System.Runtime.InteropServices;
Expand Down Expand Up @@ -89,8 +90,15 @@ internal static int Run(AntigenRootCommand command)
TestCase.s_Driver = EEDriver.GetInstance(s_runOptions.CoreRun, Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ExecutionEngine.dll"), () => EnvVarOptions.TestVars(includeOsrSwitches: PRNG.Decide(0.3), false));
TestCase.s_TestRunner = TestRunner.GetInstance(TestCase.s_Driver, s_runOptions.CoreRun);

// Generate vector methods
VectorHelpers.RecordVectorMethods();
// Generate vector methods. The flag must be set before recording, because the
// method pool is built once and reused for every test case. The pool and the
// compiler both read CORE_ROOT so that the API surface Antigen generates against
// is the same one the tests will execute against.
string coreRootDirectory = Path.GetDirectoryName(Path.GetFullPath(s_runOptions.CoreRun));
Compiler.SetReferenceDirectory(coreRootDirectory);
VectorHelpers.AllowFloatToIntegralReinterpret =
result.GetValue(command.AllowFloatToIntegralReinterpret);
VectorHelpers.RecordVectorMethods(coreRootDirectory);

Parallel.For(0, 4, (p) => RunTest());
Console.WriteLine($"Executed {s_testId} test cases.");
Expand Down
1 change: 1 addition & 0 deletions src/Antigen/Antigen/Antigen.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.3.0 " />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.8" />
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions src/Antigen/Antigen/AntigenRootCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ internal sealed class AntigenRootCommand : RootCommand
new("--NumTestCases", "-n") { Description = "Number of test cases to execute. By default, 1000." };
public Option<int> RunDuration { get; } =
new("--RunDuration", "-d") { Description = "Duration in minutes to run. By default until NumTestCases, but if Duration is given, will override the NumTestCases." };
public Option<bool> AllowFloatToIntegralReinterpret { get; } =
new("--AllowFloatToIntegralReinterpret") { Description = "Allow reinterpret-casting floating point vectors to integral types (for example, Vector128.AsInt32()). Can cause false positives due to differing NaN representations." };

public ParseResult Result { get; private set; }

Expand All @@ -26,6 +28,7 @@ public AntigenRootCommand(string[] args) : base("Antigen JIT fuzzer")
Options.Add(IssuesFolder);
Options.Add(NumTestCases);
Options.Add(RunDuration);
Options.Add(AllowFloatToIntegralReinterpret);

SetAction(result =>
{
Expand Down
15 changes: 14 additions & 1 deletion src/Antigen/Antigen/Expressions/ConstantValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ public class ConstantValue : Expression
{ "Vector4", new List<string>() { "One", "Zero", "UnitW", "UnitX", "UnitY", "UnitZ" } },
};

// Reduce the prevelence of vector-of-floats.AllBitsSet(), as NaN's tend to pollute
// otherwise interesting computations
private const double FloatingPointAllBitsSetProbability = 0.05;
private const double IntegralAllBitsSetProbability = 0.5;

private static readonly List<string> s_nonNaNVectorConstants = new List<string>() { "Zero", "One", "Indices" };

protected ConstantValue(Tree.ValueType valueType, string value) : base(null)
{
if (valueType.PrimitiveType == Primitive.Char)
Expand Down Expand Up @@ -87,7 +94,13 @@ public static ConstantValue GetConstantValue(Tree.ValueType literalType, IList<W
}
else
{
constantValue += (PRNG.Decide(0.5) ? ".AllBitsSet" : ".Zero");
double allBitsSetProbability = literalType.HasFloatingPointElement()
? FloatingPointAllBitsSetProbability
: IntegralAllBitsSetProbability;

constantValue += PRNG.Decide(allBitsSetProbability)
? ".AllBitsSet"
: ("." + s_nonNaNVectorConstants[PRNG.Next(s_nonNaNVectorConstants.Count)]);
}
}
else if ((literalType.PrimitiveType & Primitive.Numeric) != 0)
Expand Down
15 changes: 14 additions & 1 deletion src/Antigen/Antigen/Helpers/PreGenerated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,20 @@ public static Statement StaticMethods

staticMethodBuilder.AppendLine("public static int Antigen() { ");
staticMethodBuilder.AppendLine($"new {MainClassName}().Method0();");
staticMethodBuilder.AppendLine("return string.Join(Environment.NewLine, toPrint).GetHashCode();");
staticMethodBuilder.AppendLine("return StableHash(string.Join(Environment.NewLine, toPrint));");
staticMethodBuilder.AppendLine("}");

// FNV-1a hash.
// Stable run-to-run as opposed to string.GetHashCode()
staticMethodBuilder.AppendLine("[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]");
staticMethodBuilder.AppendLine("public static int StableHash(string s) {");
staticMethodBuilder.AppendLine("ulong h = 14695981039346656037UL;");
staticMethodBuilder.AppendLine("for (int i = 0; i < s.Length; i++) {");
staticMethodBuilder.AppendLine("char c = s[i];");
staticMethodBuilder.AppendLine("h ^= (byte)c; h *= 1099511628211UL;");
staticMethodBuilder.AppendLine("h ^= (byte)(c >> 8); h *= 1099511628211UL;");
staticMethodBuilder.AppendLine("}");
staticMethodBuilder.AppendLine("return (int)(h ^ (h >> 32));");
staticMethodBuilder.AppendLine("}");

// Log method
Expand Down
Loading