[clang] [CIR][X86] Add support for roundpd, roundps, roundsd, roundss builtins (PR #215787)

Phoebe Wang via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 14 07:42:07 PDT 2026


================
@@ -1145,6 +1165,77 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
     // Return timestamp (element 0 of the returned struct)
     return cir::ExtractMemberOp::create(builder, loc, i64Ty, result, 0);
   }
+  case X86::BI__builtin_ia32_roundps:
+  case X86::BI__builtin_ia32_roundpd:
+  case X86::BI__builtin_ia32_roundps256:
+  case X86::BI__builtin_ia32_roundpd256: {
+    unsigned m =
+        ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
+    constexpr unsigned mxcsrMask = 0b100;
+    constexpr unsigned fRoundNoExcMask = 0b1000;
+    unsigned useMXCSR = mxcsrMask & m;
+    unsigned fRoundNoExc = fRoundNoExcMask & m;
+
+    mlir::Location loc = getLoc(expr->getExprLoc());
+
+    if (useMXCSR || !fRoundNoExc) {
----------------
phoebewang wrote:

> If `_MM_FROUND_CUR_DIRECTION` is set (`useMXCSR` here), we should be using the constrained intrinsics to prevent code motion relative to calls that change the rounding mode. Calling `llvm.experimental.constrained.round` (or `cir::RoundOp` for this PR) will achieve that while doing the rounding using the current rounding mode.

We checked it [here](https://github.com/llvm/llvm-project/pull/171227/changes#diff-001b3c346c16a48c23aec37a4962d1ed5c10262df50599c45d71e8d64e60e955R87) before selecting to LLVM intrinsics. For `_MM_FROUND_CUR_DIRECTION`, we still use X86 intrinsics. Currently, target intrinsics are not well modeled in StrictFP. So, it's not a new issue.

> If `_MM_FROUND_NO_EXC` is set, we need to suppress exceptions. Calling a constrained intrinsic with `fpexcept.ignore` doesn't do that (or at least the semantics of the intrinsic don't guarantee it). That's just supposed to be a hint to the optimizer that it can ignore the possibility that the operation will raise an exception. It appears that the backend is setting the no exception bit based on the metadata argument, but the intrinsic isn't defined to require that.

`_MM_FROUND_NO_EXC` is coupled with RoundingControl. It's mainly used as do not care, rather than do not except, though they are the same thing when using target intrinsic. The best way to do would lower `fpexcept.ignore` into the AVX512 RC instructions, but only 512-bit supports it. So, we won't force it.

> If `_MM_FROUND_NO_EXC` is not set but we are in strict FP mode, we should be using the constrained intrinsics to prevent code motion relative to calls that read the exception state.

Note, the FRoundNoExc only masks the precision exception bit.

In a word, it's an existing problem than constrained intrinsics cannot fully represent the complex target intrinsic attributes. We have little to do within the current constrained intrinsics design.

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


More information about the cfe-commits mailing list