[cfe-commits] Patch for evaluating FP constant expressions
Christopher Lamb
christopher.lamb at gmail.com
Fri Nov 30 19:40:06 PST 2007
On Nov 29, 2007, at 11:51 AM, Chris Lattner wrote:
> On Nov 28, 2007, at 10:18 PM, Christopher Lamb wrote:
>
>> I needed this to support negation of FP literals, which is pretty
>> unambiguous. It looks like GCC evaluates more complex constant
>> expressions too, so I put in support for some of that (though
>> rounding mode is an issue). All of this is modeled on the work for
>> integer expressions and uses APFloat.
>
> Very interesting, I didn't realize that this was non-conforming:
>
> double x = -1.0;
>
> A couple of comments:
>
> + /// isRealFloatingConstantExpr - Return true if this expression
> is a valid
> + /// floating point constant expression, and, if so, return its
> value in
> + /// Result. If not a valid rfce, return false and fill in Loc
> (if specified)
> + /// with the location of the invalid expression.
> + bool isRealFloatingConstantExpr(llvm::APFloat &Result,
> ASTContext &Ctx,
> + SourceLocation *Loc = 0,
> + bool isEvaluated = true) const;
>
> Please add a comment that states this can only be used for
> statically initialized values. For non-static initializers, the
> code should be evaluated in its current context, which could be
> affected by rounding mode etc.
>
Ok.
> + // FIXME: How to choose the rounding mode? Emulate GCC behavior?
>
> This codegen routine should only be used for static initializers.
> Static inits are evaluated before main and static ctors run (e.g.
> at compile time ;-), so they can only be evaluated with the default
> rounding mode. Please add a comment to this effect.
Ok.
>
> + case BinaryOperatorClass: {
> + const BinaryOperator *Exp = cast<BinaryOperator>(this);
> +
> + // The LHS of a constant expr is always evaluated and needed.
> + if (!Exp->getLHS()->isRealFloatingConstantExpr(Result, Ctx, Loc,
> + isEvaluated))
> + return false;
> +
> + llvm::APFloat RHS(Result);
> +
> + // The short-circuiting &&/|| operators don't necessarily
> evaluate their
> + // RHS. Make sure to pass isEvaluated down correctly.
> + if (Exp->isLogicalOp()) {
> + bool RHSEval;
> + if (Exp->getOpcode() == BinaryOperator::LAnd)
> + RHSEval = Result.isNonZero();
> + else {
> + assert(Exp->getOpcode() == BinaryOperator::LOr
> &&"Unexpected logical");
> + RHSEval = Result.isZero();
> + }
>
> Logical ops like && always return bool, not an fp type, so I think
> this code is dead.
I agree.
> It would probably also be worthwhile to handle int <-> fp casts as
> well, but that can be a follow-on patch if you prefer.
Indeed. Later, though.
> + case BinaryOperator::Div:
> + if (llvm::APFloat::opOK !=
> + Result.divide(RHS, llvm::APFloat::rmNearestTiesToEven)) {
> + if (!isEvaluated) break;
> + if (Loc) *Loc = getLocStart();
> + return false;
> + }
>
> It would be "nice" if this reported diagnostics for overflow etc as
> warnings.
This is in Expr.cpp and it's called from CodeGen, how can I get the
diagnostics object here?
--
Christopher Lamb
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20071130/2b260965/attachment.html>
More information about the cfe-commits
mailing list