diff --git a/emscripten-version.txt b/emscripten-version.txt index fb1348a3e91..2286388304d 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.29.3 +1.29.4 diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index bc78c3f8e27..5c468f16863 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -2536,7 +2536,9 @@ void JSWriter::printModuleBody() { } else { Out << ", "; } - Out << "\"_" << I->getName() << '"'; + std::string name = I->getName(); + sanitizeGlobal(name); + Out << "\"" << name << '"'; } } Out << "],"; diff --git a/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp b/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp index 0fb248668d3..0e06051628b 100644 --- a/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp +++ b/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp @@ -64,6 +64,14 @@ static uint64_t UintTypeMax(unsigned Bits) { return (((uint64_t) 1) << Bits) - 1; } +static int64_t SintTypeMax(unsigned Bits) { + return (((int64_t) 1) << (Bits-1)) - 1; +} + +static int64_t SintTypeMin(unsigned Bits) { + return -(((int64_t) 1) << (Bits-1)); +} + static Value *CreateInsertValue(Value *StructVal, unsigned Index, Value *Field, Instruction *BasedOn) { SmallVector EVIndexes; @@ -73,12 +81,18 @@ static Value *CreateInsertValue(Value *StructVal, unsigned Index, BasedOn->getName() + ".insert", BasedOn), BasedOn); } -static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) { +static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul, bool Signed) { IntegerType *IntTy = IntegerType::get(M->getContext(), Bits); SmallVector Types; Types.push_back(IntTy); - Intrinsic::ID ID = (Mul ? Intrinsic::umul_with_overflow - : Intrinsic::uadd_with_overflow); + Intrinsic::ID ID; + if (!Signed) { + ID = (Mul ? Intrinsic::umul_with_overflow + : Intrinsic::uadd_with_overflow); + } else { + ID = (Mul ? Intrinsic::smul_with_overflow + : Intrinsic::sadd_with_overflow); + } std::string Name = Intrinsic::getName(ID, Types); Function *Intrinsic = M->getFunction(Name); if (!Intrinsic) @@ -114,7 +128,7 @@ static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) { Value *ArithResult, *OverflowResult; - if (!VariableArg2) { + if (!VariableArg2 && !Signed) { ArithResult = BinaryOperator::Create( (Mul ? Instruction::Mul : Instruction::Add), VariableArg, ConstantArg, Call->getName() + ".arith", Call); @@ -130,13 +144,40 @@ static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) { Call->getName() + ".overflow"); } else { // XXX EMSCRIPTEN: generalize this to nonconstant values, easy for addition + // also for signed values + assert(!Mul); + if (!VariableArg2) VariableArg2 = ConstantArg; ArithResult = BinaryOperator::Create(Instruction::Add, VariableArg, VariableArg2, Call->getName() + ".arith", Call); - // If x+y < x (or y), unsigned 32 addition, then an overflow occurred - OverflowResult = new ICmpInst( - Call, CmpInst::ICMP_ULT, ArithResult, VariableArg, - Call->getName() + ".overflow"); + if (!Signed) { + // If x+y < x (or y), unsigned 32 addition, then an overflow occurred + OverflowResult = new ICmpInst( + Call, CmpInst::ICMP_ULT, ArithResult, VariableArg, + Call->getName() + ".overflow"); + } else { + // In the signed case, we care if the sum is >127 or <-128. When looked at + // as an unsigned number, that is precisely when the sum is >= 128 + Value *PositiveTemp = BinaryOperator::Create(Instruction::Add, + VariableArg, ConstantInt::get(IntTy, SintTypeMin(Bits)), + Call->getName() + ".postemp", Call); + Value *NegativeTemp = BinaryOperator::Create(Instruction::Add, + VariableArg, ConstantInt::get(IntTy, SintTypeMax(Bits)), + Call->getName() + ".negtemp", Call); + Value *PositiveCheck = new ICmpInst( + Call, CmpInst::ICMP_SLT, ArithResult, PositiveTemp, + Call->getName() + ".poscheck"); + Value *NegativeCheck = new ICmpInst( + Call, CmpInst::ICMP_SGT, ArithResult, NegativeTemp, + Call->getName() + ".negcheck"); + Value *IsPositive = new ICmpInst( + Call, CmpInst::ICMP_SGT, VariableArg, ConstantInt::get(IntTy, 0), + Call->getName() + ".ispos"); + OverflowResult = SelectInst::Create( + IsPositive, PositiveCheck, NegativeCheck, + Call->getName() + ".select", + Call); + } } // Construct the struct result. @@ -153,8 +194,9 @@ static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) { static bool ExpandForIntSize(Module *M, unsigned Bits) { bool Modified = false; - Modified |= ExpandOpForIntSize(M, Bits, true); // Expand umul - Modified |= ExpandOpForIntSize(M, Bits, false); // Expand uadd + Modified |= ExpandOpForIntSize(M, Bits, true, false); // Expand umul + Modified |= ExpandOpForIntSize(M, Bits, false, false); // Expand uadd + Modified |= ExpandOpForIntSize(M, Bits, false, true); // Expand sadd (for ubsan) XXX EMSCRIPTEN return Modified; }