[clang] [llvm] [HLSL][SPIRV] Added clamp intrinsic (PR #113394)

Adam Yang via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 7 14:53:17 PST 2024


https://github.com/adam-yang updated https://github.com/llvm/llvm-project/pull/113394

>From a10ce771dee98ee08a85606053dd27988747f2b0 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 14 Oct 2024 16:35:45 -0700
Subject: [PATCH 1/8] Added the intrinsics and modified the clang test

---
 clang/lib/CodeGen/CGBuiltin.cpp               |  25 ++-
 clang/test/CodeGenHLSL/builtins/clamp.hlsl    | 174 +++++++++---------
 llvm/include/llvm/IR/IntrinsicsSPIRV.td       |   3 +
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |   6 +
 4 files changed, 122 insertions(+), 86 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 0ef9058640db6a..819d0cb6b99489 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18813,10 +18813,27 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     if (auto *VecTy = Ty->getAs<VectorType>())
       Ty = VecTy->getElementType();
     IsUnsigned = Ty->isUnsignedIntegerType();
-    return Builder.CreateIntrinsic(
-        /*ReturnType=*/OpX->getType(),
-        IsUnsigned ? Intrinsic::dx_uclamp : Intrinsic::dx_clamp,
-        ArrayRef<Value *>{OpX, OpMin, OpMax}, nullptr, "dx.clamp");
+    switch (CGM.getTarget().getTriple().getArch()) {
+    case llvm::Triple::dxil: {
+      return Builder.CreateIntrinsic(
+          /*ReturnType=*/OpX->getType(),
+          IsUnsigned ? Intrinsic::dx_uclamp : Intrinsic::dx_clamp,
+          ArrayRef<Value *>{OpX, OpMin, OpMax}, nullptr, "dx.clamp");
+    } break;
+    case llvm::Triple::spirv: {
+      Intrinsic::ID Intr = Intrinsic::spv_sclamp;
+      if (Ty->isFloatingType()) {
+        Intr = Intrinsic::spv_fclamp;
+      } else if (IsUnsigned) {
+        Intr = Intrinsic::spv_uclamp;
+      }
+      return Builder.CreateIntrinsic(OpX->getType(), Intr,
+                                     ArrayRef<Value *>{OpX, OpMin, OpMax},
+                                     nullptr, "spv.clamp");
+    } break;
+    default:
+      llvm_unreachable("Intrinsic clamp not supported by target architecture");
+    }
   }
   case Builtin::BI__builtin_hlsl_cross: {
     Value *Op0 = EmitScalarExpr(E->getArg(0));
diff --git a/clang/test/CodeGenHLSL/builtins/clamp.hlsl b/clang/test/CodeGenHLSL/builtins/clamp.hlsl
index af8f6b9733a071..806e786ae70931 100644
--- a/clang/test/CodeGenHLSL/builtins/clamp.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/clamp.hlsl
@@ -1,133 +1,143 @@
 // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \
 // RUN:  -fnative-half-type -emit-llvm -disable-llvm-passes -o - | \
-// RUN:  FileCheck %s --check-prefixes=CHECK,NATIVE_HALF
+// RUN:  FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \
+// RUN:  -DSCLAMP="dx.clamp" -DUCLAMP="dx.uclamp" -DFCLAMP="dx.clamp" -DFNATTR="noundef"
 // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \
 // RUN:  -emit-llvm -disable-llvm-passes -o - | \
-// RUN:  FileCheck %s --check-prefixes=CHECK,NO_HALF
+// RUN:  FileCheck %s --check-prefixes=CHECK,NO_HALF \
+// RUN:  -DSCLAMP="dx.clamp" -DUCLAMP="dx.uclamp" -DFCLAMP="dx.clamp" -DFNATTR="noundef"
+// RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute %s \
+// RUN:  -fnative-half-type -emit-llvm -disable-llvm-passes -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \
+// RUN:  -DSCLAMP="spv.sclamp" -DUCLAMP="spv.uclamp" -DFCLAMP="spv.fclamp" -DFNATTR="spir_func noundef"
+// RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute %s \
+// RUN:  -emit-llvm -disable-llvm-passes -o - | \
+// RUN:  FileCheck %s --check-prefixes=CHECK,NO_HALF \
+// RUN:  -DSCLAMP="spv.sclamp" -DUCLAMP="spv.uclamp" -DFCLAMP="spv.fclamp" -DFNATTR="spir_func noundef"
 
 #ifdef __HLSL_ENABLE_16_BIT
-// NATIVE_HALF-LABEL: define noundef i16 @_Z16test_clamp_short
-// NATIVE_HALF: call i16 @llvm.dx.clamp.i16(
+// NATIVE_HALF: define [[FNATTR]] i16 @_Z16test_clamp_short
+// NATIVE_HALF: call i16 @llvm.[[SCLAMP]].i16(
 int16_t test_clamp_short(int16_t p0, int16_t p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <2 x i16> @_Z17test_clamp_short2
-// NATIVE_HALF: call <2 x i16> @llvm.dx.clamp.v2i16(
+// NATIVE_HALF: define [[FNATTR]] <2 x i16> @_Z17test_clamp_short2
+// NATIVE_HALF: call <2 x i16> @llvm.[[SCLAMP]].v2i16(
 int16_t2 test_clamp_short2(int16_t2 p0, int16_t2 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <3 x i16> @_Z17test_clamp_short3
-// NATIVE_HALF: call <3 x i16> @llvm.dx.clamp.v3i16
+// NATIVE_HALF: define [[FNATTR]] <3 x i16> @_Z17test_clamp_short3
+// NATIVE_HALF: call <3 x i16> @llvm.[[SCLAMP]].v3i16
 int16_t3 test_clamp_short3(int16_t3 p0, int16_t3 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <4 x i16> @_Z17test_clamp_short4
-// NATIVE_HALF: call <4 x i16> @llvm.dx.clamp.v4i16
+// NATIVE_HALF: define [[FNATTR]] <4 x i16> @_Z17test_clamp_short4
+// NATIVE_HALF: call <4 x i16> @llvm.[[SCLAMP]].v4i16
 int16_t4 test_clamp_short4(int16_t4 p0, int16_t4 p1) { return clamp(p0, p1,p1); }
 
-// NATIVE_HALF-LABEL: define noundef i16 @_Z17test_clamp_ushort
-// NATIVE_HALF: call i16 @llvm.dx.uclamp.i16(
+// NATIVE_HALF: define [[FNATTR]] i16 @_Z17test_clamp_ushort
+// NATIVE_HALF: call i16 @llvm.[[UCLAMP]].i16(
 uint16_t test_clamp_ushort(uint16_t p0, uint16_t p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <2 x i16> @_Z18test_clamp_ushort2
-// NATIVE_HALF: call <2 x i16> @llvm.dx.uclamp.v2i16
+// NATIVE_HALF: define [[FNATTR]] <2 x i16> @_Z18test_clamp_ushort2
+// NATIVE_HALF: call <2 x i16> @llvm.[[UCLAMP]].v2i16
 uint16_t2 test_clamp_ushort2(uint16_t2 p0, uint16_t2 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <3 x i16> @_Z18test_clamp_ushort3
-// NATIVE_HALF: call <3 x i16> @llvm.dx.uclamp.v3i16
+// NATIVE_HALF: define [[FNATTR]] <3 x i16> @_Z18test_clamp_ushort3
+// NATIVE_HALF: call <3 x i16> @llvm.[[UCLAMP]].v3i16
 uint16_t3 test_clamp_ushort3(uint16_t3 p0, uint16_t3 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <4 x i16> @_Z18test_clamp_ushort4
-// NATIVE_HALF: call <4 x i16> @llvm.dx.uclamp.v4i16
+// NATIVE_HALF: define [[FNATTR]] <4 x i16> @_Z18test_clamp_ushort4
+// NATIVE_HALF: call <4 x i16> @llvm.[[UCLAMP]].v4i16
 uint16_t4 test_clamp_ushort4(uint16_t4 p0, uint16_t4 p1) { return clamp(p0, p1,p1); }
 #endif
 
-// CHECK-LABEL: define noundef i32 @_Z14test_clamp_int
-// CHECK: call i32 @llvm.dx.clamp.i32(
+// CHECK: define [[FNATTR]] i32 @_Z14test_clamp_int
+// CHECK: call i32 @llvm.[[SCLAMP]].i32(
 int test_clamp_int(int p0, int p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <2 x i32> @_Z15test_clamp_int2
-// CHECK: call <2 x i32> @llvm.dx.clamp.v2i32
+// CHECK: define [[FNATTR]] <2 x i32> @_Z15test_clamp_int2
+// CHECK: call <2 x i32> @llvm.[[SCLAMP]].v2i32
 int2 test_clamp_int2(int2 p0, int2 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <3 x i32> @_Z15test_clamp_int3
-// CHECK: call <3 x i32> @llvm.dx.clamp.v3i32
+// CHECK: define [[FNATTR]] <3 x i32> @_Z15test_clamp_int3
+// CHECK: call <3 x i32> @llvm.[[SCLAMP]].v3i32
 int3 test_clamp_int3(int3 p0, int3 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <4 x i32> @_Z15test_clamp_int4
-// CHECK: call <4 x i32> @llvm.dx.clamp.v4i32
+// CHECK: define [[FNATTR]] <4 x i32> @_Z15test_clamp_int4
+// CHECK: call <4 x i32> @llvm.[[SCLAMP]].v4i32
 int4 test_clamp_int4(int4 p0, int4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK-LABEL: define noundef i32 @_Z15test_clamp_uint
-// CHECK: call i32 @llvm.dx.uclamp.i32(
+// CHECK: define [[FNATTR]] i32 @_Z15test_clamp_uint
+// CHECK: call i32 @llvm.[[UCLAMP]].i32(
 int test_clamp_uint(uint p0, uint p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <2 x i32> @_Z16test_clamp_uint2
-// CHECK: call <2 x i32> @llvm.dx.uclamp.v2i32
+// CHECK: define [[FNATTR]] <2 x i32> @_Z16test_clamp_uint2
+// CHECK: call <2 x i32> @llvm.[[UCLAMP]].v2i32
 uint2 test_clamp_uint2(uint2 p0, uint2 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <3 x i32> @_Z16test_clamp_uint3
-// CHECK: call <3 x i32> @llvm.dx.uclamp.v3i32
+// CHECK: define [[FNATTR]] <3 x i32> @_Z16test_clamp_uint3
+// CHECK: call <3 x i32> @llvm.[[UCLAMP]].v3i32
 uint3 test_clamp_uint3(uint3 p0, uint3 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <4 x i32> @_Z16test_clamp_uint4
-// CHECK: call <4 x i32> @llvm.dx.uclamp.v4i32
+// CHECK: define [[FNATTR]] <4 x i32> @_Z16test_clamp_uint4
+// CHECK: call <4 x i32> @llvm.[[UCLAMP]].v4i32
 uint4 test_clamp_uint4(uint4 p0, uint4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK-LABEL: define noundef i64 @_Z15test_clamp_long
-// CHECK: call i64 @llvm.dx.clamp.i64(
+// CHECK: define [[FNATTR]] i64 @_Z15test_clamp_long
+// CHECK: call i64 @llvm.[[SCLAMP]].i64(
 int64_t test_clamp_long(int64_t p0, int64_t p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <2 x i64> @_Z16test_clamp_long2
-// CHECK: call <2 x i64> @llvm.dx.clamp.v2i64
+// CHECK: define [[FNATTR]] <2 x i64> @_Z16test_clamp_long2
+// CHECK: call <2 x i64> @llvm.[[SCLAMP]].v2i64
 int64_t2 test_clamp_long2(int64_t2 p0, int64_t2 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <3 x i64> @_Z16test_clamp_long3
-// CHECK: call <3 x i64> @llvm.dx.clamp.v3i64
+// CHECK: define [[FNATTR]] <3 x i64> @_Z16test_clamp_long3
+// CHECK: call <3 x i64> @llvm.[[SCLAMP]].v3i64
 int64_t3 test_clamp_long3(int64_t3 p0, int64_t3 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <4 x i64> @_Z16test_clamp_long4
-// CHECK: call <4 x i64> @llvm.dx.clamp.v4i64
+// CHECK: define [[FNATTR]] <4 x i64> @_Z16test_clamp_long4
+// CHECK: call <4 x i64> @llvm.[[SCLAMP]].v4i64
 int64_t4 test_clamp_long4(int64_t4 p0, int64_t4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK-LABEL: define noundef i64 @_Z16test_clamp_ulong
-// CHECK: call i64 @llvm.dx.uclamp.i64(
+// CHECK: define [[FNATTR]] i64 @_Z16test_clamp_ulong
+// CHECK: call i64 @llvm.[[UCLAMP]].i64(
 uint64_t test_clamp_ulong(uint64_t p0, uint64_t p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <2 x i64> @_Z17test_clamp_ulong2
-// CHECK: call <2 x i64> @llvm.dx.uclamp.v2i64
+// CHECK: define [[FNATTR]] <2 x i64> @_Z17test_clamp_ulong2
+// CHECK: call <2 x i64> @llvm.[[UCLAMP]].v2i64
 uint64_t2 test_clamp_ulong2(uint64_t2 p0, uint64_t2 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <3 x i64> @_Z17test_clamp_ulong3
-// CHECK: call <3 x i64> @llvm.dx.uclamp.v3i64
+// CHECK: define [[FNATTR]] <3 x i64> @_Z17test_clamp_ulong3
+// CHECK: call <3 x i64> @llvm.[[UCLAMP]].v3i64
 uint64_t3 test_clamp_ulong3(uint64_t3 p0, uint64_t3 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <4 x i64> @_Z17test_clamp_ulong4
-// CHECK: call <4 x i64> @llvm.dx.uclamp.v4i64
+// CHECK: define [[FNATTR]] <4 x i64> @_Z17test_clamp_ulong4
+// CHECK: call <4 x i64> @llvm.[[UCLAMP]].v4i64
 uint64_t4 test_clamp_ulong4(uint64_t4 p0, uint64_t4 p1) { return clamp(p0, p1,p1); }
 
-// NATIVE_HALF-LABEL: define noundef half @_Z15test_clamp_half
-// NATIVE_HALF: call half @llvm.dx.clamp.f16(
-// NO_HALF-LABEL: define noundef float @_Z15test_clamp_half
-// NO_HALF: call float @llvm.dx.clamp.f32(
+// NATIVE_HALF: define [[FNATTR]] half @_Z15test_clamp_half
+// NATIVE_HALF: call half @llvm.[[FCLAMP]].f16(
+// NO_HALF: define [[FNATTR]] float @_Z15test_clamp_half
+// NO_HALF: call float @llvm.[[FCLAMP]].f32(
 half test_clamp_half(half p0, half p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <2 x half> @_Z16test_clamp_half2
-// NATIVE_HALF: call <2 x half> @llvm.dx.clamp.v2f16
-// NO_HALF-LABEL: define noundef <2 x float> @_Z16test_clamp_half2
-// NO_HALF: call <2 x float> @llvm.dx.clamp.v2f32(
+// NATIVE_HALF: define [[FNATTR]] <2 x half> @_Z16test_clamp_half2
+// NATIVE_HALF: call <2 x half> @llvm.[[FCLAMP]].v2f16
+// NO_HALF: define [[FNATTR]] <2 x float> @_Z16test_clamp_half2
+// NO_HALF: call <2 x float> @llvm.[[FCLAMP]].v2f32(
 half2 test_clamp_half2(half2 p0, half2 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <3 x half> @_Z16test_clamp_half3
-// NATIVE_HALF: call <3 x half> @llvm.dx.clamp.v3f16
-// NO_HALF-LABEL: define noundef <3 x float> @_Z16test_clamp_half3
-// NO_HALF: call <3 x float> @llvm.dx.clamp.v3f32(
+// NATIVE_HALF: define [[FNATTR]] <3 x half> @_Z16test_clamp_half3
+// NATIVE_HALF: call <3 x half> @llvm.[[FCLAMP]].v3f16
+// NO_HALF: define [[FNATTR]] <3 x float> @_Z16test_clamp_half3
+// NO_HALF: call <3 x float> @llvm.[[FCLAMP]].v3f32(
 half3 test_clamp_half3(half3 p0, half3 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF-LABEL: define noundef <4 x half> @_Z16test_clamp_half4
-// NATIVE_HALF: call <4 x half> @llvm.dx.clamp.v4f16
-// NO_HALF-LABEL: define noundef <4 x float> @_Z16test_clamp_half4
-// NO_HALF: call <4 x float> @llvm.dx.clamp.v4f32(
+// NATIVE_HALF: define [[FNATTR]] <4 x half> @_Z16test_clamp_half4
+// NATIVE_HALF: call <4 x half> @llvm.[[FCLAMP]].v4f16
+// NO_HALF: define [[FNATTR]] <4 x float> @_Z16test_clamp_half4
+// NO_HALF: call <4 x float> @llvm.[[FCLAMP]].v4f32(
 half4 test_clamp_half4(half4 p0, half4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK-LABEL: define noundef float @_Z16test_clamp_float
-// CHECK: call float @llvm.dx.clamp.f32(
+// CHECK: define [[FNATTR]] float @_Z16test_clamp_float
+// CHECK: call float @llvm.[[FCLAMP]].f32(
 float test_clamp_float(float p0, float p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <2 x float> @_Z17test_clamp_float2
-// CHECK: call <2 x float> @llvm.dx.clamp.v2f32
+// CHECK: define [[FNATTR]] <2 x float> @_Z17test_clamp_float2
+// CHECK: call <2 x float> @llvm.[[FCLAMP]].v2f32
 float2 test_clamp_float2(float2 p0, float2 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <3 x float> @_Z17test_clamp_float3
-// CHECK: call <3 x float> @llvm.dx.clamp.v3f32
+// CHECK: define [[FNATTR]] <3 x float> @_Z17test_clamp_float3
+// CHECK: call <3 x float> @llvm.[[FCLAMP]].v3f32
 float3 test_clamp_float3(float3 p0, float3 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <4 x float> @_Z17test_clamp_float4
-// CHECK: call <4 x float> @llvm.dx.clamp.v4f32
+// CHECK: define [[FNATTR]] <4 x float> @_Z17test_clamp_float4
+// CHECK: call <4 x float> @llvm.[[FCLAMP]].v4f32
 float4 test_clamp_float4(float4 p0, float4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK-LABEL: define noundef double @_Z17test_clamp_double
-// CHECK: call double @llvm.dx.clamp.f64(
+// CHECK: define [[FNATTR]] double @_Z17test_clamp_double
+// CHECK: call double @llvm.[[FCLAMP]].f64(
 double test_clamp_double(double p0, double p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <2 x double> @_Z18test_clamp_double2
-// CHECK: call <2 x double> @llvm.dx.clamp.v2f64
+// CHECK: define [[FNATTR]] <2 x double> @_Z18test_clamp_double2
+// CHECK: call <2 x double> @llvm.[[FCLAMP]].v2f64
 double2 test_clamp_double2(double2 p0, double2 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <3 x double> @_Z18test_clamp_double3
-// CHECK: call <3 x double> @llvm.dx.clamp.v3f64
+// CHECK: define [[FNATTR]] <3 x double> @_Z18test_clamp_double3
+// CHECK: call <3 x double> @llvm.[[FCLAMP]].v3f64
 double3 test_clamp_double3(double3 p0, double3 p1) { return clamp(p0, p1,p1); }
-// CHECK-LABEL: define noundef <4 x double> @_Z18test_clamp_double4
-// CHECK: call <4 x double> @llvm.dx.clamp.v4f64
+// CHECK: define [[FNATTR]] <4 x double> @_Z18test_clamp_double4
+// CHECK: call <4 x double> @llvm.[[FCLAMP]].v4f64
 double4 test_clamp_double4(double4 p0, double4 p1) { return clamp(p0, p1,p1); }
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index e93d6fa83de61b..e471c81d4516fd 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -90,6 +90,9 @@ let TargetPrefix = "spv" in {
   def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
   def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
+  def int_spv_uclamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_sclamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_fclamp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
 
   // Create resource handle given the binding information. Returns a 
   // type appropriate for the kind of resource given the set id, binding id,
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 414583aea91e64..4cc2136d4080f4 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2739,6 +2739,12 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
   } break;
   case Intrinsic::spv_saturate:
     return selectSaturate(ResVReg, ResType, I);
+  case Intrinsic::spv_fclamp:
+    return selectExtInst(ResVReg, ResType, I, CL::fclamp, GL::FClamp);
+  case Intrinsic::spv_uclamp:
+    return selectExtInst(ResVReg, ResType, I, CL::u_clamp, GL::UClamp);
+  case Intrinsic::spv_sclamp:
+    return selectExtInst(ResVReg, ResType, I, CL::s_clamp, GL::SClamp);
   case Intrinsic::spv_wave_is_first_lane: {
     SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
     return BuildMI(BB, I, I.getDebugLoc(),

>From 80980b6b0355ec31305729fa52e989b7c124932f Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Tue, 22 Oct 2024 15:57:52 -0700
Subject: [PATCH 2/8] LLC tests

---
 .../SPIRV/hlsl-intrinsics/clamp-vec.ll        | 130 ++++++++++++++++++
 .../CodeGen/SPIRV/hlsl-intrinsics/clamp.ll    | 122 ++++++++++++++++
 2 files changed, 252 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll

diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
new file mode 100644
index 00000000000000..6af5bf2fc1812b
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
@@ -0,0 +1,130 @@
+; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+
+; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+
+; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
+; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+
+; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+
+; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
+; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
+; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
+
+; CHECK-LABEL: Begin function test_sclamp_v4i16
+define noundef <4 x i16> @test_sclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext_glsl]] SClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i32
+define noundef <4 x i32> @test_sclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext_glsl]] SClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i64
+define noundef <4 x i64> @test_sclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext_glsl]] SClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_v4half
+define noundef <4 x half> @test_fclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] FClamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
+  %0 = call <4 x half> @llvm.spv.fclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
+  ret <4 x half> %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_v4float
+define noundef <4 x float> @test_fclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] FClamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
+  %0 = call <4 x float> @llvm.spv.fclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_v4double
+define noundef <4 x double> @test_fclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext_glsl]] FClamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
+  %0 = call <4 x double> @llvm.spv.fclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
+  ret <4 x double> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i16
+define noundef <4 x i16> @test_uclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext_glsl]] UClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i32
+define noundef <4 x i32> @test_uclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext_glsl]] UClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i64
+define noundef <4 x i64> @test_uclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext_glsl]] UClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+declare <4 x half> @llvm.spv.fclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
+declare <4 x float> @llvm.spv.fclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x double> @llvm.spv.fclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
+declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+declare <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
new file mode 100644
index 00000000000000..cdc58f7b742505
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
@@ -0,0 +1,122 @@
+; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+
+; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+
+; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
+; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+
+; CHECK-LABEL: Begin function test_sclamp_i16
+define noundef i16 @test_sclamp_i16(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
+entry:
+  ; CHECK: %[[#i16_arg0:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg1:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg2:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext_glsl]] SClamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
+  %0 = call i16 @llvm.spv.sclamp.i16(i16 %a, i16 %b, i16 %c)
+  ret i16 %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_i32
+define noundef i32 @test_sclamp_i32(i32 noundef %a, i32 noundef %b, i32 noundef %c) {
+entry:
+  ; CHECK: %[[#i32_arg0:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg1:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg2:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext_glsl]] SClamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
+  %0 = call i32 @llvm.spv.sclamp.i32(i32 %a, i32 %b, i32 %c)
+  ret i32 %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_i64
+define noundef i64 @test_sclamp_i64(i64 noundef %a, i64 noundef %b, i64 noundef %c) {
+entry:
+  ; CHECK: %[[#i64_arg0:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg1:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg2:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext_glsl]] SClamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
+  %0 = call i64 @llvm.spv.sclamp.i64(i64 %a, i64 %b, i64 %c)
+  ret i64 %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_half
+define noundef half @test_fclamp_half(half noundef %a, half noundef %b, half noundef %c) {
+entry:
+  ; CHECK: %[[#f16_arg0:]] = OpFunctionParameter %[[#float_16]]
+  ; CHECK: %[[#f16_arg1:]] = OpFunctionParameter %[[#float_16]]
+  ; CHECK: %[[#f16_arg2:]] = OpFunctionParameter %[[#float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] FClamp %[[#f16_arg0]] %[[#f16_arg1]] %[[#f16_arg2]]
+  %0 = call half @llvm.spv.fclamp.f16(half %a, half %b, half %c)
+  ret half %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_float
+define noundef float @test_fclamp_float(float noundef %a, float noundef %b, float noundef %c) {
+entry:
+  ; CHECK: %[[#f32_arg0:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#f32_arg1:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#f32_arg2:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] FClamp %[[#f32_arg0]] %[[#f32_arg1]] %[[#f32_arg2]]
+  %0 = call float @llvm.spv.fclamp.f32(float %a, float %b, float %c)
+  ret float %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_double
+define noundef double @test_fclamp_double(double noundef %a, double noundef %b, double noundef %c) {
+entry:
+  ; CHECK: %[[#f64_arg0:]] = OpFunctionParameter %[[#float_64]]
+  ; CHECK: %[[#f64_arg1:]] = OpFunctionParameter %[[#float_64]]
+  ; CHECK: %[[#f64_arg2:]] = OpFunctionParameter %[[#float_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext_glsl]] FClamp %[[#f64_arg0]] %[[#f64_arg1]] %[[#f64_arg2]]
+  %0 = call double @llvm.spv.fclamp.f64(double %a, double %b, double %c)
+  ret double %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_i16
+define noundef i16 @test_uclamp_i16(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
+entry:
+  ; CHECK: %[[#i16_arg0:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg1:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg2:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext_glsl]] UClamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
+  %0 = call i16 @llvm.spv.uclamp.i16(i16 %a, i16 %b, i16 %c)
+  ret i16 %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_i32
+define noundef i32 @test_uclamp_i32(i32 noundef %a, i32 noundef %b, i32 noundef %c) {
+entry:
+  ; CHECK: %[[#i32_arg0:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg1:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg2:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext_glsl]] UClamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
+  %0 = call i32 @llvm.spv.uclamp.i32(i32 %a, i32 %b, i32 %c)
+  ret i32 %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_i64
+define noundef i64 @test_uclamp_i64(i64 noundef %a, i64 noundef %b, i64 noundef %c) {
+entry:
+  ; CHECK: %[[#i64_arg0:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg1:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg2:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext_glsl]] UClamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
+  %0 = call i64 @llvm.spv.uclamp.i64(i64 %a, i64 %b, i64 %c)
+  ret i64 %0
+}
+
+declare half @llvm.spv.fclamp.f16(half, half, half)
+declare float @llvm.spv.fclamp.f32(float, float, float)
+declare double @llvm.spv.fclamp.f64(double, double, double)
+declare i16 @llvm.spv.sclamp.i16(i16, i16, i16)
+declare i32 @llvm.spv.sclamp.i32(i32, i32, i32)
+declare i64 @llvm.spv.sclamp.i64(i64, i64, i64)
+declare i16 @llvm.spv.uclamp.i16(i16, i16, i16)
+declare i32 @llvm.spv.uclamp.i32(i32, i32, i32)
+declare i64 @llvm.spv.uclamp.i64(i64, i64, i64)
+

>From 510f4092be9be1bc1ff40f2fc4744316def2e674 Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Tue, 22 Oct 2024 16:02:27 -0700
Subject: [PATCH 3/8] Testing opencl too

---
 .../SPIRV/hlsl-intrinsics/clamp-vec.ll        |  20 +--
 .../CodeGen/SPIRV/hlsl-intrinsics/clamp.ll    |  20 +--
 llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll   | 132 ++++++++++++++++++
 llvm/test/CodeGen/SPIRV/opencl/clamp.ll       | 124 ++++++++++++++++
 4 files changed, 276 insertions(+), 20 deletions(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/clamp.ll

diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
index 6af5bf2fc1812b..cd0111c399abf7 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
@@ -1,7 +1,7 @@
 ; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
-; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#op_ext:]] = OpExtInstImport "GLSL.std.450"
 
 ; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
 ; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
@@ -25,7 +25,7 @@ entry:
   ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
   ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
   ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext_glsl]] SClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] SClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
   %0 = call <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
   ret <4 x i16> %0
 }
@@ -36,7 +36,7 @@ entry:
   ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
   ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
   ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext_glsl]] SClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] SClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
   %0 = call <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
   ret <4 x i32> %0
 }
@@ -47,7 +47,7 @@ entry:
   ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
   ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
   ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext_glsl]] SClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] SClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
   %0 = call <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
   ret <4 x i64> %0
 }
@@ -58,7 +58,7 @@ entry:
   ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
   ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
   ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] FClamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] FClamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
   %0 = call <4 x half> @llvm.spv.fclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
   ret <4 x half> %0
 }
@@ -69,7 +69,7 @@ entry:
   ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
   ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
   ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] FClamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] FClamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
   %0 = call <4 x float> @llvm.spv.fclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
   ret <4 x float> %0
 }
@@ -80,7 +80,7 @@ entry:
   ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
   ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
   ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext_glsl]] FClamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] FClamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
   %0 = call <4 x double> @llvm.spv.fclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
   ret <4 x double> %0
 }
@@ -91,7 +91,7 @@ entry:
   ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
   ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
   ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext_glsl]] UClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] UClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
   %0 = call <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
   ret <4 x i16> %0
 }
@@ -102,7 +102,7 @@ entry:
   ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
   ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
   ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext_glsl]] UClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] UClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
   %0 = call <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
   ret <4 x i32> %0
 }
@@ -113,7 +113,7 @@ entry:
   ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
   ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
   ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext_glsl]] UClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] UClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
   %0 = call <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
   ret <4 x i64> %0
 }
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
index cdc58f7b742505..61b89e16f2bd48 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
@@ -1,7 +1,7 @@
 ; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
-; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#op_ext:]] = OpExtInstImport "GLSL.std.450"
 
 ; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
 ; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
@@ -17,7 +17,7 @@ entry:
   ; CHECK: %[[#i16_arg0:]] = OpFunctionParameter %[[#int_16]]
   ; CHECK: %[[#i16_arg1:]] = OpFunctionParameter %[[#int_16]]
   ; CHECK: %[[#i16_arg2:]] = OpFunctionParameter %[[#int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext_glsl]] SClamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext]] SClamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
   %0 = call i16 @llvm.spv.sclamp.i16(i16 %a, i16 %b, i16 %c)
   ret i16 %0
 }
@@ -28,7 +28,7 @@ entry:
   ; CHECK: %[[#i32_arg0:]] = OpFunctionParameter %[[#int_32]]
   ; CHECK: %[[#i32_arg1:]] = OpFunctionParameter %[[#int_32]]
   ; CHECK: %[[#i32_arg2:]] = OpFunctionParameter %[[#int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext_glsl]] SClamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext]] SClamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
   %0 = call i32 @llvm.spv.sclamp.i32(i32 %a, i32 %b, i32 %c)
   ret i32 %0
 }
@@ -39,7 +39,7 @@ entry:
   ; CHECK: %[[#i64_arg0:]] = OpFunctionParameter %[[#int_64]]
   ; CHECK: %[[#i64_arg1:]] = OpFunctionParameter %[[#int_64]]
   ; CHECK: %[[#i64_arg2:]] = OpFunctionParameter %[[#int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext_glsl]] SClamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext]] SClamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
   %0 = call i64 @llvm.spv.sclamp.i64(i64 %a, i64 %b, i64 %c)
   ret i64 %0
 }
@@ -50,7 +50,7 @@ entry:
   ; CHECK: %[[#f16_arg0:]] = OpFunctionParameter %[[#float_16]]
   ; CHECK: %[[#f16_arg1:]] = OpFunctionParameter %[[#float_16]]
   ; CHECK: %[[#f16_arg2:]] = OpFunctionParameter %[[#float_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] FClamp %[[#f16_arg0]] %[[#f16_arg1]] %[[#f16_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext]] FClamp %[[#f16_arg0]] %[[#f16_arg1]] %[[#f16_arg2]]
   %0 = call half @llvm.spv.fclamp.f16(half %a, half %b, half %c)
   ret half %0
 }
@@ -61,7 +61,7 @@ entry:
   ; CHECK: %[[#f32_arg0:]] = OpFunctionParameter %[[#float_32]]
   ; CHECK: %[[#f32_arg1:]] = OpFunctionParameter %[[#float_32]]
   ; CHECK: %[[#f32_arg2:]] = OpFunctionParameter %[[#float_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] FClamp %[[#f32_arg0]] %[[#f32_arg1]] %[[#f32_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext]] FClamp %[[#f32_arg0]] %[[#f32_arg1]] %[[#f32_arg2]]
   %0 = call float @llvm.spv.fclamp.f32(float %a, float %b, float %c)
   ret float %0
 }
@@ -72,7 +72,7 @@ entry:
   ; CHECK: %[[#f64_arg0:]] = OpFunctionParameter %[[#float_64]]
   ; CHECK: %[[#f64_arg1:]] = OpFunctionParameter %[[#float_64]]
   ; CHECK: %[[#f64_arg2:]] = OpFunctionParameter %[[#float_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext_glsl]] FClamp %[[#f64_arg0]] %[[#f64_arg1]] %[[#f64_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext]] FClamp %[[#f64_arg0]] %[[#f64_arg1]] %[[#f64_arg2]]
   %0 = call double @llvm.spv.fclamp.f64(double %a, double %b, double %c)
   ret double %0
 }
@@ -83,7 +83,7 @@ entry:
   ; CHECK: %[[#i16_arg0:]] = OpFunctionParameter %[[#int_16]]
   ; CHECK: %[[#i16_arg1:]] = OpFunctionParameter %[[#int_16]]
   ; CHECK: %[[#i16_arg2:]] = OpFunctionParameter %[[#int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext_glsl]] UClamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext]] UClamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
   %0 = call i16 @llvm.spv.uclamp.i16(i16 %a, i16 %b, i16 %c)
   ret i16 %0
 }
@@ -94,7 +94,7 @@ entry:
   ; CHECK: %[[#i32_arg0:]] = OpFunctionParameter %[[#int_32]]
   ; CHECK: %[[#i32_arg1:]] = OpFunctionParameter %[[#int_32]]
   ; CHECK: %[[#i32_arg2:]] = OpFunctionParameter %[[#int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext_glsl]] UClamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext]] UClamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
   %0 = call i32 @llvm.spv.uclamp.i32(i32 %a, i32 %b, i32 %c)
   ret i32 %0
 }
@@ -105,7 +105,7 @@ entry:
   ; CHECK: %[[#i64_arg0:]] = OpFunctionParameter %[[#int_64]]
   ; CHECK: %[[#i64_arg1:]] = OpFunctionParameter %[[#int_64]]
   ; CHECK: %[[#i64_arg2:]] = OpFunctionParameter %[[#int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext_glsl]] UClamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext]] UClamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
   %0 = call i64 @llvm.spv.uclamp.i64(i64 %a, i64 %b, i64 %c)
   ret i64 %0
 }
diff --git a/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll b/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
new file mode 100644
index 00000000000000..35f5559c46921e
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
@@ -0,0 +1,132 @@
+; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#op_ext:]] = OpExtInstImport "OpenCL.std"
+
+; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+
+; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
+; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+
+; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+
+; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
+; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
+; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
+
+; CHECK-LABEL: Begin function test_sclamp_v4i16
+define noundef <4 x i16> @test_sclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] s_clamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i32
+define noundef <4 x i32> @test_sclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] s_clamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i64
+define noundef <4 x i64> @test_sclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] s_clamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_v4half
+define noundef <4 x half> @test_fclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] fclamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
+  %0 = call <4 x half> @llvm.spv.fclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
+  ret <4 x half> %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_v4float
+define noundef <4 x float> @test_fclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] fclamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
+  %0 = call <4 x float> @llvm.spv.fclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_v4double
+define noundef <4 x double> @test_fclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] fclamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
+  %0 = call <4 x double> @llvm.spv.fclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
+  ret <4 x double> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i16
+define noundef <4 x i16> @test_uclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] u_clamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i32
+define noundef <4 x i32> @test_uclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] u_clamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i64
+define noundef <4 x i64> @test_uclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] u_clamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+declare <4 x half> @llvm.spv.fclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
+declare <4 x float> @llvm.spv.fclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x double> @llvm.spv.fclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
+declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+declare <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+
diff --git a/llvm/test/CodeGen/SPIRV/opencl/clamp.ll b/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
new file mode 100644
index 00000000000000..f6500442042cd9
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
@@ -0,0 +1,124 @@
+; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#op_ext:]] = OpExtInstImport "OpenCL.std"
+
+; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+
+; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
+; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+
+; CHECK-LABEL: Begin function test_sclamp_i16
+define noundef i16 @test_sclamp_i16(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
+entry:
+  ; CHECK: %[[#i16_arg0:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg1:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg2:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext]] s_clamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
+  %0 = call i16 @llvm.spv.sclamp.i16(i16 %a, i16 %b, i16 %c)
+  ret i16 %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_i32
+define noundef i32 @test_sclamp_i32(i32 noundef %a, i32 noundef %b, i32 noundef %c) {
+entry:
+  ; CHECK: %[[#i32_arg0:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg1:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg2:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext]] s_clamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
+  %0 = call i32 @llvm.spv.sclamp.i32(i32 %a, i32 %b, i32 %c)
+  ret i32 %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_i64
+define noundef i64 @test_sclamp_i64(i64 noundef %a, i64 noundef %b, i64 noundef %c) {
+entry:
+  ; CHECK: %[[#i64_arg0:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg1:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg2:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext]] s_clamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
+  %0 = call i64 @llvm.spv.sclamp.i64(i64 %a, i64 %b, i64 %c)
+  ret i64 %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_half
+define noundef half @test_fclamp_half(half noundef %a, half noundef %b, half noundef %c) {
+entry:
+  ; CHECK: %[[#f16_arg0:]] = OpFunctionParameter %[[#float_16]]
+  ; CHECK: %[[#f16_arg1:]] = OpFunctionParameter %[[#float_16]]
+  ; CHECK: %[[#f16_arg2:]] = OpFunctionParameter %[[#float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext]] fclamp %[[#f16_arg0]] %[[#f16_arg1]] %[[#f16_arg2]]
+  %0 = call half @llvm.spv.fclamp.f16(half %a, half %b, half %c)
+  ret half %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_float
+define noundef float @test_fclamp_float(float noundef %a, float noundef %b, float noundef %c) {
+entry:
+  ; CHECK: %[[#f32_arg0:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#f32_arg1:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#f32_arg2:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext]] fclamp %[[#f32_arg0]] %[[#f32_arg1]] %[[#f32_arg2]]
+  %0 = call float @llvm.spv.fclamp.f32(float %a, float %b, float %c)
+  ret float %0
+}
+
+; CHECK-LABEL: Begin function test_fclamp_double
+define noundef double @test_fclamp_double(double noundef %a, double noundef %b, double noundef %c) {
+entry:
+  ; CHECK: %[[#f64_arg0:]] = OpFunctionParameter %[[#float_64]]
+  ; CHECK: %[[#f64_arg1:]] = OpFunctionParameter %[[#float_64]]
+  ; CHECK: %[[#f64_arg2:]] = OpFunctionParameter %[[#float_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext]] fclamp %[[#f64_arg0]] %[[#f64_arg1]] %[[#f64_arg2]]
+  %0 = call double @llvm.spv.fclamp.f64(double %a, double %b, double %c)
+  ret double %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_i16
+define noundef i16 @test_uclamp_i16(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
+entry:
+  ; CHECK: %[[#i16_arg0:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg1:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#i16_arg2:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_16]] %[[#op_ext]] u_clamp %[[#i16_arg0]] %[[#i16_arg1]] %[[#i16_arg2]]
+  %0 = call i16 @llvm.spv.uclamp.i16(i16 %a, i16 %b, i16 %c)
+  ret i16 %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_i32
+define noundef i32 @test_uclamp_i32(i32 noundef %a, i32 noundef %b, i32 noundef %c) {
+entry:
+  ; CHECK: %[[#i32_arg0:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg1:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#i32_arg2:]] = OpFunctionParameter %[[#int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext]] u_clamp %[[#i32_arg0]] %[[#i32_arg1]] %[[#i32_arg2]]
+  %0 = call i32 @llvm.spv.uclamp.i32(i32 %a, i32 %b, i32 %c)
+  ret i32 %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_i64
+define noundef i64 @test_uclamp_i64(i64 noundef %a, i64 noundef %b, i64 noundef %c) {
+entry:
+  ; CHECK: %[[#i64_arg0:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg1:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#i64_arg2:]] = OpFunctionParameter %[[#int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#int_64]] %[[#op_ext]] u_clamp %[[#i64_arg0]] %[[#i64_arg1]] %[[#i64_arg2]]
+  %0 = call i64 @llvm.spv.uclamp.i64(i64 %a, i64 %b, i64 %c)
+  ret i64 %0
+}
+
+declare half @llvm.spv.fclamp.f16(half, half, half)
+declare float @llvm.spv.fclamp.f32(float, float, float)
+declare double @llvm.spv.fclamp.f64(double, double, double)
+declare i16 @llvm.spv.sclamp.i16(i16, i16, i16)
+declare i32 @llvm.spv.sclamp.i32(i32, i32, i32)
+declare i64 @llvm.spv.sclamp.i64(i64, i64, i64)
+declare i16 @llvm.spv.uclamp.i16(i16, i16, i16)
+declare i32 @llvm.spv.uclamp.i32(i32, i32, i32)
+declare i64 @llvm.spv.uclamp.i64(i64, i64, i64)
+

>From 299886cd46228dce730a6c85f1cd488a0af59ccf Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Tue, 22 Oct 2024 16:10:53 -0700
Subject: [PATCH 4/8] Fixed a weirdness in the CG

---
 clang/lib/CodeGen/CGBuiltin.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 819d0cb6b99489..03d0e64c1c2e1d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18809,10 +18809,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Value *OpMax = EmitScalarExpr(E->getArg(2));
 
     QualType Ty = E->getArg(0)->getType();
-    bool IsUnsigned = false;
     if (auto *VecTy = Ty->getAs<VectorType>())
       Ty = VecTy->getElementType();
-    IsUnsigned = Ty->isUnsignedIntegerType();
+    bool IsUnsigned = Ty->isUnsignedIntegerType();
     switch (CGM.getTarget().getTriple().getArch()) {
     case llvm::Triple::dxil: {
       return Builder.CreateIntrinsic(

>From 320e6d5f9fd7fa0fee303fb1a2782e4e24989b0b Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Thu, 24 Oct 2024 16:35:56 -0700
Subject: [PATCH 5/8] Addressed feedback.

---
 clang/lib/CodeGen/CGBuiltin.cpp               |  44 ++---
 clang/lib/CodeGen/CGHLSLRuntime.h             |   3 +
 .../CodeGenHLSL/builtins/clamp-builtin.hlsl   |   4 +-
 clang/test/CodeGenHLSL/builtins/clamp.hlsl    | 168 +++++++++---------
 llvm/include/llvm/IR/IntrinsicsDirectX.td     |   3 +-
 llvm/include/llvm/IR/IntrinsicsSPIRV.td       |   6 +-
 .../Target/DirectX/DXILIntrinsicExpansion.cpp |  46 +++--
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |   4 +-
 .../SPIRV/hlsl-intrinsics/clamp-vec.ll        |  30 ++--
 .../CodeGen/SPIRV/hlsl-intrinsics/clamp.ll    |  30 ++--
 llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll   |  24 +--
 llvm/test/CodeGen/SPIRV/opencl/clamp.ll       |  24 +--
 12 files changed, 189 insertions(+), 197 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 03d0e64c1c2e1d..ee584e27e95630 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18804,35 +18804,29 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
         "hlsl.any");
   }
   case Builtin::BI__builtin_hlsl_elementwise_clamp: {
-    Value *OpX = EmitScalarExpr(E->getArg(0));
-    Value *OpMin = EmitScalarExpr(E->getArg(1));
-    Value *OpMax = EmitScalarExpr(E->getArg(2));
+    Value* OpX = EmitScalarExpr(E->getArg(0));
+    Value* OpMin = EmitScalarExpr(E->getArg(1));
+    Value* OpMax = EmitScalarExpr(E->getArg(2));
 
     QualType Ty = E->getArg(0)->getType();
-    if (auto *VecTy = Ty->getAs<VectorType>())
+    if (auto* VecTy = Ty->getAs<VectorType>())
       Ty = VecTy->getElementType();
-    bool IsUnsigned = Ty->isUnsignedIntegerType();
-    switch (CGM.getTarget().getTriple().getArch()) {
-    case llvm::Triple::dxil: {
-      return Builder.CreateIntrinsic(
-          /*ReturnType=*/OpX->getType(),
-          IsUnsigned ? Intrinsic::dx_uclamp : Intrinsic::dx_clamp,
-          ArrayRef<Value *>{OpX, OpMin, OpMax}, nullptr, "dx.clamp");
-    } break;
-    case llvm::Triple::spirv: {
-      Intrinsic::ID Intr = Intrinsic::spv_sclamp;
-      if (Ty->isFloatingType()) {
-        Intr = Intrinsic::spv_fclamp;
-      } else if (IsUnsigned) {
-        Intr = Intrinsic::spv_uclamp;
-      }
-      return Builder.CreateIntrinsic(OpX->getType(), Intr,
-                                     ArrayRef<Value *>{OpX, OpMin, OpMax},
-                                     nullptr, "spv.clamp");
-    } break;
-    default:
-      llvm_unreachable("Intrinsic clamp not supported by target architecture");
+
+    Intrinsic::ID Intr;
+    if (Ty->isFloatingType()) {
+      Intr = CGM.getHLSLRuntime().getNClampIntrinsic();
+    }
+    else if (Ty->isUnsignedIntegerType()) {
+      Intr = CGM.getHLSLRuntime().getUClampIntrinsic();
     }
+    else {
+      assert(Ty->isSignedIntegerType());
+      Intr = CGM.getHLSLRuntime().getSClampIntrinsic();
+    }
+    return Builder.CreateIntrinsic(
+      /*ReturnType=*/OpX->getType(),
+      Intr,
+      ArrayRef<Value*>{OpX, OpMin, OpMax}, nullptr, "hlsl.clamp");
   }
   case Builtin::BI__builtin_hlsl_cross: {
     Value *Op0 = EmitScalarExpr(E->getArg(0));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index caf8777fd95a9f..94d0f85a50fa72 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -95,6 +95,9 @@ class CGHLSLRuntime {
   GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
   GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
   GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(NClamp, nclamp)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(SClamp, sclamp)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(UClamp, uclamp)
 
   GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, handle_fromBinding)
 
diff --git a/clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl
index e3ef26429e7e40..62bada715a68ad 100644
--- a/clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s
 
 // CHECK-LABEL: builtin_test_clamp_int4
-// CHECK: %dx.clamp = call <4 x i32> @llvm.dx.clamp.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2)
-// CHECK: ret <4 x i32> %dx.clamp
+// CHECK: %hlsl.clamp = call <4 x i32> @llvm.dx.sclamp.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2)
+// CHECK: ret <4 x i32> %hlsl.clamp
 int4 builtin_test_clamp_int4(int4 p0, int4 p1, int4 p2) {
   return __builtin_hlsl_elementwise_clamp(p0, p1, p2);
 }
diff --git a/clang/test/CodeGenHLSL/builtins/clamp.hlsl b/clang/test/CodeGenHLSL/builtins/clamp.hlsl
index 806e786ae70931..3489f3d3e2b09e 100644
--- a/clang/test/CodeGenHLSL/builtins/clamp.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/clamp.hlsl
@@ -1,143 +1,143 @@
 // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \
 // RUN:  -fnative-half-type -emit-llvm -disable-llvm-passes -o - | \
 // RUN:  FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \
-// RUN:  -DSCLAMP="dx.clamp" -DUCLAMP="dx.uclamp" -DFCLAMP="dx.clamp" -DFNATTR="noundef"
+// RUN:  -DTARGET=dx -DFNATTRS=noundef
 // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \
 // RUN:  -emit-llvm -disable-llvm-passes -o - | \
 // RUN:  FileCheck %s --check-prefixes=CHECK,NO_HALF \
-// RUN:  -DSCLAMP="dx.clamp" -DUCLAMP="dx.uclamp" -DFCLAMP="dx.clamp" -DFNATTR="noundef"
+// RUN:  -DTARGET=dx -DFNATTRS=noundef
 // RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute %s \
 // RUN:  -fnative-half-type -emit-llvm -disable-llvm-passes -o - | \
 // RUN:  FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \
-// RUN:  -DSCLAMP="spv.sclamp" -DUCLAMP="spv.uclamp" -DFCLAMP="spv.fclamp" -DFNATTR="spir_func noundef"
+// RUN:  -DTARGET=spv -DFNATTRS="spir_func noundef"
 // RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute %s \
 // RUN:  -emit-llvm -disable-llvm-passes -o - | \
 // RUN:  FileCheck %s --check-prefixes=CHECK,NO_HALF \
-// RUN:  -DSCLAMP="spv.sclamp" -DUCLAMP="spv.uclamp" -DFCLAMP="spv.fclamp" -DFNATTR="spir_func noundef"
+// RUN:  -DTARGET=spv -DFNATTRS="spir_func noundef"
 
 #ifdef __HLSL_ENABLE_16_BIT
-// NATIVE_HALF: define [[FNATTR]] i16 @_Z16test_clamp_short
-// NATIVE_HALF: call i16 @llvm.[[SCLAMP]].i16(
+// NATIVE_HALF: define [[FNATTRS]] i16 @_Z16test_clamp_short
+// NATIVE_HALF: call i16 @llvm.[[TARGET]].sclamp.i16(
 int16_t test_clamp_short(int16_t p0, int16_t p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <2 x i16> @_Z17test_clamp_short2
-// NATIVE_HALF: call <2 x i16> @llvm.[[SCLAMP]].v2i16(
+// NATIVE_HALF: define [[FNATTRS]] <2 x i16> @_Z17test_clamp_short2
+// NATIVE_HALF: call <2 x i16> @llvm.[[TARGET]].sclamp.v2i16(
 int16_t2 test_clamp_short2(int16_t2 p0, int16_t2 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <3 x i16> @_Z17test_clamp_short3
-// NATIVE_HALF: call <3 x i16> @llvm.[[SCLAMP]].v3i16
+// NATIVE_HALF: define [[FNATTRS]] <3 x i16> @_Z17test_clamp_short3
+// NATIVE_HALF: call <3 x i16> @llvm.[[TARGET]].sclamp.v3i16
 int16_t3 test_clamp_short3(int16_t3 p0, int16_t3 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <4 x i16> @_Z17test_clamp_short4
-// NATIVE_HALF: call <4 x i16> @llvm.[[SCLAMP]].v4i16
+// NATIVE_HALF: define [[FNATTRS]] <4 x i16> @_Z17test_clamp_short4
+// NATIVE_HALF: call <4 x i16> @llvm.[[TARGET]].sclamp.v4i16
 int16_t4 test_clamp_short4(int16_t4 p0, int16_t4 p1) { return clamp(p0, p1,p1); }
 
-// NATIVE_HALF: define [[FNATTR]] i16 @_Z17test_clamp_ushort
-// NATIVE_HALF: call i16 @llvm.[[UCLAMP]].i16(
+// NATIVE_HALF: define [[FNATTRS]] i16 @_Z17test_clamp_ushort
+// NATIVE_HALF: call i16 @llvm.[[TARGET]].uclamp.i16(
 uint16_t test_clamp_ushort(uint16_t p0, uint16_t p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <2 x i16> @_Z18test_clamp_ushort2
-// NATIVE_HALF: call <2 x i16> @llvm.[[UCLAMP]].v2i16
+// NATIVE_HALF: define [[FNATTRS]] <2 x i16> @_Z18test_clamp_ushort2
+// NATIVE_HALF: call <2 x i16> @llvm.[[TARGET]].uclamp.v2i16
 uint16_t2 test_clamp_ushort2(uint16_t2 p0, uint16_t2 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <3 x i16> @_Z18test_clamp_ushort3
-// NATIVE_HALF: call <3 x i16> @llvm.[[UCLAMP]].v3i16
+// NATIVE_HALF: define [[FNATTRS]] <3 x i16> @_Z18test_clamp_ushort3
+// NATIVE_HALF: call <3 x i16> @llvm.[[TARGET]].uclamp.v3i16
 uint16_t3 test_clamp_ushort3(uint16_t3 p0, uint16_t3 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <4 x i16> @_Z18test_clamp_ushort4
-// NATIVE_HALF: call <4 x i16> @llvm.[[UCLAMP]].v4i16
+// NATIVE_HALF: define [[FNATTRS]] <4 x i16> @_Z18test_clamp_ushort4
+// NATIVE_HALF: call <4 x i16> @llvm.[[TARGET]].uclamp.v4i16
 uint16_t4 test_clamp_ushort4(uint16_t4 p0, uint16_t4 p1) { return clamp(p0, p1,p1); }
 #endif
 
-// CHECK: define [[FNATTR]] i32 @_Z14test_clamp_int
-// CHECK: call i32 @llvm.[[SCLAMP]].i32(
+// CHECK: define [[FNATTRS]] i32 @_Z14test_clamp_int
+// CHECK: call i32 @llvm.[[TARGET]].sclamp.i32(
 int test_clamp_int(int p0, int p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <2 x i32> @_Z15test_clamp_int2
-// CHECK: call <2 x i32> @llvm.[[SCLAMP]].v2i32
+// CHECK: define [[FNATTRS]] <2 x i32> @_Z15test_clamp_int2
+// CHECK: call <2 x i32> @llvm.[[TARGET]].sclamp.v2i32
 int2 test_clamp_int2(int2 p0, int2 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <3 x i32> @_Z15test_clamp_int3
-// CHECK: call <3 x i32> @llvm.[[SCLAMP]].v3i32
+// CHECK: define [[FNATTRS]] <3 x i32> @_Z15test_clamp_int3
+// CHECK: call <3 x i32> @llvm.[[TARGET]].sclamp.v3i32
 int3 test_clamp_int3(int3 p0, int3 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <4 x i32> @_Z15test_clamp_int4
-// CHECK: call <4 x i32> @llvm.[[SCLAMP]].v4i32
+// CHECK: define [[FNATTRS]] <4 x i32> @_Z15test_clamp_int4
+// CHECK: call <4 x i32> @llvm.[[TARGET]].sclamp.v4i32
 int4 test_clamp_int4(int4 p0, int4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK: define [[FNATTR]] i32 @_Z15test_clamp_uint
-// CHECK: call i32 @llvm.[[UCLAMP]].i32(
+// CHECK: define [[FNATTRS]] i32 @_Z15test_clamp_uint
+// CHECK: call i32 @llvm.[[TARGET]].uclamp.i32(
 int test_clamp_uint(uint p0, uint p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <2 x i32> @_Z16test_clamp_uint2
-// CHECK: call <2 x i32> @llvm.[[UCLAMP]].v2i32
+// CHECK: define [[FNATTRS]] <2 x i32> @_Z16test_clamp_uint2
+// CHECK: call <2 x i32> @llvm.[[TARGET]].uclamp.v2i32
 uint2 test_clamp_uint2(uint2 p0, uint2 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <3 x i32> @_Z16test_clamp_uint3
-// CHECK: call <3 x i32> @llvm.[[UCLAMP]].v3i32
+// CHECK: define [[FNATTRS]] <3 x i32> @_Z16test_clamp_uint3
+// CHECK: call <3 x i32> @llvm.[[TARGET]].uclamp.v3i32
 uint3 test_clamp_uint3(uint3 p0, uint3 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <4 x i32> @_Z16test_clamp_uint4
-// CHECK: call <4 x i32> @llvm.[[UCLAMP]].v4i32
+// CHECK: define [[FNATTRS]] <4 x i32> @_Z16test_clamp_uint4
+// CHECK: call <4 x i32> @llvm.[[TARGET]].uclamp.v4i32
 uint4 test_clamp_uint4(uint4 p0, uint4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK: define [[FNATTR]] i64 @_Z15test_clamp_long
-// CHECK: call i64 @llvm.[[SCLAMP]].i64(
+// CHECK: define [[FNATTRS]] i64 @_Z15test_clamp_long
+// CHECK: call i64 @llvm.[[TARGET]].sclamp.i64(
 int64_t test_clamp_long(int64_t p0, int64_t p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <2 x i64> @_Z16test_clamp_long2
-// CHECK: call <2 x i64> @llvm.[[SCLAMP]].v2i64
+// CHECK: define [[FNATTRS]] <2 x i64> @_Z16test_clamp_long2
+// CHECK: call <2 x i64> @llvm.[[TARGET]].sclamp.v2i64
 int64_t2 test_clamp_long2(int64_t2 p0, int64_t2 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <3 x i64> @_Z16test_clamp_long3
-// CHECK: call <3 x i64> @llvm.[[SCLAMP]].v3i64
+// CHECK: define [[FNATTRS]] <3 x i64> @_Z16test_clamp_long3
+// CHECK: call <3 x i64> @llvm.[[TARGET]].sclamp.v3i64
 int64_t3 test_clamp_long3(int64_t3 p0, int64_t3 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <4 x i64> @_Z16test_clamp_long4
-// CHECK: call <4 x i64> @llvm.[[SCLAMP]].v4i64
+// CHECK: define [[FNATTRS]] <4 x i64> @_Z16test_clamp_long4
+// CHECK: call <4 x i64> @llvm.[[TARGET]].sclamp.v4i64
 int64_t4 test_clamp_long4(int64_t4 p0, int64_t4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK: define [[FNATTR]] i64 @_Z16test_clamp_ulong
-// CHECK: call i64 @llvm.[[UCLAMP]].i64(
+// CHECK: define [[FNATTRS]] i64 @_Z16test_clamp_ulong
+// CHECK: call i64 @llvm.[[TARGET]].uclamp.i64(
 uint64_t test_clamp_ulong(uint64_t p0, uint64_t p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <2 x i64> @_Z17test_clamp_ulong2
-// CHECK: call <2 x i64> @llvm.[[UCLAMP]].v2i64
+// CHECK: define [[FNATTRS]] <2 x i64> @_Z17test_clamp_ulong2
+// CHECK: call <2 x i64> @llvm.[[TARGET]].uclamp.v2i64
 uint64_t2 test_clamp_ulong2(uint64_t2 p0, uint64_t2 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <3 x i64> @_Z17test_clamp_ulong3
-// CHECK: call <3 x i64> @llvm.[[UCLAMP]].v3i64
+// CHECK: define [[FNATTRS]] <3 x i64> @_Z17test_clamp_ulong3
+// CHECK: call <3 x i64> @llvm.[[TARGET]].uclamp.v3i64
 uint64_t3 test_clamp_ulong3(uint64_t3 p0, uint64_t3 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <4 x i64> @_Z17test_clamp_ulong4
-// CHECK: call <4 x i64> @llvm.[[UCLAMP]].v4i64
+// CHECK: define [[FNATTRS]] <4 x i64> @_Z17test_clamp_ulong4
+// CHECK: call <4 x i64> @llvm.[[TARGET]].uclamp.v4i64
 uint64_t4 test_clamp_ulong4(uint64_t4 p0, uint64_t4 p1) { return clamp(p0, p1,p1); }
 
-// NATIVE_HALF: define [[FNATTR]] half @_Z15test_clamp_half
-// NATIVE_HALF: call half @llvm.[[FCLAMP]].f16(
-// NO_HALF: define [[FNATTR]] float @_Z15test_clamp_half
-// NO_HALF: call float @llvm.[[FCLAMP]].f32(
+// NATIVE_HALF: define [[FNATTRS]] half @_Z15test_clamp_half
+// NATIVE_HALF: call half @llvm.[[TARGET]].nclamp.f16(
+// NO_HALF: define [[FNATTRS]] float @_Z15test_clamp_half
+// NO_HALF: call float @llvm.[[TARGET]].nclamp.f32(
 half test_clamp_half(half p0, half p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <2 x half> @_Z16test_clamp_half2
-// NATIVE_HALF: call <2 x half> @llvm.[[FCLAMP]].v2f16
-// NO_HALF: define [[FNATTR]] <2 x float> @_Z16test_clamp_half2
-// NO_HALF: call <2 x float> @llvm.[[FCLAMP]].v2f32(
+// NATIVE_HALF: define [[FNATTRS]] <2 x half> @_Z16test_clamp_half2
+// NATIVE_HALF: call <2 x half> @llvm.[[TARGET]].nclamp.v2f16
+// NO_HALF: define [[FNATTRS]] <2 x float> @_Z16test_clamp_half2
+// NO_HALF: call <2 x float> @llvm.[[TARGET]].nclamp.v2f32(
 half2 test_clamp_half2(half2 p0, half2 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <3 x half> @_Z16test_clamp_half3
-// NATIVE_HALF: call <3 x half> @llvm.[[FCLAMP]].v3f16
-// NO_HALF: define [[FNATTR]] <3 x float> @_Z16test_clamp_half3
-// NO_HALF: call <3 x float> @llvm.[[FCLAMP]].v3f32(
+// NATIVE_HALF: define [[FNATTRS]] <3 x half> @_Z16test_clamp_half3
+// NATIVE_HALF: call <3 x half> @llvm.[[TARGET]].nclamp.v3f16
+// NO_HALF: define [[FNATTRS]] <3 x float> @_Z16test_clamp_half3
+// NO_HALF: call <3 x float> @llvm.[[TARGET]].nclamp.v3f32(
 half3 test_clamp_half3(half3 p0, half3 p1) { return clamp(p0, p1,p1); }
-// NATIVE_HALF: define [[FNATTR]] <4 x half> @_Z16test_clamp_half4
-// NATIVE_HALF: call <4 x half> @llvm.[[FCLAMP]].v4f16
-// NO_HALF: define [[FNATTR]] <4 x float> @_Z16test_clamp_half4
-// NO_HALF: call <4 x float> @llvm.[[FCLAMP]].v4f32(
+// NATIVE_HALF: define [[FNATTRS]] <4 x half> @_Z16test_clamp_half4
+// NATIVE_HALF: call <4 x half> @llvm.[[TARGET]].nclamp.v4f16
+// NO_HALF: define [[FNATTRS]] <4 x float> @_Z16test_clamp_half4
+// NO_HALF: call <4 x float> @llvm.[[TARGET]].nclamp.v4f32(
 half4 test_clamp_half4(half4 p0, half4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK: define [[FNATTR]] float @_Z16test_clamp_float
-// CHECK: call float @llvm.[[FCLAMP]].f32(
+// CHECK: define [[FNATTRS]] float @_Z16test_clamp_float
+// CHECK: call float @llvm.[[TARGET]].nclamp.f32(
 float test_clamp_float(float p0, float p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <2 x float> @_Z17test_clamp_float2
-// CHECK: call <2 x float> @llvm.[[FCLAMP]].v2f32
+// CHECK: define [[FNATTRS]] <2 x float> @_Z17test_clamp_float2
+// CHECK: call <2 x float> @llvm.[[TARGET]].nclamp.v2f32
 float2 test_clamp_float2(float2 p0, float2 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <3 x float> @_Z17test_clamp_float3
-// CHECK: call <3 x float> @llvm.[[FCLAMP]].v3f32
+// CHECK: define [[FNATTRS]] <3 x float> @_Z17test_clamp_float3
+// CHECK: call <3 x float> @llvm.[[TARGET]].nclamp.v3f32
 float3 test_clamp_float3(float3 p0, float3 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <4 x float> @_Z17test_clamp_float4
-// CHECK: call <4 x float> @llvm.[[FCLAMP]].v4f32
+// CHECK: define [[FNATTRS]] <4 x float> @_Z17test_clamp_float4
+// CHECK: call <4 x float> @llvm.[[TARGET]].nclamp.v4f32
 float4 test_clamp_float4(float4 p0, float4 p1) { return clamp(p0, p1,p1); }
 
-// CHECK: define [[FNATTR]] double @_Z17test_clamp_double
-// CHECK: call double @llvm.[[FCLAMP]].f64(
+// CHECK: define [[FNATTRS]] double @_Z17test_clamp_double
+// CHECK: call double @llvm.[[TARGET]].nclamp.f64(
 double test_clamp_double(double p0, double p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <2 x double> @_Z18test_clamp_double2
-// CHECK: call <2 x double> @llvm.[[FCLAMP]].v2f64
+// CHECK: define [[FNATTRS]] <2 x double> @_Z18test_clamp_double2
+// CHECK: call <2 x double> @llvm.[[TARGET]].nclamp.v2f64
 double2 test_clamp_double2(double2 p0, double2 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <3 x double> @_Z18test_clamp_double3
-// CHECK: call <3 x double> @llvm.[[FCLAMP]].v3f64
+// CHECK: define [[FNATTRS]] <3 x double> @_Z18test_clamp_double3
+// CHECK: call <3 x double> @llvm.[[TARGET]].nclamp.v3f64
 double3 test_clamp_double3(double3 p0, double3 p1) { return clamp(p0, p1,p1); }
-// CHECK: define [[FNATTR]] <4 x double> @_Z18test_clamp_double4
-// CHECK: call <4 x double> @llvm.[[FCLAMP]].v4f64
+// CHECK: define [[FNATTRS]] <4 x double> @_Z18test_clamp_double4
+// CHECK: call <4 x double> @llvm.[[TARGET]].nclamp.v4f64
 double4 test_clamp_double4(double4 p0, double4 p1) { return clamp(p0, p1,p1); }
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index 43267033f024a7..6385ae0c0a2e86 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -40,8 +40,9 @@ def int_dx_cast_handle : Intrinsic<[llvm_any_ty], [llvm_any_ty]>;
 
 def int_dx_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
 def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
-def int_dx_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_uclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_sclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_nclamp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
 def int_dx_saturate : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
 
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index e471c81d4516fd..798a9e795a16f0 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -90,9 +90,9 @@ let TargetPrefix = "spv" in {
   def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
   def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
   def int_spv_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
-  def int_spv_uclamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
-  def int_spv_sclamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
-  def int_spv_fclamp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_uclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_sclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+  def int_spv_nclamp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
 
   // Create resource handle given the binding information. Returns a 
   // type appropriate for the kind of resource given the set id, binding id,
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index fb5383b3514a5a..8908a1205fdd03 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -53,9 +53,10 @@ static bool isIntrinsicExpansion(Function &F) {
   case Intrinsic::pow:
   case Intrinsic::dx_all:
   case Intrinsic::dx_any:
-  case Intrinsic::dx_clamp:
   case Intrinsic::dx_cross:
   case Intrinsic::dx_uclamp:
+  case Intrinsic::dx_sclamp:
+  case Intrinsic::dx_nclamp:
   case Intrinsic::dx_degrees:
   case Intrinsic::dx_lerp:
   case Intrinsic::dx_length:
@@ -452,43 +453,35 @@ static Value *expandRadiansIntrinsic(CallInst *Orig) {
   return Builder.CreateFMul(X, PiOver180);
 }
 
-static Intrinsic::ID getMaxForClamp(Type *ElemTy,
-                                    Intrinsic::ID ClampIntrinsic) {
+static Intrinsic::ID getMaxForClamp(Intrinsic::ID ClampIntrinsic) {
   if (ClampIntrinsic == Intrinsic::dx_uclamp)
     return Intrinsic::umax;
-  assert(ClampIntrinsic == Intrinsic::dx_clamp);
-  if (ElemTy->isVectorTy())
-    ElemTy = ElemTy->getScalarType();
-  if (ElemTy->isIntegerTy())
+  if (ClampIntrinsic == Intrinsic::dx_sclamp)
     return Intrinsic::smax;
-  assert(ElemTy->isFloatingPointTy());
+  assert(ClampIntrinsic == Intrinsic::dx_nclamp);
   return Intrinsic::maxnum;
 }
 
-static Intrinsic::ID getMinForClamp(Type *ElemTy,
-                                    Intrinsic::ID ClampIntrinsic) {
+static Intrinsic::ID getMinForClamp(Intrinsic::ID ClampIntrinsic) {
   if (ClampIntrinsic == Intrinsic::dx_uclamp)
     return Intrinsic::umin;
-  assert(ClampIntrinsic == Intrinsic::dx_clamp);
-  if (ElemTy->isVectorTy())
-    ElemTy = ElemTy->getScalarType();
-  if (ElemTy->isIntegerTy())
+  if (ClampIntrinsic == Intrinsic::dx_sclamp)
     return Intrinsic::smin;
-  assert(ElemTy->isFloatingPointTy());
+  assert(ClampIntrinsic == Intrinsic::dx_nclamp);
   return Intrinsic::minnum;
 }
 
-static Value *expandClampIntrinsic(CallInst *Orig,
-                                   Intrinsic::ID ClampIntrinsic) {
-  Value *X = Orig->getOperand(0);
-  Value *Min = Orig->getOperand(1);
-  Value *Max = Orig->getOperand(2);
-  Type *Ty = X->getType();
+static Value* expandClampIntrinsic(CallInst* Orig,
+  Intrinsic::ID ClampIntrinsic) {
+  Value* X = Orig->getOperand(0);
+  Value* Min = Orig->getOperand(1);
+  Value* Max = Orig->getOperand(2);
+  Type* Ty = X->getType();
   IRBuilder<> Builder(Orig);
-  auto *MaxCall = Builder.CreateIntrinsic(
-      Ty, getMaxForClamp(Ty, ClampIntrinsic), {X, Min}, nullptr, "dx.max");
-  return Builder.CreateIntrinsic(Ty, getMinForClamp(Ty, ClampIntrinsic),
-                                 {MaxCall, Max}, nullptr, "dx.min");
+  auto* MaxCall = Builder.CreateIntrinsic(
+    Ty, getMaxForClamp(ClampIntrinsic), { X, Min }, nullptr, "dx.max");
+  return Builder.CreateIntrinsic(Ty, getMinForClamp(ClampIntrinsic),
+    { MaxCall, Max }, nullptr, "dx.min");
 }
 
 static Value *expandDegreesIntrinsic(CallInst *Orig) {
@@ -555,7 +548,8 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
     Result = expandCrossIntrinsic(Orig);
     break;
   case Intrinsic::dx_uclamp:
-  case Intrinsic::dx_clamp:
+  case Intrinsic::dx_sclamp:
+  case Intrinsic::dx_nclamp:
     Result = expandClampIntrinsic(Orig, IntrinsicId);
     break;
   case Intrinsic::dx_degrees:
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 4cc2136d4080f4..cba681d7af2730 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2739,8 +2739,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
   } break;
   case Intrinsic::spv_saturate:
     return selectSaturate(ResVReg, ResType, I);
-  case Intrinsic::spv_fclamp:
-    return selectExtInst(ResVReg, ResType, I, CL::fclamp, GL::FClamp);
+  case Intrinsic::spv_nclamp:
+    return selectExtInst(ResVReg, ResType, I, CL::fclamp, GL::NClamp);
   case Intrinsic::spv_uclamp:
     return selectExtInst(ResVReg, ResType, I, CL::u_clamp, GL::UClamp);
   case Intrinsic::spv_sclamp:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
index cd0111c399abf7..089b76c575807a 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
@@ -52,36 +52,36 @@ entry:
   ret <4 x i64> %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_v4half
-define noundef <4 x half> @test_fclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_v4half
+define noundef <4 x half> @test_nclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
 entry:
   ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
   ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
   ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] FClamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
-  %0 = call <4 x half> @llvm.spv.fclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] NClamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
+  %0 = call <4 x half> @llvm.spv.nclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
   ret <4 x half> %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_v4float
-define noundef <4 x float> @test_fclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_v4float
+define noundef <4 x float> @test_nclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
 entry:
   ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
   ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
   ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] FClamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
-  %0 = call <4 x float> @llvm.spv.fclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] NClamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
+  %0 = call <4 x float> @llvm.spv.nclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
   ret <4 x float> %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_v4double
-define noundef <4 x double> @test_fclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_v4double
+define noundef <4 x double> @test_nclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
 entry:
   ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
   ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
   ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] FClamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
-  %0 = call <4 x double> @llvm.spv.fclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] NClamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
+  %0 = call <4 x double> @llvm.spv.nclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
   ret <4 x double> %0
 }
 
@@ -118,9 +118,9 @@ entry:
   ret <4 x i64> %0
 }
 
-declare <4 x half> @llvm.spv.fclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
-declare <4 x float> @llvm.spv.fclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
-declare <4 x double> @llvm.spv.fclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
+declare <4 x half> @llvm.spv.nclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
+declare <4 x float> @llvm.spv.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x double> @llvm.spv.nclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
 declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
 declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
 declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
index 61b89e16f2bd48..444ae41bbec282 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
@@ -44,36 +44,36 @@ entry:
   ret i64 %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_half
-define noundef half @test_fclamp_half(half noundef %a, half noundef %b, half noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_half
+define noundef half @test_nclamp_half(half noundef %a, half noundef %b, half noundef %c) {
 entry:
   ; CHECK: %[[#f16_arg0:]] = OpFunctionParameter %[[#float_16]]
   ; CHECK: %[[#f16_arg1:]] = OpFunctionParameter %[[#float_16]]
   ; CHECK: %[[#f16_arg2:]] = OpFunctionParameter %[[#float_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext]] FClamp %[[#f16_arg0]] %[[#f16_arg1]] %[[#f16_arg2]]
-  %0 = call half @llvm.spv.fclamp.f16(half %a, half %b, half %c)
+  ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext]] NClamp %[[#f16_arg0]] %[[#f16_arg1]] %[[#f16_arg2]]
+  %0 = call half @llvm.spv.nclamp.f16(half %a, half %b, half %c)
   ret half %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_float
-define noundef float @test_fclamp_float(float noundef %a, float noundef %b, float noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_float
+define noundef float @test_nclamp_float(float noundef %a, float noundef %b, float noundef %c) {
 entry:
   ; CHECK: %[[#f32_arg0:]] = OpFunctionParameter %[[#float_32]]
   ; CHECK: %[[#f32_arg1:]] = OpFunctionParameter %[[#float_32]]
   ; CHECK: %[[#f32_arg2:]] = OpFunctionParameter %[[#float_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext]] FClamp %[[#f32_arg0]] %[[#f32_arg1]] %[[#f32_arg2]]
-  %0 = call float @llvm.spv.fclamp.f32(float %a, float %b, float %c)
+  ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext]] NClamp %[[#f32_arg0]] %[[#f32_arg1]] %[[#f32_arg2]]
+  %0 = call float @llvm.spv.nclamp.f32(float %a, float %b, float %c)
   ret float %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_double
-define noundef double @test_fclamp_double(double noundef %a, double noundef %b, double noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_double
+define noundef double @test_nclamp_double(double noundef %a, double noundef %b, double noundef %c) {
 entry:
   ; CHECK: %[[#f64_arg0:]] = OpFunctionParameter %[[#float_64]]
   ; CHECK: %[[#f64_arg1:]] = OpFunctionParameter %[[#float_64]]
   ; CHECK: %[[#f64_arg2:]] = OpFunctionParameter %[[#float_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext]] FClamp %[[#f64_arg0]] %[[#f64_arg1]] %[[#f64_arg2]]
-  %0 = call double @llvm.spv.fclamp.f64(double %a, double %b, double %c)
+  ; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext]] NClamp %[[#f64_arg0]] %[[#f64_arg1]] %[[#f64_arg2]]
+  %0 = call double @llvm.spv.nclamp.f64(double %a, double %b, double %c)
   ret double %0
 }
 
@@ -110,9 +110,9 @@ entry:
   ret i64 %0
 }
 
-declare half @llvm.spv.fclamp.f16(half, half, half)
-declare float @llvm.spv.fclamp.f32(float, float, float)
-declare double @llvm.spv.fclamp.f64(double, double, double)
+declare half @llvm.spv.nclamp.f16(half, half, half)
+declare float @llvm.spv.nclamp.f32(float, float, float)
+declare double @llvm.spv.nclamp.f64(double, double, double)
 declare i16 @llvm.spv.sclamp.i16(i16, i16, i16)
 declare i32 @llvm.spv.sclamp.i32(i32, i32, i32)
 declare i64 @llvm.spv.sclamp.i64(i64, i64, i64)
diff --git a/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll b/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
index 35f5559c46921e..8f6af7b5de1e97 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
@@ -54,36 +54,36 @@ entry:
   ret <4 x i64> %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_v4half
-define noundef <4 x half> @test_fclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_v4half
+define noundef <4 x half> @test_nclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
 entry:
   ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
   ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
   ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
   ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] fclamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
-  %0 = call <4 x half> @llvm.spv.fclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
+  %0 = call <4 x half> @llvm.spv.nclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
   ret <4 x half> %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_v4float
-define noundef <4 x float> @test_fclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_v4float
+define noundef <4 x float> @test_nclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
 entry:
   ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
   ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
   ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
   ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] fclamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
-  %0 = call <4 x float> @llvm.spv.fclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
+  %0 = call <4 x float> @llvm.spv.nclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
   ret <4 x float> %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_v4double
-define noundef <4 x double> @test_fclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_v4double
+define noundef <4 x double> @test_nclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
 entry:
   ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
   ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
   ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
   ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] fclamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
-  %0 = call <4 x double> @llvm.spv.fclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
+  %0 = call <4 x double> @llvm.spv.nclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
   ret <4 x double> %0
 }
 
@@ -120,9 +120,9 @@ entry:
   ret <4 x i64> %0
 }
 
-declare <4 x half> @llvm.spv.fclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
-declare <4 x float> @llvm.spv.fclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
-declare <4 x double> @llvm.spv.fclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
+declare <4 x half> @llvm.spv.nclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
+declare <4 x float> @llvm.spv.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x double> @llvm.spv.nclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
 declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
 declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
 declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
diff --git a/llvm/test/CodeGen/SPIRV/opencl/clamp.ll b/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
index f6500442042cd9..8c6945e7bf9cfa 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
@@ -46,36 +46,36 @@ entry:
   ret i64 %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_half
-define noundef half @test_fclamp_half(half noundef %a, half noundef %b, half noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_half
+define noundef half @test_nclamp_half(half noundef %a, half noundef %b, half noundef %c) {
 entry:
   ; CHECK: %[[#f16_arg0:]] = OpFunctionParameter %[[#float_16]]
   ; CHECK: %[[#f16_arg1:]] = OpFunctionParameter %[[#float_16]]
   ; CHECK: %[[#f16_arg2:]] = OpFunctionParameter %[[#float_16]]
   ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext]] fclamp %[[#f16_arg0]] %[[#f16_arg1]] %[[#f16_arg2]]
-  %0 = call half @llvm.spv.fclamp.f16(half %a, half %b, half %c)
+  %0 = call half @llvm.spv.nclamp.f16(half %a, half %b, half %c)
   ret half %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_float
-define noundef float @test_fclamp_float(float noundef %a, float noundef %b, float noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_float
+define noundef float @test_nclamp_float(float noundef %a, float noundef %b, float noundef %c) {
 entry:
   ; CHECK: %[[#f32_arg0:]] = OpFunctionParameter %[[#float_32]]
   ; CHECK: %[[#f32_arg1:]] = OpFunctionParameter %[[#float_32]]
   ; CHECK: %[[#f32_arg2:]] = OpFunctionParameter %[[#float_32]]
   ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext]] fclamp %[[#f32_arg0]] %[[#f32_arg1]] %[[#f32_arg2]]
-  %0 = call float @llvm.spv.fclamp.f32(float %a, float %b, float %c)
+  %0 = call float @llvm.spv.nclamp.f32(float %a, float %b, float %c)
   ret float %0
 }
 
-; CHECK-LABEL: Begin function test_fclamp_double
-define noundef double @test_fclamp_double(double noundef %a, double noundef %b, double noundef %c) {
+; CHECK-LABEL: Begin function test_nclamp_double
+define noundef double @test_nclamp_double(double noundef %a, double noundef %b, double noundef %c) {
 entry:
   ; CHECK: %[[#f64_arg0:]] = OpFunctionParameter %[[#float_64]]
   ; CHECK: %[[#f64_arg1:]] = OpFunctionParameter %[[#float_64]]
   ; CHECK: %[[#f64_arg2:]] = OpFunctionParameter %[[#float_64]]
   ; CHECK: %[[#]] = OpExtInst %[[#float_64]] %[[#op_ext]] fclamp %[[#f64_arg0]] %[[#f64_arg1]] %[[#f64_arg2]]
-  %0 = call double @llvm.spv.fclamp.f64(double %a, double %b, double %c)
+  %0 = call double @llvm.spv.nclamp.f64(double %a, double %b, double %c)
   ret double %0
 }
 
@@ -112,9 +112,9 @@ entry:
   ret i64 %0
 }
 
-declare half @llvm.spv.fclamp.f16(half, half, half)
-declare float @llvm.spv.fclamp.f32(float, float, float)
-declare double @llvm.spv.fclamp.f64(double, double, double)
+declare half @llvm.spv.nclamp.f16(half, half, half)
+declare float @llvm.spv.nclamp.f32(float, float, float)
+declare double @llvm.spv.nclamp.f64(double, double, double)
 declare i16 @llvm.spv.sclamp.i16(i16, i16, i16)
 declare i32 @llvm.spv.sclamp.i32(i32, i32, i32)
 declare i64 @llvm.spv.sclamp.i64(i64, i64, i64)

>From 8d1d6dece6d9fd336eba333337cf5aea1d6b514b Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Thu, 24 Oct 2024 16:39:13 -0700
Subject: [PATCH 6/8] Formatting

---
 clang/lib/CodeGen/CGBuiltin.cpp               | 19 ++++++++-----------
 .../Target/DirectX/DXILIntrinsicExpansion.cpp | 18 +++++++++---------
 2 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index ee584e27e95630..2a57e63305f1b3 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -18804,29 +18804,26 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
         "hlsl.any");
   }
   case Builtin::BI__builtin_hlsl_elementwise_clamp: {
-    Value* OpX = EmitScalarExpr(E->getArg(0));
-    Value* OpMin = EmitScalarExpr(E->getArg(1));
-    Value* OpMax = EmitScalarExpr(E->getArg(2));
+    Value *OpX = EmitScalarExpr(E->getArg(0));
+    Value *OpMin = EmitScalarExpr(E->getArg(1));
+    Value *OpMax = EmitScalarExpr(E->getArg(2));
 
     QualType Ty = E->getArg(0)->getType();
-    if (auto* VecTy = Ty->getAs<VectorType>())
+    if (auto *VecTy = Ty->getAs<VectorType>())
       Ty = VecTy->getElementType();
 
     Intrinsic::ID Intr;
     if (Ty->isFloatingType()) {
       Intr = CGM.getHLSLRuntime().getNClampIntrinsic();
-    }
-    else if (Ty->isUnsignedIntegerType()) {
+    } else if (Ty->isUnsignedIntegerType()) {
       Intr = CGM.getHLSLRuntime().getUClampIntrinsic();
-    }
-    else {
+    } else {
       assert(Ty->isSignedIntegerType());
       Intr = CGM.getHLSLRuntime().getSClampIntrinsic();
     }
     return Builder.CreateIntrinsic(
-      /*ReturnType=*/OpX->getType(),
-      Intr,
-      ArrayRef<Value*>{OpX, OpMin, OpMax}, nullptr, "hlsl.clamp");
+        /*ReturnType=*/OpX->getType(), Intr,
+        ArrayRef<Value *>{OpX, OpMin, OpMax}, nullptr, "hlsl.clamp");
   }
   case Builtin::BI__builtin_hlsl_cross: {
     Value *Op0 = EmitScalarExpr(E->getArg(0));
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index 8908a1205fdd03..d2bfca1fada559 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -471,17 +471,17 @@ static Intrinsic::ID getMinForClamp(Intrinsic::ID ClampIntrinsic) {
   return Intrinsic::minnum;
 }
 
-static Value* expandClampIntrinsic(CallInst* Orig,
-  Intrinsic::ID ClampIntrinsic) {
-  Value* X = Orig->getOperand(0);
-  Value* Min = Orig->getOperand(1);
-  Value* Max = Orig->getOperand(2);
-  Type* Ty = X->getType();
+static Value *expandClampIntrinsic(CallInst *Orig,
+                                   Intrinsic::ID ClampIntrinsic) {
+  Value *X = Orig->getOperand(0);
+  Value *Min = Orig->getOperand(1);
+  Value *Max = Orig->getOperand(2);
+  Type *Ty = X->getType();
   IRBuilder<> Builder(Orig);
-  auto* MaxCall = Builder.CreateIntrinsic(
-    Ty, getMaxForClamp(ClampIntrinsic), { X, Min }, nullptr, "dx.max");
+  auto *MaxCall = Builder.CreateIntrinsic(Ty, getMaxForClamp(ClampIntrinsic),
+                                          {X, Min}, nullptr, "dx.max");
   return Builder.CreateIntrinsic(Ty, getMinForClamp(ClampIntrinsic),
-    { MaxCall, Max }, nullptr, "dx.min");
+                                 {MaxCall, Max}, nullptr, "dx.min");
 }
 
 static Value *expandDegreesIntrinsic(CallInst *Orig) {

>From ee8e84833d18a5ac978021b5a8298b73d82df11d Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Fri, 25 Oct 2024 10:00:57 -0700
Subject: [PATCH 7/8] Clamp-vec is now gone for all the targets

---
 llvm/test/CodeGen/DirectX/clamp-vec.ll        |  74 ------
 llvm/test/CodeGen/DirectX/clamp.ll            | 224 +++++++++++++++++-
 .../SPIRV/hlsl-intrinsics/clamp-vec.ll        | 130 ----------
 .../CodeGen/SPIRV/hlsl-intrinsics/clamp.ll    | 118 +++++++++
 llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll   | 132 -----------
 llvm/test/CodeGen/SPIRV/opencl/clamp.ll       | 118 +++++++++
 6 files changed, 447 insertions(+), 349 deletions(-)
 delete mode 100644 llvm/test/CodeGen/DirectX/clamp-vec.ll
 delete mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
 delete mode 100644 llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll

diff --git a/llvm/test/CodeGen/DirectX/clamp-vec.ll b/llvm/test/CodeGen/DirectX/clamp-vec.ll
deleted file mode 100644
index d4f33a18b71573..00000000000000
--- a/llvm/test/CodeGen/DirectX/clamp-vec.ll
+++ /dev/null
@@ -1,74 +0,0 @@
-; RUN: opt -S  -dxil-intrinsic-expansion  < %s | FileCheck %s
-
-; Make sure dxil operation function calls for clamp are generated for float/int/uint vectors.
-
-; CHECK-LABEL: clamp_half3
-define noundef <3 x half> @clamp_half3(<3 x half> noundef %a, <3 x half> noundef %b, <3 x half> noundef %c) {
-entry:
-  ; CHECK: call <3 x half> @llvm.maxnum.v3f16(<3 x half>  %a, <3 x half>  %b)
-  ; CHECK: call <3 x half> @llvm.minnum.v3f16(<3 x half>  %{{.*}}, <3 x half>  %c)
-  %dx.clamp = call <3 x half> @llvm.dx.clamp.v3f16(<3 x half> %a, <3 x half> %b, <3 x half> %c)
-  ret <3 x half> %dx.clamp
-}
-
-; CHECK-LABEL: clamp_float4
-define noundef <4 x float> @clamp_float4(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
-entry:
-  ; CHECK: call <4 x float> @llvm.maxnum.v4f32(<4 x float>  %a, <4 x float>  %b)
-  ; CHECK: call <4 x float> @llvm.minnum.v4f32(<4 x float>  %{{.*}}, <4 x float>  %c)
-  %dx.clamp = call <4 x float> @llvm.dx.clamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
-  ret <4 x float> %dx.clamp
-}
-
-; CHECK-LABEL: clamp_double2
-define noundef <2 x double> @clamp_double2(<2 x double> noundef %a, <2 x double> noundef %b, <2 x double> noundef %c) {
-entry:
-  ; CHECK: call <2 x double> @llvm.maxnum.v2f64(<2 x double>  %a, <2 x double>  %b)
-  ; CHECK: call <2 x double> @llvm.minnum.v2f64(<2 x double>  %{{.*}}, <2 x double>  %c)
-  %dx.clamp = call <2 x double> @llvm.dx.clamp.v2f64(<2 x double> %a, <2 x double> %b, <2 x double> %c)
-  ret <2 x double> %dx.clamp
-}
-
-; CHECK-LABEL: clamp_int4
-define noundef <4 x i32> @clamp_int4(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
-entry:
-  ; CHECK: call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a, <4 x i32> %b)
-  ; CHECK: call <4 x i32> @llvm.smin.v4i32(<4 x i32> %{{.*}}, <4 x i32> %c)
-  %dx.clamp = call <4 x i32> @llvm.dx.clamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
-  ret <4 x i32> %dx.clamp
-}
-
-; CHECK-LABEL: clamp_uint16_t3
-define noundef <3 x i16> @clamp_uint16_t3(<3 x i16> noundef %a, <3 x i16> noundef %b, <3 x i16> noundef %c) {
-entry:
-  ; CHECK: call <3 x i16> @llvm.umax.v3i16(<3 x i16>  %a, <3 x i16>  %b)
-  ; CHECK: call <3 x i16> @llvm.umin.v3i16(<3 x i16>  %{{.*}}, <3 x i16>  %c)
-  %dx.clamp = call <3 x i16> @llvm.dx.uclamp.v3i16(<3 x i16> %a, <3 x i16> %b, <3 x i16> %c)
-  ret <3 x i16> %dx.clamp
-}
-
-; CHECK-LABEL: clamp_uint4
-define noundef <4 x i32> @clamp_uint4(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
-entry:
-  ; CHECK: call <4 x i32> @llvm.umax.v4i32(<4 x i32>  %a, <4 x i32>  %b)
-  ; CHECK: call <4 x i32> @llvm.umin.v4i32(<4 x i32>  %{{.*}}, <4 x i32>  %c)
-  %dx.clamp = call <4 x i32> @llvm.dx.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
-  ret <4 x i32> %dx.clamp
-}
-
-; CHECK-LABEL: clamp_uint64_t4
-define noundef <2 x i64> @clamp_uint64_t4(<2 x i64> noundef %a, <2 x i64> noundef %b, <2 x i64> noundef %c) {
-entry:
-  ; CHECK: call <2 x i64> @llvm.umax.v2i64(<2 x i64>  %a, <2 x i64>  %b)
-  ; CHECK: call <2 x i64> @llvm.umin.v2i64(<2 x i64>  %{{.*}}, <2 x i64>  %c)
-  %dx.clamp = call <2 x i64> @llvm.dx.uclamp.v2i64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c)
-  ret <2 x i64> %dx.clamp
-}
-
-declare <3 x half> @llvm.dx.clamp.v3f16(<3 x half>, <3 x half>, <3 x half>)
-declare <4 x float> @llvm.dx.clamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
-declare <2 x double> @llvm.dx.clamp.v2f64(<2 x double>, <2 x double>, <2 x double>)
-declare <4 x i32> @llvm.dx.clamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
-declare <3 x i16> @llvm.dx.uclamp.v3i32(<3 x i16>, <3 x i32>, <3 x i16>)
-declare <4 x i32> @llvm.dx.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
-declare <2 x i64> @llvm.dx.uclamp.v2i64(<2 x i64>, <2 x i64>, <2 x i64>)
diff --git a/llvm/test/CodeGen/DirectX/clamp.ll b/llvm/test/CodeGen/DirectX/clamp.ll
index 23aadf893e8ca7..6345abc1789bcf 100644
--- a/llvm/test/CodeGen/DirectX/clamp.ll
+++ b/llvm/test/CodeGen/DirectX/clamp.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -dxil-intrinsic-expansion -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
+; RUN: opt -S -dxil-intrinsic-expansion -scalarizer -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
 
 ; Make sure dxil operation function calls for clamp/uclamp are generated for half/float/double/i16/i32/i64.
 
@@ -7,7 +7,7 @@ define noundef i16 @test_clamp_i16(i16 noundef %a, i16 noundef %b, i16 noundef %
 entry:
 ; CHECK: call i16 @dx.op.binary.i16(i32 37, i16 %{{.*}}, i16 %{{.*}})
 ; CHECK: call i16 @dx.op.binary.i16(i32 38, i16 %{{.*}}, i16 %{{.*}})
-  %0 = call i16 @llvm.dx.clamp.i16(i16 %a, i16 %b, i16 %c)
+  %0 = call i16 @llvm.dx.sclamp.i16(i16 %a, i16 %b, i16 %c)
   ret i16 %0
 }
 
@@ -16,7 +16,7 @@ define noundef i32 @test_clamp_i32(i32 noundef %a, i32 noundef %b, i32 noundef %
 entry:
 ; CHECK: call i32 @dx.op.binary.i32(i32 37, i32 %{{.*}}, i32 %{{.*}})
 ; CHECK: call i32 @dx.op.binary.i32(i32 38, i32 %{{.*}}, i32 %{{.*}})
-  %0 = call i32 @llvm.dx.clamp.i32(i32 %a, i32 %b, i32 %c)
+  %0 = call i32 @llvm.dx.sclamp.i32(i32 %a, i32 %b, i32 %c)
   ret i32 %0
 }
 
@@ -25,7 +25,7 @@ define noundef i64 @test_clamp_i64(i64 noundef %a, i64 noundef %b, i64 noundef %
 entry:
 ; CHECK: call i64 @dx.op.binary.i64(i32 37, i64 %a, i64 %b)
 ; CHECK: call i64 @dx.op.binary.i64(i32 38, i64 %{{.*}}, i64 %c)
-  %0 = call i64 @llvm.dx.clamp.i64(i64 %a, i64 %b, i64 %c)
+  %0 = call i64 @llvm.dx.sclamp.i64(i64 %a, i64 %b, i64 %c)
   ret i64 %0
 }
 
@@ -34,7 +34,7 @@ define noundef half @test_clamp_half(half noundef %a, half noundef %b, half noun
 entry:
 ; CHECK: call half @dx.op.binary.f16(i32 35, half %{{.*}}, half %{{.*}})
 ; CHECK: call half @dx.op.binary.f16(i32 36, half %{{.*}}, half %{{.*}})
-  %0 = call half @llvm.dx.clamp.f16(half %a, half %b, half %c)
+  %0 = call half @llvm.dx.nclamp.f16(half %a, half %b, half %c)
   ret half %0
 }
 
@@ -43,7 +43,7 @@ define noundef float @test_clamp_float(float noundef %a, float noundef %b, float
 entry:
 ; CHECK: call float @dx.op.binary.f32(i32 35, float %{{.*}}, float %{{.*}})
 ; CHECK: call float @dx.op.binary.f32(i32 36, float %{{.*}}, float %{{.*}})
-  %0 = call float @llvm.dx.clamp.f32(float %a, float %b, float %c)
+  %0 = call float @llvm.dx.nclamp.f32(float %a, float %b, float %c)
   ret float %0
 }
 
@@ -52,7 +52,7 @@ define noundef double @test_clamp_double(double noundef %a, double noundef %b, d
 entry:
 ; CHECK: call double @dx.op.binary.f64(i32 35, double %{{.*}}, double %{{.*}})
 ; CHECK: call double @dx.op.binary.f64(i32 36, double %{{.*}}, double %{{.*}})
-  %0 = call double @llvm.dx.clamp.f64(double %a, double %b, double %c)
+  %0 = call double @llvm.dx.nclamp.f64(double %a, double %b, double %c)
   ret double %0
 }
 
@@ -83,12 +83,210 @@ entry:
   ret i64 %0
 }
 
-declare half @llvm.dx.clamp.f16(half, half, half)
-declare float @llvm.dx.clamp.f32(float, float, float)
-declare double @llvm.dx.clamp.f64(double, double, double)
-declare i16 @llvm.dx.clamp.i16(i16, i16, i16)
-declare i32 @llvm.dx.clamp.i32(i32, i32, i32)
-declare i64 @llvm.dx.clamp.i64(i64, i64, i64)
+declare half @llvm.dx.nclamp.f16(half, half, half)
+declare float @llvm.dx.nclamp.f32(float, float, float)
+declare double @llvm.dx.nclamp.f64(double, double, double)
+declare i16 @llvm.dx.sclamp.i16(i16, i16, i16)
+declare i32 @llvm.dx.sclamp.i32(i32, i32, i32)
+declare i64 @llvm.dx.sclamp.i64(i64, i64, i64)
 declare i16 @llvm.dx.uclamp.i16(i16, i16, i16)
 declare i32 @llvm.dx.uclamp.i32(i32, i32, i32)
 declare i64 @llvm.dx.uclamp.i64(i64, i64, i64)
+
+; CHECK-LABEL: clamp_half3
+define noundef <3 x half> @clamp_half3(<3 x half> noundef %a, <3 x half> noundef %b, <3 x half> noundef %c) {
+entry:
+  ; CHECK-DAG: %[[a0:.+]] = extractelement <3 x half> %a, i64 0
+  ; CHECK-DAG: %[[a1:.+]] = extractelement <3 x half> %a, i64 1
+  ; CHECK-DAG: %[[a2:.+]] = extractelement <3 x half> %a, i64 2
+  ; CHECK-DAG: %[[b0:.+]] = extractelement <3 x half> %b, i64 0
+  ; CHECK-DAG: %[[b1:.+]] = extractelement <3 x half> %b, i64 1
+  ; CHECK-DAG: %[[b2:.+]] = extractelement <3 x half> %b, i64 2
+  ; CHECK-DAG: %[[c0:.+]] = extractelement <3 x half> %c, i64 0
+  ; CHECK-DAG: %[[c1:.+]] = extractelement <3 x half> %c, i64 1
+  ; CHECK-DAG: %[[c2:.+]] = extractelement <3 x half> %c, i64 2
+  ; CHECK-DAG: %[[max0:.+]] = call half @dx.op.binary.f16(i32 35, half %[[a0]], half %[[b0]])
+  ; CHECK-DAG: %[[max1:.+]] = call half @dx.op.binary.f16(i32 35, half %[[a1]], half %[[b1]])
+  ; CHECK-DAG: %[[max2:.+]] = call half @dx.op.binary.f16(i32 35, half %[[a2]], half %[[b2]])
+  ; CHECK-DAG: %[[min0:.+]] = call half @dx.op.binary.f16(i32 36, half %[[max0]], half %[[c0]])
+  ; CHECK-DAG: %[[min1:.+]] = call half @dx.op.binary.f16(i32 36, half %[[max1]], half %[[c1]])
+  ; CHECK-DAG: %[[min2:.+]] = call half @dx.op.binary.f16(i32 36, half %[[max2]], half %[[c2]])
+  ; CHECK-DAG: %[[ret0:.+]] = insertelement <3 x half> poison, half %[[min0]], i64 0
+  ; CHECK-DAG: %[[ret1:.+]] = insertelement <3 x half> %[[ret0]], half %[[min1]], i64 1
+  ; CHECK-DAG: %[[ret2:.+]] = insertelement <3 x half> %[[ret1]], half %[[min2]], i64 2
+  ; CHECK: ret <3 x half> %[[ret2]]
+  %dx.clamp = call <3 x half> @llvm.dx.nclamp.v3f16(<3 x half> %a, <3 x half> %b, <3 x half> %c)
+  ret <3 x half> %dx.clamp
+}
+
+; CHECK-LABEL: clamp_float4
+define noundef <4 x float> @clamp_float4(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK-DAG: %[[a0:.+]] = extractelement <4 x float> %a, i64 0
+  ; CHECK-DAG: %[[a1:.+]] = extractelement <4 x float> %a, i64 1
+  ; CHECK-DAG: %[[a2:.+]] = extractelement <4 x float> %a, i64 2
+  ; CHECK-DAG: %[[a3:.+]] = extractelement <4 x float> %a, i64 3
+  ; CHECK-DAG: %[[b0:.+]] = extractelement <4 x float> %b, i64 0
+  ; CHECK-DAG: %[[b1:.+]] = extractelement <4 x float> %b, i64 1
+  ; CHECK-DAG: %[[b2:.+]] = extractelement <4 x float> %b, i64 2
+  ; CHECK-DAG: %[[b3:.+]] = extractelement <4 x float> %b, i64 3
+  ; CHECK-DAG: %[[c0:.+]] = extractelement <4 x float> %c, i64 0
+  ; CHECK-DAG: %[[c1:.+]] = extractelement <4 x float> %c, i64 1
+  ; CHECK-DAG: %[[c2:.+]] = extractelement <4 x float> %c, i64 2
+  ; CHECK-DAG: %[[c3:.+]] = extractelement <4 x float> %c, i64 3
+  ; CHECK-DAG: %[[max0:.+]] = call float @dx.op.binary.f32(i32 35, float %[[a0]], float %[[b0]])
+  ; CHECK-DAG: %[[max1:.+]] = call float @dx.op.binary.f32(i32 35, float %[[a1]], float %[[b1]])
+  ; CHECK-DAG: %[[max2:.+]] = call float @dx.op.binary.f32(i32 35, float %[[a2]], float %[[b2]])
+  ; CHECK-DAG: %[[max3:.+]] = call float @dx.op.binary.f32(i32 35, float %[[a3]], float %[[b3]])
+  ; CHECK-DAG: %[[min0:.+]] = call float @dx.op.binary.f32(i32 36, float %[[max0]], float %[[c0]])
+  ; CHECK-DAG: %[[min1:.+]] = call float @dx.op.binary.f32(i32 36, float %[[max1]], float %[[c1]])
+  ; CHECK-DAG: %[[min2:.+]] = call float @dx.op.binary.f32(i32 36, float %[[max2]], float %[[c2]])
+  ; CHECK-DAG: %[[min3:.+]] = call float @dx.op.binary.f32(i32 36, float %[[max3]], float %[[c3]])
+  ; CHECK-DAG: %[[ret0:.+]] = insertelement <4 x float> poison, float %[[min0]], i64 0
+  ; CHECK-DAG: %[[ret1:.+]] = insertelement <4 x float> %[[ret0]], float %[[min1]], i64 1
+  ; CHECK-DAG: %[[ret2:.+]] = insertelement <4 x float> %[[ret1]], float %[[min2]], i64 2
+  ; CHECK-DAG: %[[ret3:.+]] = insertelement <4 x float> %[[ret2]], float %[[min3]], i64 3
+  ; CHECK: ret <4 x float> %[[ret3]]
+  %dx.clamp = call <4 x float> @llvm.dx.nclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %dx.clamp
+}
+
+; CHECK-LABEL: clamp_double2
+define noundef <2 x double> @clamp_double2(<2 x double> noundef %a, <2 x double> noundef %b, <2 x double> noundef %c) {
+entry:
+  ; CHECK-DAG: %[[a0:.+]] = extractelement <2 x double> %a, i64 0
+  ; CHECK-DAG: %[[a1:.+]] = extractelement <2 x double> %a, i64 1
+  ; CHECK-DAG: %[[b0:.+]] = extractelement <2 x double> %b, i64 0
+  ; CHECK-DAG: %[[b1:.+]] = extractelement <2 x double> %b, i64 1
+  ; CHECK-DAG: %[[c0:.+]] = extractelement <2 x double> %c, i64 0
+  ; CHECK-DAG: %[[c1:.+]] = extractelement <2 x double> %c, i64 1
+  ; CHECK-DAG: %[[max0:.+]] = call double @dx.op.binary.f64(i32 35, double %[[a0]], double %[[b0]])
+  ; CHECK-DAG: %[[max1:.+]] = call double @dx.op.binary.f64(i32 35, double %[[a1]], double %[[b1]])
+  ; CHECK-DAG: %[[min0:.+]] = call double @dx.op.binary.f64(i32 36, double %[[max0]], double %[[c0]])
+  ; CHECK-DAG: %[[min1:.+]] = call double @dx.op.binary.f64(i32 36, double %[[max1]], double %[[c1]])
+  ; CHECK-DAG: %[[ret0:.+]] = insertelement <2 x double> poison, double %[[min0]], i64 0
+  ; CHECK-DAG: %[[ret1:.+]] = insertelement <2 x double> %[[ret0]], double %[[min1]], i64 1
+  ; CHECK: ret <2 x double> %[[ret1]]
+  %dx.clamp = call <2 x double> @llvm.dx.nclamp.v2f64(<2 x double> %a, <2 x double> %b, <2 x double> %c)
+  ret <2 x double> %dx.clamp
+}
+
+; CHECK-LABEL: clamp_int4
+define noundef <4 x i32> @clamp_int4(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK-DAG: %[[a0:.+]] = extractelement <4 x i32> %a, i64 0
+  ; CHECK-DAG: %[[a1:.+]] = extractelement <4 x i32> %a, i64 1
+  ; CHECK-DAG: %[[a2:.+]] = extractelement <4 x i32> %a, i64 2
+  ; CHECK-DAG: %[[a3:.+]] = extractelement <4 x i32> %a, i64 3
+  ; CHECK-DAG: %[[b0:.+]] = extractelement <4 x i32> %b, i64 0
+  ; CHECK-DAG: %[[b1:.+]] = extractelement <4 x i32> %b, i64 1
+  ; CHECK-DAG: %[[b2:.+]] = extractelement <4 x i32> %b, i64 2
+  ; CHECK-DAG: %[[b3:.+]] = extractelement <4 x i32> %b, i64 3
+  ; CHECK-DAG: %[[c0:.+]] = extractelement <4 x i32> %c, i64 0
+  ; CHECK-DAG: %[[c1:.+]] = extractelement <4 x i32> %c, i64 1
+  ; CHECK-DAG: %[[c2:.+]] = extractelement <4 x i32> %c, i64 2
+  ; CHECK-DAG: %[[c3:.+]] = extractelement <4 x i32> %c, i64 3
+  ; CHECK-DAG: %[[max0:.+]] = call i32 @dx.op.binary.i32(i32 37, i32 %[[a0]], i32 %[[b0]])
+  ; CHECK-DAG: %[[max1:.+]] = call i32 @dx.op.binary.i32(i32 37, i32 %[[a1]], i32 %[[b1]])
+  ; CHECK-DAG: %[[max2:.+]] = call i32 @dx.op.binary.i32(i32 37, i32 %[[a2]], i32 %[[b2]])
+  ; CHECK-DAG: %[[max3:.+]] = call i32 @dx.op.binary.i32(i32 37, i32 %[[a3]], i32 %[[b3]])
+  ; CHECK-DAG: %[[min0:.+]] = call i32 @dx.op.binary.i32(i32 38, i32 %[[max0]], i32 %[[c0]])
+  ; CHECK-DAG: %[[min1:.+]] = call i32 @dx.op.binary.i32(i32 38, i32 %[[max1]], i32 %[[c1]])
+  ; CHECK-DAG: %[[min2:.+]] = call i32 @dx.op.binary.i32(i32 38, i32 %[[max2]], i32 %[[c2]])
+  ; CHECK-DAG: %[[min3:.+]] = call i32 @dx.op.binary.i32(i32 38, i32 %[[max3]], i32 %[[c3]])
+  ; CHECK-DAG: %[[ret0:.+]] = insertelement <4 x i32> poison, i32 %[[min0]], i64 0
+  ; CHECK-DAG: %[[ret1:.+]] = insertelement <4 x i32> %[[ret0]], i32 %[[min1]], i64 1
+  ; CHECK-DAG: %[[ret2:.+]] = insertelement <4 x i32> %[[ret1]], i32 %[[min2]], i64 2
+  ; CHECK-DAG: %[[ret3:.+]] = insertelement <4 x i32> %[[ret2]], i32 %[[min3]], i64 3
+  ; CHECK: ret <4 x i32> %[[ret3]]
+  %dx.clamp = call <4 x i32> @llvm.dx.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %dx.clamp
+}
+
+; CHECK-LABEL: clamp_uint16_t3
+define noundef <3 x i16> @clamp_uint16_t3(<3 x i16> noundef %a, <3 x i16> noundef %b, <3 x i16> noundef %c) {
+entry:
+  ; CHECK-DAG: %[[a0:.+]] = extractelement <3 x i16> %a, i64 0
+  ; CHECK-DAG: %[[a1:.+]] = extractelement <3 x i16> %a, i64 1
+  ; CHECK-DAG: %[[a2:.+]] = extractelement <3 x i16> %a, i64 2
+  ; CHECK-DAG: %[[b0:.+]] = extractelement <3 x i16> %b, i64 0
+  ; CHECK-DAG: %[[b1:.+]] = extractelement <3 x i16> %b, i64 1
+  ; CHECK-DAG: %[[b2:.+]] = extractelement <3 x i16> %b, i64 2
+  ; CHECK-DAG: %[[c0:.+]] = extractelement <3 x i16> %c, i64 0
+  ; CHECK-DAG: %[[c1:.+]] = extractelement <3 x i16> %c, i64 1
+  ; CHECK-DAG: %[[c2:.+]] = extractelement <3 x i16> %c, i64 2
+  ; CHECK-DAG: %[[max0:.+]] = call i16 @dx.op.binary.i16(i32 39, i16 %[[a0]], i16 %[[b0]])
+  ; CHECK-DAG: %[[max1:.+]] = call i16 @dx.op.binary.i16(i32 39, i16 %[[a1]], i16 %[[b1]])
+  ; CHECK-DAG: %[[max2:.+]] = call i16 @dx.op.binary.i16(i32 39, i16 %[[a2]], i16 %[[b2]])
+  ; CHECK-DAG: %[[min0:.+]] = call i16 @dx.op.binary.i16(i32 40, i16 %[[max0]], i16 %[[c0]])
+  ; CHECK-DAG: %[[min1:.+]] = call i16 @dx.op.binary.i16(i32 40, i16 %[[max1]], i16 %[[c1]])
+  ; CHECK-DAG: %[[min2:.+]] = call i16 @dx.op.binary.i16(i32 40, i16 %[[max2]], i16 %[[c2]])
+  ; CHECK-DAG: %[[ret0:.+]] = insertelement <3 x i16> poison, i16 %[[min0]], i64 0
+  ; CHECK-DAG: %[[ret1:.+]] = insertelement <3 x i16> %[[ret0]], i16 %[[min1]], i64 1
+  ; CHECK-DAG: %[[ret2:.+]] = insertelement <3 x i16> %[[ret1]], i16 %[[min2]], i64 2
+  ; CHECK: ret <3 x i16> %[[ret2]]
+  %dx.clamp = call <3 x i16> @llvm.dx.uclamp.v3i16(<3 x i16> %a, <3 x i16> %b, <3 x i16> %c)
+  ret <3 x i16> %dx.clamp
+}
+
+; CHECK-LABEL: clamp_uint4
+define noundef <4 x i32> @clamp_uint4(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK-DAG: %[[a0:.+]] = extractelement <4 x i32> %a, i64 0
+  ; CHECK-DAG: %[[a1:.+]] = extractelement <4 x i32> %a, i64 1
+  ; CHECK-DAG: %[[a2:.+]] = extractelement <4 x i32> %a, i64 2
+  ; CHECK-DAG: %[[a3:.+]] = extractelement <4 x i32> %a, i64 3
+  ; CHECK-DAG: %[[b0:.+]] = extractelement <4 x i32> %b, i64 0
+  ; CHECK-DAG: %[[b1:.+]] = extractelement <4 x i32> %b, i64 1
+  ; CHECK-DAG: %[[b2:.+]] = extractelement <4 x i32> %b, i64 2
+  ; CHECK-DAG: %[[b3:.+]] = extractelement <4 x i32> %b, i64 3
+  ; CHECK-DAG: %[[c0:.+]] = extractelement <4 x i32> %c, i64 0
+  ; CHECK-DAG: %[[c1:.+]] = extractelement <4 x i32> %c, i64 1
+  ; CHECK-DAG: %[[c2:.+]] = extractelement <4 x i32> %c, i64 2
+  ; CHECK-DAG: %[[c3:.+]] = extractelement <4 x i32> %c, i64 3
+  ; CHECK-DAG: %[[max0:.+]] = call i32 @dx.op.binary.i32(i32 39, i32 %[[a0]], i32 %[[b0]])
+  ; CHECK-DAG: %[[max1:.+]] = call i32 @dx.op.binary.i32(i32 39, i32 %[[a1]], i32 %[[b1]])
+  ; CHECK-DAG: %[[max2:.+]] = call i32 @dx.op.binary.i32(i32 39, i32 %[[a2]], i32 %[[b2]])
+  ; CHECK-DAG: %[[max3:.+]] = call i32 @dx.op.binary.i32(i32 39, i32 %[[a3]], i32 %[[b3]])
+  ; CHECK-DAG: %[[min0:.+]] = call i32 @dx.op.binary.i32(i32 40, i32 %[[max0]], i32 %[[c0]])
+  ; CHECK-DAG: %[[min1:.+]] = call i32 @dx.op.binary.i32(i32 40, i32 %[[max1]], i32 %[[c1]])
+  ; CHECK-DAG: %[[min2:.+]] = call i32 @dx.op.binary.i32(i32 40, i32 %[[max2]], i32 %[[c2]])
+  ; CHECK-DAG: %[[min3:.+]] = call i32 @dx.op.binary.i32(i32 40, i32 %[[max3]], i32 %[[c3]])
+  ; CHECK-DAG: %[[ret0:.+]] = insertelement <4 x i32> poison, i32 %[[min0]], i64 0
+  ; CHECK-DAG: %[[ret1:.+]] = insertelement <4 x i32> %[[ret0]], i32 %[[min1]], i64 1
+  ; CHECK-DAG: %[[ret2:.+]] = insertelement <4 x i32> %[[ret1]], i32 %[[min2]], i64 2
+  ; CHECK-DAG: %[[ret3:.+]] = insertelement <4 x i32> %[[ret2]], i32 %[[min3]], i64 3
+  ; CHECK: ret <4 x i32> %[[ret3]]
+  %dx.clamp = call <4 x i32> @llvm.dx.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %dx.clamp
+}
+
+; CHECK-LABEL: clamp_uint64_t4
+define noundef <2 x i64> @clamp_uint64_t4(<2 x i64> noundef %a, <2 x i64> noundef %b, <2 x i64> noundef %c) {
+entry:
+  ; CHECK-DAG: %[[a0:.+]] = extractelement <2 x i64> %a, i64 0
+  ; CHECK-DAG: %[[a1:.+]] = extractelement <2 x i64> %a, i64 1
+  ; CHECK-DAG: %[[b0:.+]] = extractelement <2 x i64> %b, i64 0
+  ; CHECK-DAG: %[[b1:.+]] = extractelement <2 x i64> %b, i64 1
+  ; CHECK-DAG: %[[c0:.+]] = extractelement <2 x i64> %c, i64 0
+  ; CHECK-DAG: %[[c1:.+]] = extractelement <2 x i64> %c, i64 1
+  ; CHECK-DAG: %[[max0:.+]] = call i64 @dx.op.binary.i64(i32 39, i64 %[[a0]], i64 %[[b0]])
+  ; CHECK-DAG: %[[max1:.+]] = call i64 @dx.op.binary.i64(i32 39, i64 %[[a1]], i64 %[[b1]])
+  ; CHECK-DAG: %[[min0:.+]] = call i64 @dx.op.binary.i64(i32 40, i64 %[[max0]], i64 %[[c0]])
+  ; CHECK-DAG: %[[min1:.+]] = call i64 @dx.op.binary.i64(i32 40, i64 %[[max1]], i64 %[[c1]])
+  ; CHECK-DAG: %[[ret0:.+]] = insertelement <2 x i64> poison, i64 %[[min0]], i64 0
+  ; CHECK-DAG: %[[ret1:.+]] = insertelement <2 x i64> %[[ret0]], i64 %[[min1]], i64 1
+  ; CHECK: ret <2 x i64> %[[ret1]]
+  %dx.clamp = call <2 x i64> @llvm.dx.uclamp.v2i64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c)
+  ret <2 x i64> %dx.clamp
+}
+
+
+declare <3 x half> @llvm.dx.nclamp.v3f16(<3 x half>, <3 x half>, <3 x half>)
+declare <4 x float> @llvm.dx.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
+declare <2 x double> @llvm.dx.nclamp.v2f64(<2 x double>, <2 x double>, <2 x double>)
+declare <4 x i32> @llvm.dx.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <3 x i16> @llvm.dx.uclamp.v3i32(<3 x i16>, <3 x i32>, <3 x i16>)
+declare <4 x i32> @llvm.dx.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <2 x i64> @llvm.dx.uclamp.v2i64(<2 x i64>, <2 x i64>, <2 x i64>)
+
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
deleted file mode 100644
index 089b76c575807a..00000000000000
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp-vec.ll
+++ /dev/null
@@ -1,130 +0,0 @@
-; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-
-; CHECK-DAG: %[[#op_ext:]] = OpExtInstImport "GLSL.std.450"
-
-; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
-; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
-; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
-
-; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
-; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
-; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
-
-; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
-; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
-; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
-
-; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
-; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
-; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
-
-; CHECK-LABEL: Begin function test_sclamp_v4i16
-define noundef <4 x i16> @test_sclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] SClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
-  %0 = call <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
-  ret <4 x i16> %0
-}
-
-; CHECK-LABEL: Begin function test_sclamp_v4i32
-define noundef <4 x i32> @test_sclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] SClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
-  %0 = call <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
-  ret <4 x i32> %0
-}
-
-; CHECK-LABEL: Begin function test_sclamp_v4i64
-define noundef <4 x i64> @test_sclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] SClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
-  %0 = call <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
-  ret <4 x i64> %0
-}
-
-; CHECK-LABEL: Begin function test_nclamp_v4half
-define noundef <4 x half> @test_nclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] NClamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
-  %0 = call <4 x half> @llvm.spv.nclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
-  ret <4 x half> %0
-}
-
-; CHECK-LABEL: Begin function test_nclamp_v4float
-define noundef <4 x float> @test_nclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] NClamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
-  %0 = call <4 x float> @llvm.spv.nclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
-  ret <4 x float> %0
-}
-
-; CHECK-LABEL: Begin function test_nclamp_v4double
-define noundef <4 x double> @test_nclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] NClamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
-  %0 = call <4 x double> @llvm.spv.nclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
-  ret <4 x double> %0
-}
-
-; CHECK-LABEL: Begin function test_uclamp_v4i16
-define noundef <4 x i16> @test_uclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] UClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
-  %0 = call <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
-  ret <4 x i16> %0
-}
-
-; CHECK-LABEL: Begin function test_uclamp_v4i32
-define noundef <4 x i32> @test_uclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] UClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
-  %0 = call <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
-  ret <4 x i32> %0
-}
-
-; CHECK-LABEL: Begin function test_uclamp_v4i64
-define noundef <4 x i64> @test_uclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] UClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
-  %0 = call <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
-  ret <4 x i64> %0
-}
-
-declare <4 x half> @llvm.spv.nclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
-declare <4 x float> @llvm.spv.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
-declare <4 x double> @llvm.spv.nclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
-declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
-declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
-declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
-declare <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
-declare <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
-declare <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
-
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
index 444ae41bbec282..9376a5433ddcff 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
@@ -11,6 +11,14 @@
 ; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
 ; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
 
+; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+
+; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
+; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
+; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
+
 ; CHECK-LABEL: Begin function test_sclamp_i16
 define noundef i16 @test_sclamp_i16(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
 entry:
@@ -120,3 +128,113 @@ declare i16 @llvm.spv.uclamp.i16(i16, i16, i16)
 declare i32 @llvm.spv.uclamp.i32(i32, i32, i32)
 declare i64 @llvm.spv.uclamp.i64(i64, i64, i64)
 
+; CHECK-LABEL: Begin function test_sclamp_v4i16
+define noundef <4 x i16> @test_sclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] SClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i32
+define noundef <4 x i32> @test_sclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] SClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i64
+define noundef <4 x i64> @test_sclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] SClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+; CHECK-LABEL: Begin function test_nclamp_v4half
+define noundef <4 x half> @test_nclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] NClamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
+  %0 = call <4 x half> @llvm.spv.nclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
+  ret <4 x half> %0
+}
+
+; CHECK-LABEL: Begin function test_nclamp_v4float
+define noundef <4 x float> @test_nclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] NClamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
+  %0 = call <4 x float> @llvm.spv.nclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %0
+}
+
+; CHECK-LABEL: Begin function test_nclamp_v4double
+define noundef <4 x double> @test_nclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] NClamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
+  %0 = call <4 x double> @llvm.spv.nclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
+  ret <4 x double> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i16
+define noundef <4 x i16> @test_uclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] UClamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i32
+define noundef <4 x i32> @test_uclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] UClamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i64
+define noundef <4 x i64> @test_uclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] UClamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+declare <4 x half> @llvm.spv.nclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
+declare <4 x float> @llvm.spv.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x double> @llvm.spv.nclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
+declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+declare <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+
+
diff --git a/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll b/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
deleted file mode 100644
index 8f6af7b5de1e97..00000000000000
--- a/llvm/test/CodeGen/SPIRV/opencl/clamp-vec.ll
+++ /dev/null
@@ -1,132 +0,0 @@
-; RUN: llc  -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-
-; CHECK-DAG: %[[#op_ext:]] = OpExtInstImport "OpenCL.std"
-
-; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
-; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
-; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
-
-; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
-; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
-; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
-
-; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
-; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
-; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
-
-; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
-; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
-; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
-
-; CHECK-LABEL: Begin function test_sclamp_v4i16
-define noundef <4 x i16> @test_sclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] s_clamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
-  %0 = call <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
-  ret <4 x i16> %0
-}
-
-; CHECK-LABEL: Begin function test_sclamp_v4i32
-define noundef <4 x i32> @test_sclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] s_clamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
-  %0 = call <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
-  ret <4 x i32> %0
-}
-
-; CHECK-LABEL: Begin function test_sclamp_v4i64
-define noundef <4 x i64> @test_sclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] s_clamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
-  %0 = call <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
-  ret <4 x i64> %0
-}
-
-; CHECK-LABEL: Begin function test_nclamp_v4half
-define noundef <4 x half> @test_nclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] fclamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
-  %0 = call <4 x half> @llvm.spv.nclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
-  ret <4 x half> %0
-}
-
-; CHECK-LABEL: Begin function test_nclamp_v4float
-define noundef <4 x float> @test_nclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] fclamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
-  %0 = call <4 x float> @llvm.spv.nclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
-  ret <4 x float> %0
-}
-
-; CHECK-LABEL: Begin function test_nclamp_v4double
-define noundef <4 x double> @test_nclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] fclamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
-  %0 = call <4 x double> @llvm.spv.nclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
-  ret <4 x double> %0
-}
-
-; CHECK-LABEL: Begin function test_uclamp_v4i16
-define noundef <4 x i16> @test_uclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] u_clamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
-  %0 = call <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
-  ret <4 x i16> %0
-}
-
-; CHECK-LABEL: Begin function test_uclamp_v4i32
-define noundef <4 x i32> @test_uclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] u_clamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
-  %0 = call <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
-  ret <4 x i32> %0
-}
-
-; CHECK-LABEL: Begin function test_uclamp_v4i64
-define noundef <4 x i64> @test_uclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
-entry:
-  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
-  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] u_clamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
-  %0 = call <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
-  ret <4 x i64> %0
-}
-
-declare <4 x half> @llvm.spv.nclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
-declare <4 x float> @llvm.spv.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
-declare <4 x double> @llvm.spv.nclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
-declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
-declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
-declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
-declare <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
-declare <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
-declare <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
-
diff --git a/llvm/test/CodeGen/SPIRV/opencl/clamp.ll b/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
index 8c6945e7bf9cfa..02e43b09a0a62b 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/clamp.ll
@@ -13,6 +13,14 @@
 ; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
 ; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
 
+; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+
+; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
+; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
+; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
+
 ; CHECK-LABEL: Begin function test_sclamp_i16
 define noundef i16 @test_sclamp_i16(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
 entry:
@@ -122,3 +130,113 @@ declare i16 @llvm.spv.uclamp.i16(i16, i16, i16)
 declare i32 @llvm.spv.uclamp.i32(i32, i32, i32)
 declare i64 @llvm.spv.uclamp.i64(i64, i64, i64)
 
+; CHECK-LABEL: Begin function test_sclamp_v4i16
+define noundef <4 x i16> @test_sclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] s_clamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i32
+define noundef <4 x i32> @test_sclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] s_clamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_sclamp_v4i64
+define noundef <4 x i64> @test_sclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] s_clamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+; CHECK-LABEL: Begin function test_nclamp_v4half
+define noundef <4 x half> @test_nclamp_v4half(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f16_arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg1:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#vec4_f16_arg2:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext]] fclamp %[[#vec4_f16_arg0]] %[[#vec4_f16_arg1]] %[[#vec4_f16_arg2]]
+  %0 = call <4 x half> @llvm.spv.nclamp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c)
+  ret <4 x half> %0
+}
+
+; CHECK-LABEL: Begin function test_nclamp_v4float
+define noundef <4 x float> @test_nclamp_v4float(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f32_arg0:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg1:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#vec4_f32_arg2:]] = OpFunctionParameter %[[#vec4_float_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext]] fclamp %[[#vec4_f32_arg0]] %[[#vec4_f32_arg1]] %[[#vec4_f32_arg2]]
+  %0 = call <4 x float> @llvm.spv.nclamp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c)
+  ret <4 x float> %0
+}
+
+; CHECK-LABEL: Begin function test_nclamp_v4double
+define noundef <4 x double> @test_nclamp_v4double(<4 x double> noundef %a, <4 x double> noundef %b, <4 x double> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_f64_arg0:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg1:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#vec4_f64_arg2:]] = OpFunctionParameter %[[#vec4_float_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext]] fclamp %[[#vec4_f64_arg0]] %[[#vec4_f64_arg1]] %[[#vec4_f64_arg2]]
+  %0 = call <4 x double> @llvm.spv.nclamp.v4f64(<4 x double> %a, <4 x double> %b, <4 x double> %c)
+  ret <4 x double> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i16
+define noundef <4 x i16> @test_uclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i16_arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg1:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#vec4_i16_arg2:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext]] u_clamp %[[#vec4_i16_arg0]] %[[#vec4_i16_arg1]] %[[#vec4_i16_arg2]]
+  %0 = call <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c)
+  ret <4 x i16> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i32
+define noundef <4 x i32> @test_uclamp_v4i32(<4 x i32> noundef %a, <4 x i32> noundef %b, <4 x i32> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i32_arg0:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg1:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#vec4_i32_arg2:]] = OpFunctionParameter %[[#vec4_int_32]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext]] u_clamp %[[#vec4_i32_arg0]] %[[#vec4_i32_arg1]] %[[#vec4_i32_arg2]]
+  %0 = call <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c)
+  ret <4 x i32> %0
+}
+
+; CHECK-LABEL: Begin function test_uclamp_v4i64
+define noundef <4 x i64> @test_uclamp_v4i64(<4 x i64> noundef %a, <4 x i64> noundef %b, <4 x i64> noundef %c) {
+entry:
+  ; CHECK: %[[#vec4_i64_arg0:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg1:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#vec4_i64_arg2:]] = OpFunctionParameter %[[#vec4_int_64]]
+  ; CHECK: %[[#]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext]] u_clamp %[[#vec4_i64_arg0]] %[[#vec4_i64_arg1]] %[[#vec4_i64_arg2]]
+  %0 = call <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c)
+  ret <4 x i64> %0
+}
+
+declare <4 x half> @llvm.spv.nclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
+declare <4 x float> @llvm.spv.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x double> @llvm.spv.nclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)
+declare <4 x i16> @llvm.spv.sclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.sclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.sclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+declare <4 x i16> @llvm.spv.uclamp.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)
+declare <4 x i32> @llvm.spv.uclamp.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
+declare <4 x i64> @llvm.spv.uclamp.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
+
+

>From abfdd15c26427fdd175e9cc33a8e7ddfc1f94d5c Mon Sep 17 00:00:00 2001
From: Adam Yang <31109344+adam-yang at users.noreply.github.com>
Date: Mon, 28 Oct 2024 14:11:27 -0700
Subject: [PATCH 8/8] Moved the declarations to the bottom

---
 .../CodeGen/SPIRV/hlsl-intrinsics/clamp.ll    | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
index 9376a5433ddcff..7ad786f78974ca 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clamp.ll
@@ -118,16 +118,6 @@ entry:
   ret i64 %0
 }
 
-declare half @llvm.spv.nclamp.f16(half, half, half)
-declare float @llvm.spv.nclamp.f32(float, float, float)
-declare double @llvm.spv.nclamp.f64(double, double, double)
-declare i16 @llvm.spv.sclamp.i16(i16, i16, i16)
-declare i32 @llvm.spv.sclamp.i32(i32, i32, i32)
-declare i64 @llvm.spv.sclamp.i64(i64, i64, i64)
-declare i16 @llvm.spv.uclamp.i16(i16, i16, i16)
-declare i32 @llvm.spv.uclamp.i32(i32, i32, i32)
-declare i64 @llvm.spv.uclamp.i64(i64, i64, i64)
-
 ; CHECK-LABEL: Begin function test_sclamp_v4i16
 define noundef <4 x i16> @test_sclamp_v4i16(<4 x i16> noundef %a, <4 x i16> noundef %b, <4 x i16> noundef %c) {
 entry:
@@ -227,6 +217,15 @@ entry:
   ret <4 x i64> %0
 }
 
+declare half @llvm.spv.nclamp.f16(half, half, half)
+declare float @llvm.spv.nclamp.f32(float, float, float)
+declare double @llvm.spv.nclamp.f64(double, double, double)
+declare i16 @llvm.spv.sclamp.i16(i16, i16, i16)
+declare i32 @llvm.spv.sclamp.i32(i32, i32, i32)
+declare i64 @llvm.spv.sclamp.i64(i64, i64, i64)
+declare i16 @llvm.spv.uclamp.i16(i16, i16, i16)
+declare i32 @llvm.spv.uclamp.i32(i32, i32, i32)
+declare i64 @llvm.spv.uclamp.i64(i64, i64, i64)
 declare <4 x half> @llvm.spv.nclamp.v4f16(<4 x half>, <4 x half>, <4 x half>)
 declare <4 x float> @llvm.spv.nclamp.v4f32(<4 x float>, <4 x float>, <4 x float>)
 declare <4 x double> @llvm.spv.nclamp.v4f64(<4 x double>, <4 x double>, <4 x double>)



More information about the cfe-commits mailing list