You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
11 KiB
302 lines
11 KiB
using System.Runtime.CompilerServices; |
|
using Unity.Burst; |
|
using Unity.Burst.CompilerServices; |
|
|
|
namespace Burst.Compiler.IL.Tests |
|
{ |
|
#if BURST_INTERNAL || UNITY_BURST_EXPERIMENTAL_LOOP_INTRINSICS |
|
internal class LoopIntrinsics |
|
{ |
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe void CheckExpectVectorizedImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
a[i] += b[i]; |
|
} |
|
} |
|
|
|
[TestCompiler(100, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Loops are not vectorized when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorized(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectVectorizedImpl(a, b, count); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] |
|
private static unsafe void CheckExpectVectorizedNoOptimizationsImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
a[i] += b[i]; |
|
} |
|
} |
|
|
|
[TestCompiler(100, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoopUnexpectedAutoVectorization, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Intrinsics are not evaluated when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorizedNoOptimizations(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectVectorizedNoOptimizationsImpl(a, b, count); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] |
|
private static unsafe void CheckExpectNotVectorizedNoOptimizationsImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectNotVectorized(); |
|
|
|
a[i] += b[i]; |
|
} |
|
} |
|
|
|
[TestCompiler(100, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
public static unsafe void CheckExpectNotVectorizedNoOptimizations(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectNotVectorizedNoOptimizationsImpl(a, b, count); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoOptimization)] |
|
private static unsafe void CheckExpectVectorizedOptimizationsDisabledImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
a[i] += b[i]; |
|
} |
|
} |
|
|
|
[TestCompiler(100, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoopUnexpectedAutoVectorization, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("We only validate loop intrinsics with optimizations enabled")] |
|
public static unsafe void CheckExpectVectorizedOptimizationsDisabled(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectVectorizedOptimizationsDisabledImpl(a, b, count); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe void CheckExpectNotVectorizedImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectNotVectorized(); |
|
|
|
if (a[i] > b[i]) |
|
{ |
|
break; |
|
} |
|
|
|
a[i] += b[i]; |
|
} |
|
} |
|
|
|
[TestCompiler(100, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
public static unsafe void CheckExpectNotVectorized(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectNotVectorizedImpl(a, b, count); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe void CheckExpectVectorizedFailImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
if (a[i] > b[i]) |
|
{ |
|
break; |
|
} |
|
|
|
a[i] += b[i]; |
|
} |
|
} |
|
|
|
[TestCompiler(100, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoopUnexpectedAutoVectorization, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Intrinsics are not evaluated when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorizedFail(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectVectorizedFailImpl(a, b, count); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe void CheckExpectNotVectorizedFailImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectNotVectorized(); |
|
|
|
a[i] += b[i]; |
|
} |
|
} |
|
|
|
[TestCompiler(100, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoopUnexpectedAutoVectorization, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Loops are not vectorized when optimizations are disabled")] |
|
public static unsafe void CheckExpectNotVectorizedFail(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectNotVectorizedFailImpl(a, b, count); |
|
} |
|
|
|
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoopIntrinsicMustBeCalledInsideLoop, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Intrinsics are not evaluated when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorizedOutsideLoop() |
|
{ |
|
Loop.ExpectVectorized(); |
|
} |
|
|
|
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoopIntrinsicMustBeCalledInsideLoop, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Intrinsics are not evaluated when optimizations are disabled")] |
|
public static unsafe void CheckExpectNotVectorizedOutsideLoop() |
|
{ |
|
Loop.ExpectNotVectorized(); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe void CheckExpectVectorizedMultipleCallsImpl([NoAlias] int* a, [NoAlias] int* b, int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
a[i] += b[i]; |
|
|
|
Loop.ExpectVectorized(); |
|
} |
|
} |
|
|
|
[TestCompiler(100, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Loops are not vectorized when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorizedMultipleCalls(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectVectorizedMultipleCallsImpl(a, b, count); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe void CheckExpectVectorizedUnrolledLoopImpl([NoAlias] int* a, [NoAlias] int* b) |
|
{ |
|
for (var i = 0; i < 4; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
if (a[i] > b[i]) |
|
{ |
|
a[i] += b[i]; |
|
} |
|
} |
|
} |
|
|
|
[TestCompiler(100, ExpectedDiagnosticId = DiagnosticId.WRN_LoopIntrinsicCalledButLoopOptimizedAway, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Loops are not vectorized when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorizedUnrolledLoop(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
|
|
CheckExpectVectorizedUnrolledLoopImpl(a, b); |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe int CheckExpectVectorizedPartiallyUnrolledLoopImpl(int* a, int count) |
|
{ |
|
var sum = 0; |
|
|
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
sum += a[i]; |
|
} |
|
|
|
return sum; |
|
} |
|
|
|
[TestCompiler(100, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Loops are not vectorized when optimizations are disabled")] |
|
public static unsafe int CheckExpectVectorizedPartiallyUnrolledLoop(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
|
|
a[0] = 8; |
|
a[10] = 16; |
|
|
|
return CheckExpectVectorizedPartiallyUnrolledLoopImpl(a, count); |
|
} |
|
|
|
[TestCompiler(100, ExpectedDiagnosticId = DiagnosticId.WRN_LoopIntrinsicCalledButLoopOptimizedAway, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Loops are not vectorized when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorizedRemovedLoop(int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
} |
|
} |
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)] |
|
private static unsafe void CheckExpectVectorizedNestedImpl( |
|
[NoAlias] int* a, [NoAlias] int* b, |
|
[NoAlias] int* c, [NoAlias] int* d, |
|
int count) |
|
{ |
|
for (var i = 0; i < count; i++) |
|
{ |
|
Loop.ExpectNotVectorized(); |
|
|
|
if (a[i] > b[i]) |
|
{ |
|
break; |
|
} |
|
|
|
a[i] += b[i]; |
|
|
|
for (var j = i; j < count; j++) |
|
{ |
|
Loop.ExpectVectorized(); |
|
|
|
c[j] += d[j]; |
|
} |
|
} |
|
} |
|
|
|
[TestCompiler(100, IgnoreOnPlatform = Backend.TargetPlatform.Wasm)] |
|
[OptimizationsOnly("Loops are not vectorized when optimizations are disabled")] |
|
public static unsafe void CheckExpectVectorizedNested(int count) |
|
{ |
|
var a = stackalloc int[count]; |
|
var b = stackalloc int[count]; |
|
var c = stackalloc int[count]; |
|
var d = stackalloc int[count]; |
|
|
|
CheckExpectVectorizedNestedImpl(a, b, c, d, count); |
|
} |
|
} |
|
#endif |
|
}
|
|
|