[Mlir-commits] [mlir] 02b0838 - [mlir][llvm] Add more constrained FP operations (#213745)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Aug 6 09:16:13 PDT 2026


Author: Andy Kaylor
Date: 2026-08-06T09:16:07-07:00
New Revision: 02b08387ae43a19b5f2817641d36b9398a0e19e5

URL: https://github.com/llvm/llvm-project/commit/02b08387ae43a19b5f2817641d36b9398a0e19e5
DIFF: https://github.com/llvm/llvm-project/commit/02b08387ae43a19b5f2817641d36b9398a0e19e5.diff

LOG: [mlir][llvm] Add more constrained FP operations (#213745)

This change adds special constrained forms of transcendental operations
for the remaining cases that lower to contrained fp intrinsic calls. It
also adds fast-math flag support to the constrained operations, which is
needed to handle combinations of Clang command-line options such as
"-ffinite-math-only -ftrapping-math".

Assisted-by: Cursor / various models

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
    mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll
    mlir/test/Target/LLVMIR/Import/intrinsic.ll
    mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index cbd513e1a4021..69f44e64b2de9 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -441,14 +441,16 @@ class LLVM_ConstrainedIntr<string mnem, int numArgs,
                                !gt(hasRoundingMode, 0) : [DeclareOpInterfaceMethods<RoundingModeOpInterface>],
                                true : [])
                            # extraTraits,
-                           /*requiresFastmath=*/0,
+                           /*requiresFastmath=*/1,
                            /*requiresArgAndResultAttrs=*/0,
                            /*immArgPositions=*/[],
                            /*immArgAttrNames=*/[]> {
   dag regularArgs = !dag(ins, !listsplat(LLVM_Type, numArgs), !foreach(i, !range(numArgs), "arg_" #i));
   dag attrArgs = !con(!cond(!gt(hasRoundingMode, 0) : (ins ValidRoundingModeAttr:$roundingmode),
                             true : (ins)),
-                      (ins FPExceptionBehaviorAttr:$fpExceptionBehavior));
+                      (ins FPExceptionBehaviorAttr:$fpExceptionBehavior,
+                           DefaultValuedAttr<LLVM_FastmathFlagsAttr,
+                                             "{}">:$fastmathFlags));
   let arguments = !con(regularArgs, attrArgs);
   let llvmBuilder = [{
     SmallVector<llvm::Value *> args =
@@ -499,8 +501,124 @@ class LLVM_ConstrainedIntr<string mnem, int numArgs,
         $_builder.getNamedAttr($_qualCppClassName::getRoundingModeAttrName(),
                                roundingModeAttr));
     }], true : "") # [{
-    $res = $_qualCppClassName::create($_builder, $_location,
+    auto op = $_qualCppClassName::create($_builder, $_location,
       $_resultType, mlirOperands, mlirAttrs);
+    moduleImport.setFastmathFlagsAttr(inst, op);
+    $res = op;
+  }];
+}
+
+// Convenience base class for constrained intrinsics that take a single
+// floating-point operand of the same type as the result and support a rounding
+// mode (e.g. the transcendental math functions).
+class LLVM_ConstrainedUnaryIntrRM<string mnem>
+    : LLVM_ConstrainedIntr<mnem, /*numArgs=*/1,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[],
+        /*hasRoundingMode=*/1, [SameOperandsAndResultType]> {
+  let assemblyFormat = [{
+    $arg_0 $roundingmode $fpExceptionBehavior attr-dict `:` type($arg_0)
+  }];
+}
+
+// Convenience base class for constrained intrinsics that take a single
+// floating-point operand of the same type as the result and do not support a
+// rounding mode (e.g. the rounding math functions such as `ceil`).
+class LLVM_ConstrainedUnaryIntrNoRM<string mnem>
+    : LLVM_ConstrainedIntr<mnem, /*numArgs=*/1,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[],
+        /*hasRoundingMode=*/0, [SameOperandsAndResultType]> {
+  let assemblyFormat = [{
+    $arg_0 $fpExceptionBehavior attr-dict `:` type($arg_0)
+  }];
+}
+
+// Convenience base class for constrained intrinsics that take two
+// floating-point operands of the same type as the result and support a rounding
+// mode (e.g. `pow` and `atan2`).
+class LLVM_ConstrainedBinaryIntrRM<string mnem>
+    : LLVM_ConstrainedIntr<mnem, /*numArgs=*/2,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[],
+        /*hasRoundingMode=*/1, [SameOperandsAndResultType]> {
+  let assemblyFormat = [{
+    $arg_0 `,` $arg_1 $roundingmode $fpExceptionBehavior attr-dict `:` type($arg_0)
+  }];
+}
+
+// Convenience base class for constrained intrinsics that take two
+// floating-point operands of the same type as the result and do not support a
+// rounding mode (e.g. `maxnum` and `minnum`).
+class LLVM_ConstrainedBinaryIntrNoRM<string mnem>
+    : LLVM_ConstrainedIntr<mnem, /*numArgs=*/2,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[],
+        /*hasRoundingMode=*/0, [SameOperandsAndResultType]> {
+  let assemblyFormat = [{
+    $arg_0 `,` $arg_1 $fpExceptionBehavior attr-dict `:` type($arg_0)
+  }];
+}
+
+// Convenience base class for constrained FP-to-int conversions that support a
+// rounding mode (e.g. `lrint`).
+class LLVM_ConstrainedFPToIntIntrRM<string mnem>
+    : LLVM_ConstrainedIntr<mnem, /*numArgs=*/1,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[0],
+        /*hasRoundingMode=*/1> {
+  let assemblyFormat = [{
+    $arg_0 $roundingmode $fpExceptionBehavior attr-dict `:`
+    type($arg_0) `to` type(results)
+  }];
+}
+
+// Convenience base class for constrained FP-to-int conversions that do not
+// support a rounding mode (e.g. `lround` and `fptosi`).
+class LLVM_ConstrainedFPToIntIntrNoRM<string mnem>
+    : LLVM_ConstrainedIntr<mnem, /*numArgs=*/1,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[0],
+        /*hasRoundingMode=*/0> {
+  let assemblyFormat = [{
+    $arg_0 $fpExceptionBehavior attr-dict `:` type($arg_0) `to` type(results)
+  }];
+}
+
+// Constrained floating-point comparisons. These take a predicate attribute
+// instead of a rounding mode and lower via CreateConstrainedFPCmp.
+class LLVM_ConstrainedFCmpIntrBase<string mnem>
+    : LLVM_OneResultIntrOp<"experimental.constrained." # mnem,
+        /*overloadedResults=*/[], /*overloadedOperands=*/[0],
+        /*traits=*/[Pure, SameTypeOperands,
+          TypesMatchWith<"result type has i1 element type and same shape as "
+                         "operands", "arg_0", "res",
+                         "::getI1SameShape($_self)">,
+          DeclareOpInterfaceMethods<FPExceptionBehaviorOpInterface>],
+        /*requiresFastmath=*/1> {
+  let arguments = (ins FCmpPredicate:$predicate,
+                       LLVM_Type:$arg_0,
+                       LLVM_Type:$arg_1,
+                       FPExceptionBehaviorAttr:$fpExceptionBehavior,
+                       DefaultValuedAttr<LLVM_FastmathFlagsAttr,
+                                         "{}">:$fastmathFlags);
+  // Predicate and fast-math flags are attributes (no matching LLVM operand);
+  // the exception behavior metadata is the fourth LLVM operand.
+  list<int> llvmArgIndices = [-1, 0, 1, 3, -1];
+  let assemblyFormat = [{
+    $predicate $arg_0 `,` $arg_1 $fpExceptionBehavior attr-dict `:` type($arg_0)
+  }];
+  let llvmBuilder = [{
+    $res = builder.CreateConstrainedFPCmp(
+        llvm::Intrinsic::experimental_constrained_}] # mnem # [{,
+        convertFCmpPredicateToLLVM($predicate), $arg_0, $arg_1, "",
+        moduleTranslation.translateFPExceptionBehavior(
+            $fpExceptionBehavior));
+  }];
+  let mlirBuilder = [{
+    auto *cmpInst = cast<llvm::ConstrainedFPCmpIntrinsic>(inst);
+    auto op = $_qualCppClassName::create(
+        $_builder, $_location, $_resultType,
+        $_builder.getAttr<FCmpPredicateAttr>(
+            convertFCmpPredicateFromLLVM(cmpInst->getPredicate())),
+        $arg_0, $arg_1,
+        $_fpExceptionBehavior_attr($fpExceptionBehavior));
+    moduleImport.setFastmathFlagsAttr(inst, op);
+    $res = op;
   }];
 }
 
