@@ -1882,7 +1882,22 @@ void Legalization::visitIntrinsicInst(llvm::IntrinsicInst& I)
18821882 auto zero = ConstantInt::get (src0->getType (), 0 , true );
18831883 // Signed a - b overflows if the sign of a and -b are the same, but diffrent from the result
18841884 // 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+ }
18861901 }
18871902 break ;
18881903 case Intrinsic::umul_with_overflow:
0 commit comments