Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 069fd96

Browse files
authored
Merge pull request #231 from juj/workaround_ios_9_right_shift_zero_bug
Add a workaround for Safari 9 ARM iOS right shift by non-immediate zero JIT bug
2 parents 49340ac + 0f7dc7d commit 069fd96

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

lib/Target/JSBackend/JSBackend.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,18 @@ EnableCyberDWARFIntrinsics("enable-debug-intrinsics",
165165
cl::desc("Include debug intrinsics in generated output"),
166166
cl::init(false));
167167

168+
// Work around Safari/WebKit bug in iOS 9.3.5: https://bugs.webkit.org/show_bug.cgi?id=151514 where computing "a >> b" or "a >>> b" in JavaScript would erroneously
169+
// output 0 when a!=0 and b==0, after suitable JIT compiler optimizations have been applied to a function at runtime (bug does not occur in debug builds).
170+
// Fix was landed in https://trac.webkit.org/changeset/196591/webkit on Feb 15th 2016. iOS 9.3.5 was released on August 25 2016, but oddly did not have the fix.
171+
// iOS Safari 10.3.3 was released on July 19 2017, that no longer has the issue. Unknown which released version between these was the first to contain the patch,
172+
// though notable is that iOS 9.3.5 and iOS 10.3.3 are the two consecutive "end-of-life" versions of iOS that users are likely to be on, e.g.
173+
// iPhone 4s, iPad 2, iPad 3, iPad Mini 1, Pod Touch 5 all had end-of-life at iOS 9.3.5 (tested to be affected),
174+
// and iPad 4, iPhone 5 and iPhone 5c had end-of-life at iOS 10.3.3 (confirmed not affected)
175+
static cl::opt<bool>
176+
WorkAroundIos9RightShiftByZeroBug("emscripten-asmjs-work-around-ios-9-right-shift-bug",
177+
cl::desc("Enables codegen to guard against broken right shift by (non-immediate) zero on WebKit/Safari 9 on ARM iOS 9.3.5 (iPhone 4s and older)"),
178+
cl::init(false));
179+
168180
static cl::opt<bool>
169181
WebAssembly("emscripten-wasm",
170182
cl::desc("Generate asm.js which will later be compiled to WebAssembly (see emscripten BINARYEN setting)"),
@@ -2661,7 +2673,12 @@ void JSWriter::generateExpression(const User *I, raw_string_ostream& Code) {
26612673
if (I->getType()->getIntegerBitWidth() < 32) {
26622674
Input = '(' + getCast(Input, I->getType(), opcode == Instruction::AShr ? ASM_SIGNED : ASM_UNSIGNED) + ')'; // fill in high bits, as shift needs those and is done in 32-bit
26632675
}
2664-
Code << Input << (opcode == Instruction::AShr ? " >> " : " >>> ") << getValueAsStr(I->getOperand(1));
2676+
std::string shift = getValueAsStr(I->getOperand(1));
2677+
if (WorkAroundIos9RightShiftByZeroBug) {
2678+
Code << '(' << shift << ")?(" << Input << (opcode == Instruction::AShr ? " >> " : " >>> ") << shift << "):(" << Input << ')';
2679+
} else {
2680+
Code << Input << (opcode == Instruction::AShr ? " >> " : " >>> ") << shift;
2681+
}
26652682
break;
26662683
}
26672684

0 commit comments

Comments
 (0)