@@ -567,6 +685,80 @@ def LLVM_ConstrainedFMulAddIntr
   }];
 }
 
+// Constrained intrinsics for math library functions. These correspond to the
+// like-named operations in the Math dialect and are produced when the source
+// operation carries a `#arith.fenv` floating-point environment attribute.
+
+// Unary transcendental functions (support a rounding mode).
+def LLVM_ConstrainedSqrtIntr  : LLVM_ConstrainedUnaryIntrRM<"sqrt">;
+def LLVM_ConstrainedSinIntr   : LLVM_ConstrainedUnaryIntrRM<"sin">;
+def LLVM_ConstrainedCosIntr   : LLVM_ConstrainedUnaryIntrRM<"cos">;
+def LLVM_ConstrainedTanIntr   : LLVM_ConstrainedUnaryIntrRM<"tan">;
+def LLVM_ConstrainedASinIntr  : LLVM_ConstrainedUnaryIntrRM<"asin">;
+def LLVM_ConstrainedACosIntr  : LLVM_ConstrainedUnaryIntrRM<"acos">;
+def LLVM_ConstrainedATanIntr  : LLVM_ConstrainedUnaryIntrRM<"atan">;
+def LLVM_ConstrainedSinhIntr  : LLVM_ConstrainedUnaryIntrRM<"sinh">;
+def LLVM_ConstrainedCoshIntr  : LLVM_ConstrainedUnaryIntrRM<"cosh">;
+def LLVM_ConstrainedTanhIntr  : LLVM_ConstrainedUnaryIntrRM<"tanh">;
+def LLVM_ConstrainedExpIntr   : LLVM_ConstrainedUnaryIntrRM<"exp">;
+def LLVM_ConstrainedExp2Intr  : LLVM_ConstrainedUnaryIntrRM<"exp2">;
+def LLVM_ConstrainedLogIntr   : LLVM_ConstrainedUnaryIntrRM<"log">;
+def LLVM_ConstrainedLog10Intr : LLVM_ConstrainedUnaryIntrRM<"log10">;
+def LLVM_ConstrainedLog2Intr  : LLVM_ConstrainedUnaryIntrRM<"log2">;
+def LLVM_ConstrainedRIntIntr  : LLVM_ConstrainedUnaryIntrRM<"rint">;
+def LLVM_ConstrainedNearbyIntIntr : LLVM_ConstrainedUnaryIntrRM<"nearbyint">;
+
+// Unary rounding functions (do not support a rounding mode).
+def LLVM_ConstrainedCeilIntr      : LLVM_ConstrainedUnaryIntrNoRM<"ceil">;
+def LLVM_ConstrainedFloorIntr     : LLVM_ConstrainedUnaryIntrNoRM<"floor">;
+def LLVM_ConstrainedRoundIntr     : LLVM_ConstrainedUnaryIntrNoRM<"round">;
+def LLVM_ConstrainedRoundEvenIntr : LLVM_ConstrainedUnaryIntrNoRM<"roundeven">;
+def LLVM_ConstrainedTruncIntr     : LLVM_ConstrainedUnaryIntrNoRM<"trunc">;
+
+// Binary functions (support a rounding mode).
+def LLVM_ConstrainedPowIntr   : LLVM_ConstrainedBinaryIntrRM<"pow">;
+def LLVM_ConstrainedATan2Intr : LLVM_ConstrainedBinaryIntrRM<"atan2">;
+
+// Binary min/max functions (do not support a rounding mode).
+def LLVM_ConstrainedMaxNumIntr  : LLVM_ConstrainedBinaryIntrNoRM<"maxnum">;
+def LLVM_ConstrainedMinNumIntr  : LLVM_ConstrainedBinaryIntrNoRM<"minnum">;
+def LLVM_ConstrainedMaximumIntr : LLVM_ConstrainedBinaryIntrNoRM<"maximum">;
+def LLVM_ConstrainedMinimumIntr : LLVM_ConstrainedBinaryIntrNoRM<"minimum">;
+
+def LLVM_ConstrainedPowIIntr
+    : LLVM_ConstrainedIntr<"powi", /*numArgs=*/2,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[],
+        /*hasRoundingMode=*/1> {
+  let assemblyFormat = [{
+    $arg_0 `,` $arg_1 $roundingmode $fpExceptionBehavior attr-dict `:`
+    functional-type(operands, results)
+  }];
+}
+
+def LLVM_ConstrainedLdexpIntr
+    : LLVM_ConstrainedIntr<"ldexp", /*numArgs=*/2,
+        /*overloadedResult=*/1, /*overloadedOperands=*/[1],
+        /*hasRoundingMode=*/1> {
+  let assemblyFormat = [{
+    $arg_0 `,` $arg_1 $roundingmode $fpExceptionBehavior attr-dict `:`
+    functional-type(operands, results)
+  }];
+}
+
+// FP-to-int rounding conversions.
+def LLVM_ConstrainedLRintIntr  : LLVM_ConstrainedFPToIntIntrRM<"lrint">;
+def LLVM_ConstrainedLLRintIntr : LLVM_ConstrainedFPToIntIntrRM<"llrint">;
+def LLVM_ConstrainedLRoundIntr  : LLVM_ConstrainedFPToIntIntrNoRM<"lround">;
+def LLVM_ConstrainedLLRoundIntr : LLVM_ConstrainedFPToIntIntrNoRM<"llround">;
+
+// FP-to-int conversions (do not support a rounding mode).
+def LLVM_ConstrainedFPToSIIntr : LLVM_ConstrainedFPToIntIntrNoRM<"fptosi">;
+def LLVM_ConstrainedFPToUIIntr : LLVM_ConstrainedFPToIntIntrNoRM<"fptoui">;
+
+// Constrained floating-point comparisons.
+def LLVM_ConstrainedFCmpIntr  : LLVM_ConstrainedFCmpIntrBase<"fcmp">;
+def LLVM_ConstrainedFCmpSIntr : LLVM_ConstrainedFCmpIntrBase<"fcmps">;
+
 def LLVM_ConstrainedUIToFP
     : LLVM_ConstrainedIntr<"uitofp", /*numArgs=*/1,
         /*overloadedResult=*/1, /*overloadedOperands=*/[0],

