c11_atomics: Filter invalid memory orders for 2 order instructions (#2506)

* OpenCL C (and SPIR-V) require that the failure memory order is not
stronger than the success memory order.

Also see Khronos internal memory model issue #181

CC @bashbaug
This commit is contained in:
alan-baker
2025-11-26 19:25:46 -05:00
committed by GitHub
parent 2174715160
commit d1b75bd200

View File

@@ -702,6 +702,28 @@ public:
cl_context context,
cl_command_queue queue)
{
// Comparator for orders and scopes.
const auto checkValidity = [](TExplicitMemoryOrderType success,
TExplicitMemoryOrderType failure,
TExplicitMemoryScopeType scope) {
// Both memory order arguments must be set (or neither).
if ((success == MEMORY_ORDER_EMPTY || failure == MEMORY_ORDER_EMPTY)
&& success != failure)
return false;
// Memory scope without memory order is disallowed.
if (success == MEMORY_ORDER_EMPTY && scope != MEMORY_SCOPE_EMPTY)
return false;
// Failure must not be release or acq_rel.
if (failure == MEMORY_ORDER_RELEASE
|| failure == MEMORY_ORDER_ACQ_REL)
return false;
// Failure must not be stronger than success.
return failure <= success;
};
// repeat test for each reasonable memory order/scope combination
std::vector<TExplicitMemoryOrderType> memoryOrder;
std::vector<TExplicitMemoryScopeType> memoryScope;
@@ -719,16 +741,10 @@ public:
{
for (unsigned si = 0; si < memoryScope.size(); si++)
{
if ((memoryOrder[oi] == MEMORY_ORDER_EMPTY
|| memoryOrder[o2i] == MEMORY_ORDER_EMPTY)
&& memoryOrder[oi] != memoryOrder[o2i])
continue; // both memory order arguments must be set (or
// none)
if ((memoryOrder[oi] == MEMORY_ORDER_EMPTY
|| memoryOrder[o2i] == MEMORY_ORDER_EMPTY)
&& memoryScope[si] != MEMORY_SCOPE_EMPTY)
continue; // memory scope without memory order is not
// allowed
if (!checkValidity(memoryOrder[oi], memoryOrder[o2i],
memoryScope[si]))
continue;
MemoryOrder(memoryOrder[oi]);
MemoryOrder2(memoryOrder[o2i]);
MemoryScope(memoryScope[si]);