From 46eae8cf2f2f60b406ec462add6954ba502c639f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 1 Apr 2019 19:51:45 -0400 Subject: [PATCH 1/2] common/fp/op/FPRecipExponent: Prevent undefined behavior from shifting a negative value Due to promotion rules (types < int, even if unsigned, get promoted to int when arithmetic is performed on them), this is a potential spot for undefined behavior. --- src/common/fp/op/FPRecipExponent.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/fp/op/FPRecipExponent.cpp b/src/common/fp/op/FPRecipExponent.cpp index 4e0224e7..eafad6a9 100644 --- a/src/common/fp/op/FPRecipExponent.cpp +++ b/src/common/fp/op/FPRecipExponent.cpp @@ -48,8 +48,9 @@ FPT FPRecipExponent(FPT op, FPCR fpcr, FPSR& fpsr) { } // Infinities and normals - const auto negated_exponent = (~exponent << FPInfo::explicit_mantissa_width) & FPInfo::exponent_mask; - return FPT(sign_bits | negated_exponent); + const FPT negated_exponent = FPT(~exponent); + const FPT adjusted_exponent = FPT(negated_exponent << FPInfo::explicit_mantissa_width) & FPInfo::exponent_mask; + return FPT(sign_bits | adjusted_exponent); } template u16 FPRecipExponent(u16 op, FPCR fpcr, FPSR& fpsr); From b37279f65ca3bcd34db9cdb3ecab27dcd1bda77b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 1 Apr 2019 19:53:46 -0400 Subject: [PATCH 2/2] backend/x64/emit_x64_vector: Prevent undefined behavior within VectorSignedSaturatedShiftLeft Avoids undefined behavior by potentially left-shifting a signed negative value. --- src/backend/x64/emit_x64_vector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/x64/emit_x64_vector.cpp b/src/backend/x64/emit_x64_vector.cpp index a519cd09..03d47af0 100644 --- a/src/backend/x64/emit_x64_vector.cpp +++ b/src/backend/x64/emit_x64_vector.cpp @@ -3838,7 +3838,7 @@ static bool VectorSignedSaturatedShiftLeft(VectorArray& dst, const VectorArra dst[i] = saturate(element); qc_flag = true; } else { - const T shifted = element << shift; + const T shifted = T(U(element) << shift); if ((shifted >> shift) != element) { dst[i] = saturate(element);