Modified: trunk/Source/_javascript_Core/ChangeLog (214907 => 214908)
--- trunk/Source/_javascript_Core/ChangeLog 2017-04-04 22:30:04 UTC (rev 214907)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-04-04 22:37:51 UTC (rev 214908)
@@ -1,3 +1,22 @@
+2017-04-04 Filip Pizlo <[email protected]>
+
+ B3::LowerToAir incorrectly selects BitXor(AtomicStrongCAS(...), $1)
+ https://bugs.webkit.org/show_bug.cgi?id=169867
+
+ Reviewed by Saam Barati.
+
+ The BitXor(AtomicWeakCAS(...), $1) optimization makes a lot of sense because we an fold the
+ BitXor into the CAS condition read-out. But there is no version of this that is profitable or
+ correct for AtomicStrongCAS. The inversion case is handled by Equal(AtomicStrongCAS(...), ...)
+ becoming NotEqual(AtomicStrongCAS(...), ...), and we alraedy handle that separately.
+
+ So, the fix here is to make the BitXor CAS pattern only recognize AtomicWeakCAS.
+
+ * b3/B3LowerToAir.cpp:
+ (JSC::B3::Air::LowerToAir::lower):
+ * b3/testb3.cpp:
+ (JSC::B3::testAtomicStrongCAS):
+
2017-04-04 Saam Barati <[email protected]>
WebAssembly: JSWebAssemblyCallee should not be a JSCell
Modified: trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp (214907 => 214908)
--- trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp 2017-04-04 22:30:04 UTC (rev 214907)
+++ trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp 2017-04-04 22:37:51 UTC (rev 214908)
@@ -2597,10 +2597,8 @@
// This pattern is super useful on both x86 and ARM64, since the inversion of the CAS result
// can be done with zero cost on x86 (just flip the set from E to NE) and it's a progression
// on ARM64 (since STX returns 0 on success, so ordinarily we have to flip it).
- // FIXME: This looks wrong for AtomicStrongCAS
- // https://bugs.webkit.org/show_bug.cgi?id=169867
if (m_value->child(1)->isInt(1)
- && isAtomicCAS(m_value->child(0)->opcode())
+ && m_value->child(0)->opcode() == AtomicWeakCAS
&& canBeInternal(m_value->child(0))) {
commitInternal(m_value->child(0));
appendCAS(m_value->child(0), true);
Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (214907 => 214908)
--- trunk/Source/_javascript_Core/b3/testb3.cpp 2017-04-04 22:30:04 UTC (rev 214907)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp 2017-04-04 22:37:51 UTC (rev 214908)
@@ -14871,11 +14871,47 @@
}
{
+ // Test for https://bugs.webkit.org/show_bug.cgi?id=169867.
+
Procedure proc;
BasicBlock* root = proc.addBlock();
root->appendNew<Value>(
proc, Return, Origin(),
root->appendNew<Value>(
+ proc, BitXor, Origin(),
+ root->appendNew<AtomicValue>(
+ proc, AtomicStrongCAS, Origin(), width,
+ root->appendIntConstant(proc, Origin(), type, 42),
+ root->appendIntConstant(proc, Origin(), type, 0xbeef),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
+ root->appendIntConstant(proc, Origin(), type, 1)));
+
+ typename NativeTraits<T>::CanonicalType _one_ = 1;
+
+ auto code = compileProc(proc);
+ T value[2];
+ value[0] = 42;
+ value[1] = 13;
+ CHECK_EQ(invoke<typename NativeTraits<T>::CanonicalType>(*code, value), 42 ^ one);
+ CHECK_EQ(value[0], static_cast<T>(0xbeef));
+ CHECK_EQ(value[1], 13);
+ value[0] = static_cast<T>(300);
+ CHECK_EQ(invoke<typename NativeTraits<T>::CanonicalType>(*code, value), static_cast<typename NativeTraits<T>::CanonicalType>(static_cast<T>(300)) ^ one);
+ CHECK_EQ(value[0], static_cast<T>(300));
+ CHECK_EQ(value[1], 13);
+ value[0] = static_cast<T>(-1);
+ CHECK_EQ(invoke<typename NativeTraits<T>::CanonicalType>(*code, value), static_cast<typename NativeTraits<T>::CanonicalType>(static_cast<T>(-1)) ^ one);
+ CHECK_EQ(value[0], static_cast<T>(-1));
+ CHECK_EQ(value[1], 13);
+ checkMyDisassembly(*code, true);
+ }
+
+ {
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ root->appendNew<Value>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
proc, Equal, Origin(),
root->appendNew<AtomicValue>(
proc, AtomicStrongCAS, Origin(), width,