[clang] 33bae9c - [AST] Fix handling of some edge cases in fixed-point division.
Bevin Hansson via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 30 04:47:53 PDT 2020
Author: Bevin Hansson
Date: 2020-06-30T13:47:12+02:00
New Revision: 33bae9c265486cd37e0612711a863f0a4b865a26
URL: https://github.com/llvm/llvm-project/commit/33bae9c265486cd37e0612711a863f0a4b865a26
DIFF: https://github.com/llvm/llvm-project/commit/33bae9c265486cd37e0612711a863f0a4b865a26.diff
LOG: [AST] Fix handling of some edge cases in fixed-point division.
Division by zero was not being handled, and division of
-EPSILON / MAX did not perform rounding correctly.
Added:
Modified:
clang/lib/AST/ExprConstant.cpp
clang/lib/Basic/FixedPoint.cpp
clang/test/Frontend/fixed_point_div.c
clang/test/Frontend/fixed_point_errors.c
Removed:
################################################################################
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index ebe09c99429f..9eba40c44ddc 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -12954,6 +12954,10 @@ bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
break;
}
case BO_Div: {
+ if (RHSFX.getValue() == 0) {
+ Info.FFDiag(E, diag::note_expr_divide_by_zero);
+ return false;
+ }
Result = LHSFX.div(RHSFX, &OpOverflow)
.convert(ResultFXSema, &ConversionOverflow);
break;
diff --git a/clang/lib/Basic/FixedPoint.cpp b/clang/lib/Basic/FixedPoint.cpp
index e8db43c6fe90..ed8b92c98fdb 100644
--- a/clang/lib/Basic/FixedPoint.cpp
+++ b/clang/lib/Basic/FixedPoint.cpp
@@ -282,7 +282,7 @@ APFixedPoint APFixedPoint::div(const APFixedPoint &Other,
llvm::APInt::sdivrem(ThisVal, OtherVal, Result, Rem);
// If the quotient is negative and the remainder is nonzero, round
// towards negative infinity by subtracting epsilon from the result.
- if (Result.isNegative() && !Rem.isNullValue())
+ if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isNullValue())
Result = Result - 1;
} else
Result = ThisVal.udiv(OtherVal);
diff --git a/clang/test/Frontend/fixed_point_div.c b/clang/test/Frontend/fixed_point_div.c
index ce1e02387de1..b18ba59ae735 100644
--- a/clang/test/Frontend/fixed_point_div.c
+++ b/clang/test/Frontend/fixed_point_div.c
@@ -64,6 +64,8 @@ short _Accum sa_const13 = 0.0234375hk / 2.0hk;
// CHECK-DAG: @sa_const13 = {{.*}}global i16 1, align 2
short _Accum sa_const14 = -0.0234375hk / 2.0hk;
// CHECK-DAG: @sa_const14 = {{.*}}global i16 -2, align 2
+short _Accum sa_const15 = -0.0078125hk / 255.28125hk;
+// CHECK-DAG: @sa_const15 = {{.*}}global i16 -1, align 2
void SignedDivision() {
// CHECK-LABEL: SignedDivision
diff --git a/clang/test/Frontend/fixed_point_errors.c b/clang/test/Frontend/fixed_point_errors.c
index c1d80d5daf46..2fd8cfd1fdf7 100644
--- a/clang/test/Frontend/fixed_point_errors.c
+++ b/clang/test/Frontend/fixed_point_errors.c
@@ -264,3 +264,6 @@ short _Fract add_sat = (_Sat short _Fract)0.5hr + 0.5hr;
short _Accum sub_sat = (_Sat short _Accum)-200.0hk - 80.0hk;
short _Accum mul_sat = (_Sat short _Accum)80.0hk * 10.0hk;
short _Fract div_sat = (_Sat short _Fract)0.9hr / 0.1hr;
+
+// Division by zero
+short _Accum div_zero = 4.5k / 0.0lr; // expected-error {{initializer element is not a compile-time constant}}
More information about the cfe-commits
mailing list