rsmith added inline comments.

================
Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2195
+    Value *ExpectedValue = EmitScalarExpr(E->getArg(1));
+    Value *Confidence = EmitScalarExpr(E->getArg(2));
+    // Don't generate llvm.expect.with.probability on -O0 as the backend
----------------
LukeZhuang wrote:
> rsmith wrote:
> > If the intrinsic expects a `ConstantFP` value, this isn't enough to 
> > guarantee that you get one (the set of cases that we fold to constants 
> > during expression emission is much smaller than the set of cases we can 
> > constant-evaluate). You should run the constant evaluator first, to produce 
> > an `APFloat`, then emit that value as a constant. (Optionally you can form 
> > a `ConstantExpr` as part of the check in `Sema` and store the value in that 
> > object rather than recomputing it here.)
> Thank you for commenting! I have a question about this. If I check this 
> argument can be fold as constant float in `Sema`, why I need to check it 
> here? Or do you mean I had better create a `ConstantFP` value here after 
> constant emitting? 
`EmitScalarExpr` will emit arbitrary IR that evaluates the argument. If the 
argument isn't a simple floating-point literal, then you won't necessarily get 
an IR-level constant back from that. For example:

```
struct die {
  constexpr int sides() { return 6; }
  int roll();
} d6;
bool rolled_a_one = __builtin_expect_with_probability(d6.roll(), 1, 1.0 / 
d6.sides());
```

Here, we can evaluate `1.0 / d6.sides()`, but `EmitScalarExpr` will emit a 
function call and a division, not a constant.

Instead, you could use `EvaluateAsFloat` here (you can assert it succeeds 
because you already checked that in `Sema`) and then directly form a 
`ConstantFP` from the `APFloat` result.


================
Comment at: clang/lib/Sema/SemaChecking.cpp:1805
+    const Expr *ProbArg = TheCall->getArg(2);
+    if (ProbArg->EvaluateAsFloat(Confidence, Context)) {
+      double P = Confidence.convertToDouble();
----------------
LukeZhuang wrote:
> LukeZhuang wrote:
> > rsmith wrote:
> > > What rules should be applied here? Do we just want to allow anything that 
> > > we can evaluate (which might change over time), or do we want to use the 
> > > underlying language's notion of floating-point constant expressions, if 
> > > it has them?
> > Thank you for commenting. I just read the llvm::Expr document and found 
> > that it just have `isIntegerConstantExpr` without a float-point version. 
> > Under `EvaluateAsFloat` it says "Return true if this is a constant which we 
> > can fold and convert to a floating point value", thus I use this function. 
> > Is there any better function to achieve this goal?
> Hi, and I didn't find other builtin functions ever handle case like this, is 
> there any example I could refer to?
I think this is the first builtin (and maybe the first part of Clang) that 
wants to enforce that it sees a floating-point constant expression.

The right thing to do is generally to call `EvaluateAsConstantExpr` and check 
that it produces the right kind of value and doesn't generate any notes. See 
the code at the end of `CheckConvertedConstantExpr` for how to do this.

You also need to check that `ProbArg` is not value-dependent before you try to 
evaluate it; it's not meaningful to ask for the value of a value-dependent 
expression.


================
Comment at: clang/lib/Sema/SemaChecking.cpp:1813-1814
+    } else {
+      Diag(ProbArg->getLocStart(), diag::err_probability_not_constant_float)
+          << ProbArg->getSourceRange();
+      return ExprError();
----------------
`EvaluateAsConstantExpr` will give you some notes to attach to this diagnostic 
to explain why the expression is non-constant.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79830/new/

https://reviews.llvm.org/D79830



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to