Skip to content

Commit f6b40e7

Browse files
spirv-val: Add Vulkan Aligned PowerOfTwo check (KhronosGroup#6027)
1 parent fb80331 commit f6b40e7

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

source/val/validate_memory.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,16 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
380380
<< _.VkErrorID(4708)
381381
<< "Memory accesses with PhysicalStorageBuffer must use Aligned.";
382382
}
383+
} else {
384+
// even if there are other masks, the Aligned operand will be next
385+
const uint32_t aligned_value = inst->GetOperandAs<uint32_t>(index + 1);
386+
const bool is_power_of_two =
387+
aligned_value && !(aligned_value & (aligned_value - 1));
388+
if (!is_power_of_two) {
389+
return _.diag(SPV_ERROR_INVALID_ID, inst)
390+
<< "Memory accesses Aligned operand value " << aligned_value
391+
<< " is not a power of two.";
392+
}
383393
}
384394

385395
return SPV_SUCCESS;

test/val/val_id_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5764,7 +5764,7 @@ TEST_P(ValidateIdWithMessage,
57645764
%2 = OpFunction %8 None %11
57655765
%4 = OpFunctionParameter %10
57665766
%15 = OpLabel
5767-
%16 = OpLoad %6 %3 Aligned 0
5767+
%16 = OpLoad %6 %3 Aligned 1
57685768
%17 = OpCompositeExtract %5 %16 0
57695769
%18 = OpInBoundsPtrAccessChain %13 %4 %17 %12
57705770
OpStore %18 %14 Aligned 4
@@ -5798,7 +5798,7 @@ TEST_P(ValidateIdWithMessage, OpPtrAccessChainGood) {
57985798
%2 = OpFunction %8 None %12
57995799
%4 = OpFunctionParameter %11
58005800
%17 = OpLabel
5801-
%18 = OpLoad %6 %3 Aligned 0
5801+
%18 = OpLoad %6 %3 Aligned 1
58025802
%19 = OpCompositeExtract %5 %18 0
58035803
%20 = OpBitwiseAnd %5 %19 %13
58045804
%21 = OpPtrAccessChain %15 %4 %20 %14

test/val/val_memory_test.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,68 @@ OpFunctionEnd
18181818
HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
18191819
}
18201820

1821+
TEST_F(ValidateMemory, PSBStoreAlignedZero) {
1822+
const std::string body = R"(
1823+
OpCapability PhysicalStorageBufferAddresses
1824+
OpCapability Shader
1825+
OpExtension "SPV_EXT_physical_storage_buffer"
1826+
OpMemoryModel PhysicalStorageBuffer64 GLSL450
1827+
OpEntryPoint Fragment %main "main"
1828+
OpExecutionMode %main OriginUpperLeft
1829+
%uint = OpTypeInt 32 0
1830+
%uint_1 = OpConstant %uint 1
1831+
%ptr = OpTypePointer PhysicalStorageBuffer %uint
1832+
%pptr_f = OpTypePointer Function %ptr
1833+
%void = OpTypeVoid
1834+
%voidfn = OpTypeFunction %void
1835+
%main = OpFunction %void None %voidfn
1836+
%entry = OpLabel
1837+
%val1 = OpVariable %pptr_f Function
1838+
%val2 = OpLoad %ptr %val1
1839+
OpStore %val2 %uint_1 Aligned 0
1840+
OpReturn
1841+
OpFunctionEnd
1842+
)";
1843+
1844+
CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1845+
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1846+
EXPECT_THAT(
1847+
getDiagnosticString(),
1848+
HasSubstr(
1849+
"Memory accesses Aligned operand value 0 is not a power of two"));
1850+
}
1851+
1852+
TEST_F(ValidateMemory, PSBStoreAlignedNonPoT) {
1853+
const std::string body = R"(
1854+
OpCapability PhysicalStorageBufferAddresses
1855+
OpCapability Shader
1856+
OpExtension "SPV_EXT_physical_storage_buffer"
1857+
OpMemoryModel PhysicalStorageBuffer64 GLSL450
1858+
OpEntryPoint Fragment %main "main"
1859+
OpExecutionMode %main OriginUpperLeft
1860+
%uint = OpTypeInt 32 0
1861+
%uint_1 = OpConstant %uint 1
1862+
%ptr = OpTypePointer PhysicalStorageBuffer %uint
1863+
%pptr_f = OpTypePointer Function %ptr
1864+
%void = OpTypeVoid
1865+
%voidfn = OpTypeFunction %void
1866+
%main = OpFunction %void None %voidfn
1867+
%entry = OpLabel
1868+
%val1 = OpVariable %pptr_f Function
1869+
%val2 = OpLoad %ptr %val1
1870+
OpStore %val2 %uint_1 Aligned 3
1871+
OpReturn
1872+
OpFunctionEnd
1873+
)";
1874+
1875+
CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1876+
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1877+
EXPECT_THAT(
1878+
getDiagnosticString(),
1879+
HasSubstr(
1880+
"Memory accesses Aligned operand value 3 is not a power of two."));
1881+
}
1882+
18211883
TEST_F(ValidateMemory, PSBCopyMemoryAlignedSuccess) {
18221884
const std::string body = R"(
18231885
OpCapability PhysicalStorageBufferAddresses

0 commit comments

Comments
 (0)