[clang] [clang] Enable constexpr handling for __builtin_elementwise_fma (PR #152919)

Chaitanya Koparkar via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 10 07:40:42 PDT 2025


================
@@ -15878,6 +15901,22 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
     Result = minimumnum(Result, RHS);
     return true;
   }
+
+  case Builtin::BI__builtin_elementwise_fma: {
+    if(!E->getArg(0)->isPRValue() ||
+       !E->getArg(1)->isPRValue() ||
+       !E->getArg(2)->isPRValue()) {
+      return false;
----------------
ckoparkar wrote:

I'm a bit confused about this check.

Without it, these statements in `clang/test/CodeGen/builtins-elementwise-math.c` lead to an assertion failure at `E->isPRValue()` in `EvaluateFloat`:

```
float f2 = __builtin_elementwise_fma(f32, f32, f32);
double d2 = __builtin_elementwise_fma(f64, f64, f64);
v2f64 = __builtin_elementwise_fma(f64, f64, f64); 
half tmp_f16 = __builtin_elementwise_fma(f16, f16, f16);
```

When I dump the arguments, I see this; the first argument is not an r-value, leading to the assertion failure:
```
Arg 0: DeclRefExpr 0x5a72563dffe8 'float' lvalue ParmVar 0x5a72563de468 'f32' 'float'

Arg 1: ImplicitCastExpr 0x5a72563e00f0 'float' <LValueToRValue>
`-DeclRefExpr 0x5a72563e0008 'float' lvalue ParmVar 0x5a72563de468 'f32' 'float'

Arg 2: ImplicitCastExpr 0x5a72563e0108 'float' <LValueToRValue>
`-DeclRefExpr 0x5a72563e0028 'float' lvalue ParmVar 0x5a72563de468 'f32' 'float'
```

 
The arguments look different for some other builtins I checked, e.g. for fmax:

```
/*
Arg 0 : ImplicitCastExpr 0x5ffaa8eed648 'double' <FloatingCast>
`-ImplicitCastExpr 0x5ffaa8eed630 'half':'_Float16' <LValueToRValue>
  `-DeclRefExpr 0x5ffaa8eed568 'half':'_Float16' lvalue ParmVar 0x5ffaa8eebde0 'f16' 'half':'_Float16'

Arg 1: ImplicitCastExpr 0x5ffaa8eed678 'double' <FloatingCast>
`-ImplicitCastExpr 0x5ffaa8eed660 'half':'_Float16' <LValueToRValue>
  `-DeclRefExpr 0x5ffaa8eed588 'half':'_Float16' lvalue ParmVar 0x5ffaa8eebde0 'f16' 'half':'_Float16'
*/

half tmp2_f16 = __builtin_fmax(f16, f16);
```

I'm not sure what code is responsible for the `LValueToRValue` here, and is it a bug that it isn't happening for the first argument of `fma`? Is it related to way that `APFloat::fusedMultiplyAdd` stores its result? I'd be happy to debug further if someone can point me the right direction.

https://github.com/llvm/llvm-project/pull/152919


More information about the cfe-commits mailing list