diff options
| author | Mukund Keshava <mkeshava@nvidia.com> | 2025-05-11 02:29:37 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-10 20:59:37 +0000 |
| commit | 083eecee3f56b90c7011895f53aaafa9db15856e (patch) | |
| tree | a0a18f0905f2884374ee351713fe77af0843f679 /tests/language-feature | |
| parent | 48203ea02250ba517f749a222092f091d9bef15e (diff) | |
Add debug information for slang inling (#6621)
Diffstat (limited to 'tests/language-feature')
4 files changed, 296 insertions, 0 deletions
diff --git a/tests/language-feature/function-calls/forceinline-basic-block-inline-order.slang b/tests/language-feature/function-calls/forceinline-basic-block-inline-order.slang new file mode 100644 index 000000000..24bfd5dff --- /dev/null +++ b/tests/language-feature/function-calls/forceinline-basic-block-inline-order.slang @@ -0,0 +1,39 @@ +//TEST:SIMPLE(filecheck=CHECK): -stage compute -entry computeMain -target spirv -O0 -g3 +RWStructuredBuffer<int> outputBuffer; + +// Test where outer function is inlined before the inner function. + +[ForceInline] +int inlineSingleBasicBlock1(int value1, int value2) +{ + // Simple operation that should be inlined + return value1 * 2 + value2; +} + +[__unsafeForceInlineEarly] +int inlineSingleBasicBlock2(int value1, int value2) +{ + int result1 = inlineSingleBasicBlock1(10, 20); + // Simple operation that should be inlined + return value1 * 2 + value2 + result1; +} + + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int i = dispatchThreadID.x; + + // Call the forceinline function + int result = inlineSingleBasicBlock2(16, 10); + + outputBuffer[i] = result; +} + + +// CHECK-COUNT-2: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} +// CHECK-COUNT-3: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}} +// CHECK-COUNT-1: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugNoScope +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugNoScope
\ No newline at end of file diff --git a/tests/language-feature/function-calls/forceinline-basic-block.slang b/tests/language-feature/function-calls/forceinline-basic-block.slang new file mode 100644 index 000000000..32e8faef5 --- /dev/null +++ b/tests/language-feature/function-calls/forceinline-basic-block.slang @@ -0,0 +1,37 @@ +//TEST:SIMPLE(filecheck=CHECK): -stage compute -entry computeMain -target spirv -O0 -g3 +RWStructuredBuffer<int> outputBuffer; + +[ForceInline] +int inlineSingleBasicBlock1(int value1, int value2) +{ + // Simple operation that should be inlined + return value1 * 2 + value2; +} + +[ForceInline] +int inlineSingleBasicBlock2(int value1, int value2) +{ + int result1 = inlineSingleBasicBlock1(10, 20); + // Simple operation that should be inlined + return value1 * 2 + value2 + result1; +} + + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int i = dispatchThreadID.x; + + // Call the forceinline function + int result = inlineSingleBasicBlock2(16, 10); + + outputBuffer[i] = result; +} + + +// CHECK-COUNT-2: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} +// CHECK-COUNT-3: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}} +// CHECK-COUNT-1: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugNoScope +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugNoScope
\ No newline at end of file diff --git a/tests/language-feature/function-calls/forceinline-multiple-blocks.slang b/tests/language-feature/function-calls/forceinline-multiple-blocks.slang new file mode 100644 index 000000000..dba1d3953 --- /dev/null +++ b/tests/language-feature/function-calls/forceinline-multiple-blocks.slang @@ -0,0 +1,79 @@ +//TEST:SIMPLE(filecheck=CHECK): -stage compute -entry computeMain -target spirv -O0 -g3 +RWStructuredBuffer<int> outputBuffer; + +// This tests the following use cases: +// Inline single block function in multiple places. +// Inline single block function into multi-block function(This also covers multiple blocks with a phi node.) +// Inline single block function in multiple places in the same function. +// Inline multi-block function into another function +// Inline multi-block function multiple times +// Recursive inlining use case. + +[ForceInline] +int calculateAdjustment(int value) +{ + return value * 3 / 2; +} + +[ForceInline] +int inlineMultipleBasicBlocks(int value) +{ + int result = 0; + + result = value * 2; + result = calculateAdjustment(result); + + // Add another branch to create more basic blocks + if (result > 20) + { + result = result + 25; + } + else + { + result = result + 50; + } + + result = value * 4; + result = calculateAdjustment(result); + + // Add another branch to create more basic blocks + if (result < 20) + { + result = result + 10; + } + + result = value * 10; + result = calculateAdjustment(result); + + if (result < 250) + { + result = result + 100; + } + + return result; +} + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int i = dispatchThreadID.x; + + // Call the forceinline function + int result1 = inlineMultipleBasicBlocks(16); + + int result2 = inlineMultipleBasicBlocks(22); + + int result3 = calculateAdjustment(2); + + outputBuffer[i] = result1 + result2 + result3; +} + +// CHECK-COUNT-3: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugFunction %{{[0-9]+}} %{{[0-9]+}} %{{[0-9]+}} %uint_{{[0-9]+}} %uint_{{[0-9]+}} %{{[0-9]+}} %{{[0-9]+}} %uint_{{[0-9]+}} %uint_{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugFunction %{{[0-9]+}} %{{[0-9]+}} %{{[0-9]+}} %uint_{{[0-9]+}} %uint_{{[0-9]+}} %{{[0-9]+}} %{{[0-9]+}} %uint_{{[0-9]+}} %uint_{{[0-9]+}} + +// TODO: Actual count is 6. But the pattern matcher complains to match. +// CHECK-COUNT-5: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} %{{[0-9]+}} + +// CHECK-COUNT-27: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}}
\ No newline at end of file diff --git a/tests/language-feature/function-calls/forceinline-multiple-cases.slang b/tests/language-feature/function-calls/forceinline-multiple-cases.slang new file mode 100644 index 000000000..3f1cfc0f7 --- /dev/null +++ b/tests/language-feature/function-calls/forceinline-multiple-cases.slang @@ -0,0 +1,141 @@ +//TEST:SIMPLE(filecheck=CHECK): -stage compute -entry computeMain -target spirv -O0 -g3 +RWStructuredBuffer<int> outputBuffer; + +// Function with a single basic block +[ForceInline] +int basicBlockFunc(int value1, int value2) +{ + // Simple operation that should be inlined + return value1 * 2 + value2; +} + +// Function with multiple basic blocks +[ForceInline] +int multipleBlockFunc(int value1, int value2) +{ + int result = value1 * 2; + + // Add a condition to create multiple basic blocks + if (value1 > value2) + { + result += value2 * 3; + } + else + { + result -= value2; + } + + return result; +} + +// Test case a: Multiple calls to basic block function +int testMultipleBasicBlockCalls() +{ + int result = basicBlockFunc(10, 5); + result += basicBlockFunc(20, 15); + result += basicBlockFunc(30, 25); + return result; +} + +// Test case b: Multiple calls to multiple block function +int testMultipleBlockCalls() +{ + int result = multipleBlockFunc(10, 5); + result += multipleBlockFunc(20, 25); + result += multipleBlockFunc(30, 25); + return result; +} + +// Test case c: One call to basic block, other instructions, another call to basic block +int testBasicBlockWithInstructions() +{ + int result = basicBlockFunc(10, 5); + + // Some other instructions + result *= 2; + result += 10; + + result += basicBlockFunc(20, 15); + return result; +} + +// Test case d: One call to multiple block func, other instructions, another call to multiple block func +int testMultipleBlockWithInstructions() +{ + int result = multipleBlockFunc(10, 5); + + // Some other instructions + result *= 2; + result += 10; + + result += multipleBlockFunc(20, 25); + return result; +} + +// Test case e: One call to basic block, other instructions, call to multiple block +int testBasicToMultipleBlock() +{ + int result = basicBlockFunc(10, 5); + + // Some other instructions + result *= 2; + result += 10; + + result += multipleBlockFunc(20, 25); + return result; +} + +// Additional test case: Mixed calls with condition +int testMixedCallsWithCondition() +{ + int result = basicBlockFunc(15, 7); + if (result > 30) + { + result += multipleBlockFunc(8, 3); + } + else + { + result += multipleBlockFunc(12, 9); + } + return result; +} + +[numthreads(8, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + // Call all test functions directly and store results in different indices + + // Test case a: Multiple calls to basic block function + outputBuffer[0] = testMultipleBasicBlockCalls(); + + // Test case b: Multiple calls to multiple block function + outputBuffer[1] = testMultipleBlockCalls(); + + // Test case c: One call to basic block, other instructions, another call to basic block + outputBuffer[2] = testBasicBlockWithInstructions(); + + // Test case d: One call to multiple block func, other instructions, another call to multiple block func + outputBuffer[3] = testMultipleBlockWithInstructions(); + + // Test case e: One call to basic block, other instructions, call to multiple block + outputBuffer[4] = testBasicToMultipleBlock(); + + // Additional test case: Mixed calls with condition + outputBuffer[5] = testMixedCallsWithCondition(); + + // Set any remaining indices to 0 + if (dispatchThreadID.x >= 6) + { + outputBuffer[dispatchThreadID.x] = 0; + } +} + +// CHECK-COUNT-14: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugInlinedAt %uint_{{[0-9]+}} %{{[0-9]+}} +// CHECK-COUNT-28: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}} +// CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugScope %{{[0-9]+}} %{{[0-9]+}} + +// TODO: Verified manually that the count in the .actual file is 28. +// But the pattern matcher complains to match. +// _CHECK-COUNT-28: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugNoScope +// _CHECK-NOT: %{{[0-9]+}} = OpExtInst %void %{{[0-9]+}} DebugNoScope |
