================
@@ -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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to