@@ -10462,7 +10462,8 @@ GlobOpt::TypeSpecializeBinary(IR::Instr **pInstr, Value **pSrc1Val, Value **pSrc
1046210462
1046310463 // Type specialize binary operators to int32
1046410464
10465- bool lossy = true;
10465+ bool src1Lossy = true;
10466+ bool src2Lossy = true;
1046610467 IR::BailOutKind bailOutKind = IR::BailOutInvalid;
1046710468 bool ignoredIntOverflow = this->ignoredIntOverflowForCurrentInstr;
1046810469 bool ignoredNegativeZero = false;
@@ -10746,7 +10747,8 @@ GlobOpt::TypeSpecializeBinary(IR::Instr **pInstr, Value **pSrc1Val, Value **pSrc
1074610747 bailOutKind = IR::BailOutOnDivOfMinInt;
1074710748 }
1074810749
10749- lossy = false; // Detect -0 on the sources
10750+ src1Lossy = false; // Detect -0 on the sources
10751+ src2Lossy = false;
1075010752
1075110753 opcode = Js::OpCode::Div_I4;
1075210754 bailOutKind |= IR::BailOnDivResultNotInt;
@@ -10969,10 +10971,13 @@ GlobOpt::TypeSpecializeBinary(IR::Instr **pInstr, Value **pSrc1Val, Value **pSrc
1096910971 // If one of the values is a float constant with a value that fits in a uint32 but not an int32,
1097010972 // and the instruction can ignore int overflow, the source value for the purposes of int specialization
1097110973 // would have been changed to an int constant value by ignoring overflow. But, the conversion is still lossy.
10972- if (!(src1OriginalVal && src1OriginalVal->GetValueInfo()->IsFloatConstant() && src1Val && src1Val->GetValueInfo()->HasIntConstantValue()) &&
10973- !(src2OriginalVal && src2OriginalVal->GetValueInfo()->IsFloatConstant() && src2Val && src2Val->GetValueInfo()->HasIntConstantValue()))
10974+ if (!(src1OriginalVal && src1OriginalVal->GetValueInfo()->IsFloatConstant() && src1Val && src1Val->GetValueInfo()->HasIntConstantValue()))
1097410975 {
10975- lossy = false;
10976+ src1Lossy = false;
10977+ }
10978+ if (!(src2OriginalVal && src2OriginalVal->GetValueInfo()->IsFloatConstant() && src2Val && src2Val->GetValueInfo()->HasIntConstantValue()))
10979+ {
10980+ src2Lossy = false;
1097610981 }
1097710982
1097810983 switch(instr->m_opcode)
@@ -11740,26 +11745,29 @@ GlobOpt::TypeSpecializeBinary(IR::Instr **pInstr, Value **pSrc1Val, Value **pSrc
1174011745 }
1174111746
1174211747 Value *src1ValueToSpecialize = src1Val, *src2ValueToSpecialize = src2Val;
11743- if(lossy)
11748+ // Lossy conversions to int32 must be done based on the original source values. For instance, if one of the values is a
11749+ // float constant with a value that fits in a uint32 but not an int32, and the instruction can ignore int overflow, the
11750+ // source value for the purposes of int specialization would have been changed to an int constant value by ignoring
11751+ // overflow. If we were to specialize the sym using the int constant value, it would be treated as a lossless
11752+ // conversion, but since there may be subsequent uses of the same float constant value that may not ignore overflow,
11753+ // this must be treated as a lossy conversion by specializing the sym using the original float constant value.
11754+ if(src1Lossy)
1174411755 {
11745- // Lossy conversions to int32 must be done based on the original source values. For instance, if one of the values is a
11746- // float constant with a value that fits in a uint32 but not an int32, and the instruction can ignore int overflow, the
11747- // source value for the purposes of int specialization would have been changed to an int constant value by ignoring
11748- // overflow. If we were to specialize the sym using the int constant value, it would be treated as a lossless
11749- // conversion, but since there may be subsequent uses of the same float constant value that may not ignore overflow,
11750- // this must be treated as a lossy conversion by specializing the sym using the original float constant value.
1175111756 src1ValueToSpecialize = src1OriginalVal;
11757+ }
11758+ if (src2Lossy)
11759+ {
1175211760 src2ValueToSpecialize = src2OriginalVal;
1175311761 }
1175411762
1175511763 // Make sure the srcs are specialized
1175611764 src1 = instr->GetSrc1();
11757- this->ToInt32(instr, src1, this->currentBlock, src1ValueToSpecialize, nullptr, lossy );
11765+ this->ToInt32(instr, src1, this->currentBlock, src1ValueToSpecialize, nullptr, src1Lossy );
1175811766
1175911767 if (!skipSrc2)
1176011768 {
1176111769 src2 = instr->GetSrc2();
11762- this->ToInt32(instr, src2, this->currentBlock, src2ValueToSpecialize, nullptr, lossy );
11770+ this->ToInt32(instr, src2, this->currentBlock, src2ValueToSpecialize, nullptr, src2Lossy );
1176311771 }
1176411772
1176511773 if(bailOutKind != IR::BailOutInvalid && !this->IsLoopPrePass())
0 commit comments