@@ -1882,7 +1882,22 @@ void Legalization::visitIntrinsicInst(llvm::IntrinsicInst& I)
1882
1882
auto zero = ConstantInt::get (src0->getType (), 0 , true );
1883
1883
// Signed a - b overflows if the sign of a and -b are the same, but diffrent from the result
1884
1884
// Signed a + b overflows if the sign of a and b are the same, but diffrent from the result
1885
- isOverflow = CmpInst::Create (Instruction::ICmp, CmpInst::ICMP_SLT, andOpt, zero, " " , &I);
1885
+ if (src0->getType ()->getIntegerBitWidth () == 8 &&
1886
+ !m_ctx->platform .supportByteALUOperation ())
1887
+ {
1888
+ // The promotion char->short is breaking the current logic for overflow algorithm.
1889
+ // For ex. in PVC we are losing the sign bit here, if we are operating on signed char.
1890
+ // In first half of the short (the original char) we still have the correct sign bit -
1891
+ // so we are checking if original char has sign bit light-on.
1892
+ auto charSignBit = ConstantInt::get (Builder.getInt8Ty (), 1 << 7 , true );
1893
+ andOpt = BinaryOperator::CreateAnd (andOpt, charSignBit, " " , &I);
1894
+ andOpt->setDebugLoc (I.getDebugLoc ());
1895
+ isOverflow = CmpInst::Create (Instruction::ICmp, CmpInst::ICMP_NE, andOpt, zero, " " , &I);
1896
+ }
1897
+ else
1898
+ {
1899
+ isOverflow = CmpInst::Create (Instruction::ICmp, CmpInst::ICMP_SLT, andOpt, zero, " " , &I);
1900
+ }
1886
1901
}
1887
1902
break ;
1888
1903
case Intrinsic::umul_with_overflow:
0 commit comments