diff  --git a/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll b/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll
index da58d48d995be..e5d6a4391b124 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll
@@ -80,19 +80,19 @@ define signext i32 @test_intrin_arg_attr(i32 signext %a) nounwind {
 
 ; // -----
 
-; Constrained FP intrinsics with no dedicated MLIR op should fall back to
+; Rounding FP intrinsics with no dedicated MLIR op should fall back to
 ; `llvm.call_intrinsic`, and their `metadata !"..."` operands should be
 ; imported as `llvm.mlir.metadata_as_value` ops wrapping the corresponding
-; `#llvm.md_string` attribute.
+; `#llvm.md_string` attribute. `llvm.fptrunc.round` is used here because it
+; takes an MDString rounding-mode operand and has no specialized MLIR op.
 
-declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
+declare float @llvm.fptrunc.round.f32.f64(double, metadata)
 
-; CHECK-LABEL: llvm.func @constrained_sqrt
-define float @constrained_sqrt(float %a) {
+; CHECK-LABEL: llvm.func @fptrunc_round
+define float @fptrunc_round(double %a) {
   ; CHECK: %[[RM:.*]] = llvm.mlir.metadata_as_value #llvm.md_string<"round.tonearest">
-  ; CHECK: %[[EB:.*]] = llvm.mlir.metadata_as_value #llvm.md_string<"fpexcept.strict">
-  ; CHECK: %{{.*}} = llvm.call_intrinsic "llvm.experimental.constrained.sqrt.f32"(%{{.*}}, %[[RM]], %[[EB]]) : (f32, !llvm.metadata, !llvm.metadata) -> f32
-  %r = call float @llvm.experimental.constrained.sqrt.f32(float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptrunc.round.f32.f64"(%{{.*}}, %[[RM]]) : (f64, !llvm.metadata) -> f32
+  %r = call float @llvm.fptrunc.round.f32.f64(double %a, metadata !"round.tonearest")
   ret float %r
 }
 

diff  --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
index c47d1cca187b7..5bbb920e423c8 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
@@ -1176,6 +1176,8 @@ define void @experimental_constrained_fadd(float %s, <4 x float> %v) {
   %1 = call float @llvm.experimental.constrained.fadd.f32(float %s, float %s, metadata !"round.towardzero", metadata !"fpexcept.ignore")
   ; CHECK: llvm.intr.experimental.constrained.fadd %{{.*}}, %{{.*}} towardzero ignore : vector<4xf32>
   %2 = call <4 x float> @llvm.experimental.constrained.fadd.v4f32(<4 x float> %v, <4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.fadd %{{.*}}, %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nnan, nsz>} : f32
+  %3 = call nnan nsz float @llvm.experimental.constrained.fadd.f32(float %s, float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
   ret void
 }
 
@@ -1297,6 +1299,376 @@ define void @experimental_constrained_fpext(float %s, <4 x float> %v) {
   ret void
 }
 
+; CHECK-LABEL: experimental_constrained_sqrt
+define void @experimental_constrained_sqrt(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.sqrt %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.sqrt.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.sqrt %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.sqrt.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.sqrt %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.sqrt.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_sin
+define void @experimental_constrained_sin(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.sin %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.sin.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.sin %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.sin.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.sin %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.sin.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_cos
+define void @experimental_constrained_cos(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.cos %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.cos.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.cos %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.cos.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.cos %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.cos.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_tan
+define void @experimental_constrained_tan(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.tan %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.tan.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.tan %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.tan.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.tan %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.tan.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_asin
+define void @experimental_constrained_asin(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.asin %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.asin.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.asin %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.asin.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.asin %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.asin.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_acos
+define void @experimental_constrained_acos(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.acos %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.acos.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.acos %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.acos.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.acos %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.acos.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_atan
+define void @experimental_constrained_atan(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.atan %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.atan.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.atan %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.atan.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.atan %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.atan.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_sinh
+define void @experimental_constrained_sinh(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.sinh %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.sinh.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.sinh %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.sinh.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.sinh %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.sinh.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_cosh
+define void @experimental_constrained_cosh(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.cosh %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.cosh.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.cosh %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.cosh.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.cosh %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.cosh.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_tanh
+define void @experimental_constrained_tanh(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.tanh %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.tanh.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.tanh %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.tanh.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.tanh %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.tanh.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_exp
+define void @experimental_constrained_exp(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.exp %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.exp.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.exp %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.exp.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.exp %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.exp.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_exp2
+define void @experimental_constrained_exp2(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.exp2 %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.exp2.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.exp2 %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.exp2.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.exp2 %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.exp2.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_log
+define void @experimental_constrained_log(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.log %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.log.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.log %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.log.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.log %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.log.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_log10
+define void @experimental_constrained_log10(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.log10 %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.log10.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.log10 %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.log10.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.log10 %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.log10.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_log2
+define void @experimental_constrained_log2(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.log2 %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.log2.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.log2 %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.log2.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.log2 %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.log2.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_rint
+define void @experimental_constrained_rint(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.rint %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.rint.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.rint %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.rint.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.rint %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.rint.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_nearbyint
+define void @experimental_constrained_nearbyint(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.nearbyint %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.nearbyint.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.nearbyint %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.nearbyint.v4f32(<4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.nearbyint %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.nearbyint.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_ceil
+define void @experimental_constrained_ceil(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.ceil %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.ceil.f32(float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.ceil %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.ceil.v4f32(<4 x float> %v, metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_floor
+define void @experimental_constrained_floor(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.floor %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.floor.f32(float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.floor %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.floor.v4f32(<4 x float> %v, metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_round
+define void @experimental_constrained_round(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.round %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.round.f32(float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.round %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.round.v4f32(<4 x float> %v, metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_roundeven
+define void @experimental_constrained_roundeven(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.roundeven %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.roundeven.f32(float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.roundeven %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.roundeven.v4f32(<4 x float> %v, metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_trunc
+define void @experimental_constrained_trunc(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.trunc %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.trunc.f32(float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.trunc %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.trunc.v4f32(<4 x float> %v, metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_pow
+define void @experimental_constrained_pow(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.pow %{{.*}}, %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.pow.f32(float %s, float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.pow %{{.*}}, %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.pow.v4f32(<4 x float> %v, <4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.pow %{{.*}}, %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.pow.f32(float %s, float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_atan2
+define void @experimental_constrained_atan2(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.atan2 %{{.*}}, %{{.*}} tonearest strict : f32
+  %1 = call float @llvm.experimental.constrained.atan2.f32(float %s, float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.atan2 %{{.*}}, %{{.*}} towardzero ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.atan2.v4f32(<4 x float> %v, <4 x float> %v, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.atan2 %{{.*}}, %{{.*}} tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.atan2.f32(float %s, float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_maxnum
+define void @experimental_constrained_maxnum(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.maxnum %{{.*}}, %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.maxnum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.maxnum %{{.*}}, %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.maxnum.v4f32(<4 x float> %v, <4 x float> %v, metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.maxnum %{{.*}}, %{{.*}} strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.maxnum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_minnum
+define void @experimental_constrained_minnum(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.minnum %{{.*}}, %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.minnum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.minnum %{{.*}}, %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.minnum.v4f32(<4 x float> %v, <4 x float> %v, metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.minnum %{{.*}}, %{{.*}} strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.minnum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_maximum
+define void @experimental_constrained_maximum(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.maximum %{{.*}}, %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.maximum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.maximum %{{.*}}, %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.maximum.v4f32(<4 x float> %v, <4 x float> %v, metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.maximum %{{.*}}, %{{.*}} strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.maximum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_minimum
+define void @experimental_constrained_minimum(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.minimum %{{.*}}, %{{.*}} strict : f32
+  %1 = call float @llvm.experimental.constrained.minimum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.minimum %{{.*}}, %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.minimum.v4f32(<4 x float> %v, <4 x float> %v, metadata !"fpexcept.ignore")
+  ; CHECK: llvm.intr.experimental.constrained.minimum %{{.*}}, %{{.*}} strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  %3 = call nsz float @llvm.experimental.constrained.minimum.f32(float %s, float %s, metadata !"fpexcept.strict")
+  ret void
+}
+
+
+; CHECK-LABEL: experimental_constrained_powi
+define void @experimental_constrained_powi(float %s, i32 %e, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.powi %{{.*}}, %{{.*}} tonearest strict : (f32, i32) -> f32
+  %1 = call float @llvm.experimental.constrained.powi.f32(float %s, i32 %e, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.powi %{{.*}}, %{{.*}} towardzero ignore : (vector<4xf32>, i32) -> vector<4xf32>
+  %2 = call <4 x float> @llvm.experimental.constrained.powi.v4f32(<4 x float> %v, i32 %e, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_ldexp
+define void @experimental_constrained_ldexp(float %s, i32 %e) {
+  ; CHECK: llvm.intr.experimental.constrained.ldexp %{{.*}}, %{{.*}} tonearest strict : (f32, i32) -> f32
+  %1 = call float @llvm.experimental.constrained.ldexp.f32.i32(float %s, i32 %e, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_lrint
+define void @experimental_constrained_lrint(float %s) {
+  ; CHECK: llvm.intr.experimental.constrained.lrint %{{.*}} tonearest strict : f32 to i32
+  %1 = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_llrint
+define void @experimental_constrained_llrint(float %s) {
+  ; CHECK: llvm.intr.experimental.constrained.llrint %{{.*}} tonearest strict : f32 to i64
+  %1 = call i64 @llvm.experimental.constrained.llrint.i64.f32(float %s, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_lround
+define void @experimental_constrained_lround(float %s) {
+  ; CHECK: llvm.intr.experimental.constrained.lround %{{.*}} strict : f32 to i32
+  %1 = call i32 @llvm.experimental.constrained.lround.i32.f32(float %s, metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_llround
+define void @experimental_constrained_llround(float %s) {
+  ; CHECK: llvm.intr.experimental.constrained.llround %{{.*}} strict : f32 to i64
+  %1 = call i64 @llvm.experimental.constrained.llround.i64.f32(float %s, metadata !"fpexcept.strict")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_fptosi
+define void @experimental_constrained_fptosi(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.fptosi %{{.*}} strict : f32 to i32
+  %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.fptosi %{{.*}} ignore : vector<4xf32> to vector<4xi32>
+  %2 = call <4 x i32> @llvm.experimental.constrained.fptosi.v4i32.v4f32(<4 x float> %v, metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_fptoui
+define void @experimental_constrained_fptoui(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.fptoui %{{.*}} strict : f32 to i32
+  %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %s, metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.fptoui %{{.*}} ignore : vector<4xf32> to vector<4xi32>
+  %2 = call <4 x i32> @llvm.experimental.constrained.fptoui.v4i32.v4f32(<4 x float> %v, metadata !"fpexcept.ignore")
+  ret void
+}
+
+; CHECK-LABEL: experimental_constrained_fcmp
+define void @experimental_constrained_fcmp(float %s, <4 x float> %v) {
+  ; CHECK: llvm.intr.experimental.constrained.fcmp oeq %{{.*}}, %{{.*}} strict : f32
+  %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %s, float %s, metadata !"oeq", metadata !"fpexcept.strict")
+  ; CHECK: llvm.intr.experimental.constrained.fcmps olt %{{.*}}, %{{.*}} ignore : vector<4xf32>
+  %2 = call <4 x i1> @llvm.experimental.constrained.fcmps.v4f32(<4 x float> %v, <4 x float> %v, metadata !"olt", metadata !"fpexcept.ignore")
+  ret void
+}
+
 ; CHECK-LABEL:  llvm.func @ucmp
 define i2 @ucmp(i32 %a, i32 %b) {
   ; CHECK: %{{.*}} = llvm.intr.ucmp(%{{.*}}, %{{.*}}) : (i32, i32) -> i2
@@ -1603,6 +1975,75 @@ declare <4 x half> @llvm.experimental.constrained.fptrunc.v4f16.v4f64(<4 x doubl
 declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata)
 declare <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f32(<4 x float>, metadata)
 declare double @llvm.experimental.constrained.fpext.f64.f32(float, metadata)
+declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.sqrt.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.sin.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.sin.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.cos.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.cos.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.tan.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.tan.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.asin.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.asin.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.acos.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.acos.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.atan.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.atan.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.sinh.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.sinh.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.cosh.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.cosh.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.tanh.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.tanh.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.exp.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.exp.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.exp2.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.exp2.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.log.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.log.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.log10.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.log10.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.log2.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.log2.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.rint.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.rint.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.nearbyint.f32(float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.nearbyint.v4f32(<4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.ceil.f32(float, metadata)
+declare <4 x float> @llvm.experimental.constrained.ceil.v4f32(<4 x float>, metadata)
+declare float @llvm.experimental.constrained.floor.f32(float, metadata)
+declare <4 x float> @llvm.experimental.constrained.floor.v4f32(<4 x float>, metadata)
+declare float @llvm.experimental.constrained.round.f32(float, metadata)
+declare <4 x float> @llvm.experimental.constrained.round.v4f32(<4 x float>, metadata)
+declare float @llvm.experimental.constrained.roundeven.f32(float, metadata)
+declare <4 x float> @llvm.experimental.constrained.roundeven.v4f32(<4 x float>, metadata)
+declare float @llvm.experimental.constrained.trunc.f32(float, metadata)
+declare <4 x float> @llvm.experimental.constrained.trunc.v4f32(<4 x float>, metadata)
+declare float @llvm.experimental.constrained.pow.f32(float, float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.pow.v4f32(<4 x float>, <4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.atan2.f32(float, float, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.atan2.v4f32(<4 x float>, <4 x float>, metadata, metadata)
+declare float @llvm.experimental.constrained.maxnum.f32(float, float, metadata)
+declare <4 x float> @llvm.experimental.constrained.maxnum.v4f32(<4 x float>, <4 x float>, metadata)
+declare float @llvm.experimental.constrained.minnum.f32(float, float, metadata)
+declare <4 x float> @llvm.experimental.constrained.minnum.v4f32(<4 x float>, <4 x float>, metadata)
+declare float @llvm.experimental.constrained.maximum.f32(float, float, metadata)
+declare <4 x float> @llvm.experimental.constrained.maximum.v4f32(<4 x float>, <4 x float>, metadata)
+declare float @llvm.experimental.constrained.minimum.f32(float, float, metadata)
+declare <4 x float> @llvm.experimental.constrained.minimum.v4f32(<4 x float>, <4 x float>, metadata)
+declare float @llvm.experimental.constrained.powi.f32(float, i32, metadata, metadata)
+declare <4 x float> @llvm.experimental.constrained.powi.v4f32(<4 x float>, i32, metadata, metadata)
+declare float @llvm.experimental.constrained.ldexp.f32.i32(float, i32, metadata, metadata)
+declare i32 @llvm.experimental.constrained.lrint.i32.f32(float, metadata, metadata)
+declare i64 @llvm.experimental.constrained.llrint.i64.f32(float, metadata, metadata)
+declare i32 @llvm.experimental.constrained.lround.i32.f32(float, metadata)
+declare i64 @llvm.experimental.constrained.llround.i64.f32(float, metadata)
+declare i32 @llvm.experimental.constrained.fptosi.i32.f32(float, metadata)
+declare <4 x i32> @llvm.experimental.constrained.fptosi.v4i32.v4f32(<4 x float>, metadata)
+declare i32 @llvm.experimental.constrained.fptoui.i32.f32(float, metadata)
+declare <4 x i32> @llvm.experimental.constrained.fptoui.v4i32.v4f32(<4 x float>, metadata)
+declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata)
+declare <4 x i1> @llvm.experimental.constrained.fcmps.v4f32(<4 x float>, <4 x float>, metadata, metadata)
 declare i2 @llvm.ucmp.i2.i32(i32, i32)
 declare <4 x i32> @llvm.ucmp.v4i32.v4i32(<4 x i32>, <4 x i32>)
 declare i2 @llvm.scmp.i2.i32(i32, i32)

diff  --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
index d5df69a786b3e..13d4155e4ca04 100644
--- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -1300,6 +1300,10 @@ llvm.func @experimental_constrained_fadd(%s: f32, %v: vector<4 x f32>) attribute
   // CHECK: metadata !"round.towardzero"
   // CHECK: metadata !"fpexcept.ignore"
   %1 = llvm.intr.experimental.constrained.fadd %v, %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nnan nsz float @llvm.experimental.constrained.fadd.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.fadd %s, %s tonearest strict {fastmathFlags = #llvm.fastmath<nnan, nsz>} : f32
   llvm.return
 }
 
@@ -1485,6 +1489,532 @@ llvm.func @experimental_constrained_fpext(%s: f32, %v: vector<4xf32>) attributes
   llvm.return
 }
 
+// CHECK-LABEL: @experimental_constrained_sqrt
+llvm.func @experimental_constrained_sqrt(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.sqrt.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.sqrt %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.sqrt.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.sqrt %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.sqrt.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.sqrt %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_sin
+llvm.func @experimental_constrained_sin(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.sin.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.sin %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.sin.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.sin %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.sin.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.sin %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_cos
+llvm.func @experimental_constrained_cos(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.cos.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.cos %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.cos.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.cos %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.cos.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.cos %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_tan
+llvm.func @experimental_constrained_tan(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.tan.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.tan %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.tan.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.tan %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.tan.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.tan %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_asin
+llvm.func @experimental_constrained_asin(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.asin.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.asin %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.asin.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.asin %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.asin.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.asin %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_acos
+llvm.func @experimental_constrained_acos(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.acos.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.acos %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.acos.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.acos %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.acos.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.acos %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_atan
+llvm.func @experimental_constrained_atan(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.atan.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.atan %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.atan.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.atan %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.atan.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.atan %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_sinh
+llvm.func @experimental_constrained_sinh(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.sinh.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.sinh %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.sinh.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.sinh %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.sinh.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.sinh %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_cosh
+llvm.func @experimental_constrained_cosh(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.cosh.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.cosh %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.cosh.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.cosh %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.cosh.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.cosh %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_tanh
+llvm.func @experimental_constrained_tanh(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.tanh.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.tanh %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.tanh.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.tanh %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.tanh.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.tanh %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_exp
+llvm.func @experimental_constrained_exp(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.exp.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.exp %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.exp.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.exp %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.exp.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.exp %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_exp2
+llvm.func @experimental_constrained_exp2(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.exp2.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.exp2 %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.exp2.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.exp2 %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.exp2.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.exp2 %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_log
+llvm.func @experimental_constrained_log(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.log.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.log %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.log.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.log %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.log.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.log %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_log10
+llvm.func @experimental_constrained_log10(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.log10.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.log10 %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.log10.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.log10 %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.log10.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.log10 %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_log2
+llvm.func @experimental_constrained_log2(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.log2.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.log2 %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.log2.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.log2 %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.log2.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.log2 %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_rint
+llvm.func @experimental_constrained_rint(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.rint.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.rint %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.rint.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.rint %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.rint.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.rint %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_nearbyint
+llvm.func @experimental_constrained_nearbyint(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.nearbyint.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.nearbyint %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.nearbyint.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.nearbyint %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.nearbyint.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.nearbyint %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_ceil
+llvm.func @experimental_constrained_ceil(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.ceil.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.ceil %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.ceil.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.ceil %v ignore : vector<4 x f32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_floor
+llvm.func @experimental_constrained_floor(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.floor.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.floor %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.floor.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.floor %v ignore : vector<4 x f32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_round
+llvm.func @experimental_constrained_round(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.round.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.round %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.round.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.round %v ignore : vector<4 x f32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_roundeven
+llvm.func @experimental_constrained_roundeven(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.roundeven.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.roundeven %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.roundeven.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.roundeven %v ignore : vector<4 x f32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_trunc
+llvm.func @experimental_constrained_trunc(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.trunc.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.trunc %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.trunc.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.trunc %v ignore : vector<4 x f32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_pow
+llvm.func @experimental_constrained_pow(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.pow.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.pow %s, %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.pow.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.pow %v, %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.pow.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.pow %s, %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_atan2
+llvm.func @experimental_constrained_atan2(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.atan2.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.atan2 %s, %s tonearest strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.atan2.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.atan2 %v, %v towardzero ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.atan2.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.atan2 %s, %s tonearest strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_maxnum
+llvm.func @experimental_constrained_maxnum(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.maxnum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.maxnum %s, %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.maxnum.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.maxnum %v, %v ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.maxnum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.maxnum %s, %s strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_minnum
+llvm.func @experimental_constrained_minnum(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.minnum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.minnum %s, %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.minnum.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.minnum %v, %v ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.minnum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.minnum %s, %s strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_maximum
+llvm.func @experimental_constrained_maximum(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.maximum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.maximum %s, %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.maximum.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.maximum %v, %v ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.maximum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.maximum %s, %s strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_minimum
+llvm.func @experimental_constrained_minimum(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.minimum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.minimum %s, %s strict : f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.minimum.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.minimum %v, %v ignore : vector<4 x f32>
+  // CHECK: call nsz float @llvm.experimental.constrained.minimum.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %2 = llvm.intr.experimental.constrained.minimum %s, %s strict {fastmathFlags = #llvm.fastmath<nsz>} : f32
+  llvm.return
+}
+
+
+// CHECK-LABEL: @experimental_constrained_powi
+llvm.func @experimental_constrained_powi(%s: f32, %e: i32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.powi.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.powi %s, %e tonearest strict : (f32, i32) -> f32
+  // CHECK: call <4 x float> @llvm.experimental.constrained.powi.v4f32(
+  // CHECK: metadata !"round.towardzero"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.powi %v, %e towardzero ignore : (vector<4 x f32>, i32) -> vector<4 x f32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_ldexp
+llvm.func @experimental_constrained_ldexp(%s: f32, %e: i32) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call float @llvm.experimental.constrained.ldexp.f32.i32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.ldexp %s, %e tonearest strict : (f32, i32) -> f32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_lrint
+llvm.func @experimental_constrained_lrint(%s: f32) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call i32 @llvm.experimental.constrained.lrint.i32.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.lrint %s tonearest strict : f32 to i32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_llrint
+llvm.func @experimental_constrained_llrint(%s: f32) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call i64 @llvm.experimental.constrained.llrint.i64.f32(
+  // CHECK: metadata !"round.tonearest"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.llrint %s tonearest strict : f32 to i64
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_lround
+llvm.func @experimental_constrained_lround(%s: f32) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call i32 @llvm.experimental.constrained.lround.i32.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.lround %s strict : f32 to i32
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_llround
+llvm.func @experimental_constrained_llround(%s: f32) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call i64 @llvm.experimental.constrained.llround.i64.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.llround %s strict : f32 to i64
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_fptosi
+llvm.func @experimental_constrained_fptosi(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call i32 @llvm.experimental.constrained.fptosi.i32.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.fptosi %s strict : f32 to i32
+  // CHECK: call <4 x i32> @llvm.experimental.constrained.fptosi.v4i32.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.fptosi %v ignore : vector<4 x f32> to vector<4 x i32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_fptoui
+llvm.func @experimental_constrained_fptoui(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call i32 @llvm.experimental.constrained.fptoui.i32.f32(
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.fptoui %s strict : f32 to i32
+  // CHECK: call <4 x i32> @llvm.experimental.constrained.fptoui.v4i32.v4f32(
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.fptoui %v ignore : vector<4 x f32> to vector<4 x i32>
+  llvm.return
+}
+
+// CHECK-LABEL: @experimental_constrained_fcmp
+llvm.func @experimental_constrained_fcmp(%s: f32, %v: vector<4 x f32>) attributes { passthrough = ["strictfp"] } {
+  // CHECK: call i1 @llvm.experimental.constrained.fcmp.f32(
+  // CHECK: metadata !"oeq"
+  // CHECK: metadata !"fpexcept.strict"
+  %0 = llvm.intr.experimental.constrained.fcmp oeq %s, %s strict : f32
+  // CHECK: call <4 x i1> @llvm.experimental.constrained.fcmps.v4f32(
+  // CHECK: metadata !"olt"
+  // CHECK: metadata !"fpexcept.ignore"
+  %1 = llvm.intr.experimental.constrained.fcmps olt %v, %v ignore : vector<4 x f32>
+  llvm.return
+}
+
 // CHECK-LABEL: @ucmp
 llvm.func @ucmp(%a: i32, %b: i32) -> i2 {
   // CHECK: call i2 @llvm.ucmp.i2.i32


        


More information about the Mlir-commits mailing list