Index: src/IceIntrinsics.cpp |
diff --git a/src/IceIntrinsics.cpp b/src/IceIntrinsics.cpp |
index 26a81dea7eaa10b5836e1aac95d29011c9396db9..2d2501133f81baf8622544ec10dc799c98cb0dfb 100644 |
--- a/src/IceIntrinsics.cpp |
+++ b/src/IceIntrinsics.cpp |
@@ -233,9 +233,70 @@ const Intrinsics::FullIntrinsicInfo *Intrinsics::find(const IceString &Name, |
return &it->second; |
} |
-bool Intrinsics::VerifyMemoryOrder(uint64_t Order) { |
- // There is only one memory ordering for atomics allowed right now. |
- return Order == Intrinsics::MemoryOrderSequentiallyConsistent; |
+namespace { |
+ |
+// Returns whether PNaCl allows the given memory ordering in general. |
+bool isMemoryOrderValidPNaCl(uint64_t Order) { |
+ switch (Order) { |
+ case Intrinsics::MemoryOrderAcquire: |
+ case Intrinsics::MemoryOrderRelease: |
+ case Intrinsics::MemoryOrderAcquireRelease: |
+ case Intrinsics::MemoryOrderSequentiallyConsistent: |
+ return true; |
+ default: |
+ return false; |
+ } |
+} |
+ |
+} // end of anonymous namespace |
+ |
+bool Intrinsics::isMemoryOrderValid(IntrinsicID ID, uint64_t Order, |
+ uint64_t OrderOther) { |
+ // Reject orderings not allowed in PNaCl. |
+ if (!isMemoryOrderValidPNaCl(Order)) |
+ return false; |
+ if (ID == AtomicCmpxchg && !isMemoryOrderValidPNaCl(OrderOther)) |
+ return false; |
+ // Reject orderings not allowed by C++11. |
+ switch (ID) { |
+ default: |
+ llvm_unreachable("isMemoryOrderValid: Unknown IntrinsicID"); |
+ return false; |
+ case AtomicFence: |
+ case AtomicFenceAll: |
+ case AtomicRMW: |
+ return true; |
+ case AtomicCmpxchg: |
+ // Reject orderings that are invalid combinations for cmpxchg. |
+ switch (OrderOther) { |
+ case MemoryOrderAcquire: |
+ case MemoryOrderSequentiallyConsistent: |
JF
2015/03/18 06:26:30
This is wrong, order can also be relaxed or consum
Jim Stichnoth
2015/03/18 13:50:15
But but, that's covered by the isMemoryOrderValidP
|
+ if (OrderOther > Order) |
+ return false; |
+ if (Order == MemoryOrderRelease && OrderOther != MemoryOrderRelaxed) |
+ return false; |
+ return true; |
+ default: |
+ return false; |
+ } |
+ case AtomicLoad: |
+ switch (Order) { |
+ case MemoryOrderRelease: |
+ case MemoryOrderAcquireRelease: |
+ return false; |
+ default: |
+ return true; |
+ } |
+ case AtomicStore: |
+ switch (Order) { |
+ case MemoryOrderConsume: |
+ case MemoryOrderAcquire: |
+ case MemoryOrderAcquireRelease: |
+ return false; |
+ default: |
+ return true; |
+ } |
+ } |
} |
Intrinsics::ValidateCallValue |