Skip to content

Commit 33bae9c

Browse files
committed
[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.
1 parent 80eb422 commit 33bae9c

File tree

4 files changed

+10
-1
lines changed

4 files changed

+10
-1
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12954,6 +12954,10 @@ bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1295412954
break;
1295512955
}
1295612956
case BO_Div: {
12957+
if (RHSFX.getValue() == 0) {
12958+
Info.FFDiag(E, diag::note_expr_divide_by_zero);
12959+
return false;
12960+
}
1295712961
Result = LHSFX.div(RHSFX, &OpOverflow)
1295812962
.convert(ResultFXSema, &ConversionOverflow);
1295912963
break;

clang/lib/Basic/FixedPoint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ APFixedPoint APFixedPoint::div(const APFixedPoint &Other,
282282
llvm::APInt::sdivrem(ThisVal, OtherVal, Result, Rem);
283283
// If the quotient is negative and the remainder is nonzero, round
284284
// towards negative infinity by subtracting epsilon from the result.
285-
if (Result.isNegative() && !Rem.isNullValue())
285+
if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isNullValue())
286286
Result = Result - 1;
287287
} else
288288
Result = ThisVal.udiv(OtherVal);

clang/test/Frontend/fixed_point_div.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ short _Accum sa_const13 = 0.0234375hk / 2.0hk;
6464
// CHECK-DAG: @sa_const13 = {{.*}}global i16 1, align 2
6565
short _Accum sa_const14 = -0.0234375hk / 2.0hk;
6666
// CHECK-DAG: @sa_const14 = {{.*}}global i16 -2, align 2
67+
short _Accum sa_const15 = -0.0078125hk / 255.28125hk;
68+
// CHECK-DAG: @sa_const15 = {{.*}}global i16 -1, align 2
6769

6870
void SignedDivision() {
6971
// CHECK-LABEL: SignedDivision

clang/test/Frontend/fixed_point_errors.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,6 @@ short _Fract add_sat = (_Sat short _Fract)0.5hr + 0.5hr;
264264
short _Accum sub_sat = (_Sat short _Accum)-200.0hk - 80.0hk;
265265
short _Accum mul_sat = (_Sat short _Accum)80.0hk * 10.0hk;
266266
short _Fract div_sat = (_Sat short _Fract)0.9hr / 0.1hr;
267+
268+
// Division by zero
269+
short _Accum div_zero = 4.5k / 0.0lr; // expected-error {{initializer element is not a compile-time constant}}

0 commit comments

Comments
 (0)