SPV OpAtomicCompareSwap: Generate correct operand order and number of operands.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 37ee52f..3dffceb 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2526,14 +2526,21 @@
// Sort out the operands
// - mapping from glslang -> SPV
// - there are extra SPV operands with no glslang source
+ // - compare-exchange swaps the value and comparator
+ // - compare-exchange has an extra memory semantics
std::vector<spv::Id> spvAtomicOperands; // hold the spv operands
auto opIt = operands.begin(); // walk the glslang operands
spvAtomicOperands.push_back(*(opIt++));
spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope?
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics?
+ if (opCode == spv::OpAtomicCompareExchange) {
+ spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics?
+ spvAtomicOperands.push_back(*(opIt + 1));
+ spvAtomicOperands.push_back(*opIt);
+ opIt += 2;
+ }
- // Add the rest of the operands, skipping the first one, which was dealt with above.
- // For some ops, there are none, for some 1, for compare-exchange, 2.
+ // Add the rest of the operands, skipping any that were dealt with above.
for (; opIt != operands.end(); ++opIt)
spvAtomicOperands.push_back(*opIt);