https://github.com/Priyanshu3820 updated 
https://github.com/llvm/llvm-project/pull/179098

>From 5f1482a60cb7a179ca6a119505bb37b43d15f454 Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Sun, 1 Feb 2026 15:38:02 +0530
Subject: [PATCH 01/13] Upstream generic intrinsic emission path

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       | 200 ++++++++++++++++++
 .../CIR/CodeGenBuiltins/X86/rd-builtins.c     |  25 +++
 2 files changed, 225 insertions(+)
 create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 5e6c9e8e2490e..5fd70df43a5f6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -26,6 +26,7 @@
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
 #include "clang/CIR/MissingFeatures.h"
+#include "llvm/IR/Intrinsics.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
@@ -726,6 +727,108 @@ static RValue tryEmitFPMathIntrinsic(CIRGenFunction &cgf, 
const CallExpr *e,
   return RValue::getIgnored();
 }
 
+static mlir::Type
+decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> &infos,
+                mlir::MLIRContext *context) {
+  using namespace llvm::Intrinsic;
+
+  IITDescriptor descriptor = infos.front();
+  infos = infos.slice(1);
+
+  switch (descriptor.Kind) {
+  case IITDescriptor::Void:
+    return cir::VoidType::get(context);
+  case IITDescriptor::Integer:
+    return cir::IntType::get(context, descriptor.Integer_Width,
+                             /*isSigned=*/true);
+  case IITDescriptor::Float:
+    return cir::SingleType::get(context);
+  case IITDescriptor::Double:
+    return cir::DoubleType::get(context);
+  default:
+    llvm_unreachable("NYI");
+  }
+}
+
+/// Helper function to correct integer signedness for intrinsic arguments.
+/// IIT always returns signed integers, but the actual intrinsic may expect
+/// unsigned integers based on the AST FunctionDecl parameter types.
+static mlir::Type getIntrinsicArgumentTypeFromAST(mlir::Type iitType,
+                                                  const CallExpr *E,
+                                                  unsigned argIndex,
+                                                  mlir::MLIRContext *context) {
+  // If it's not an integer type, return as-is
+  auto intTy = dyn_cast<cir::IntType>(iitType);
+  if (!intTy)
+    return iitType;
+
+  // Get the FunctionDecl from the CallExpr
+  const FunctionDecl *FD = nullptr;
+  if (const auto *DRE =
+          dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImpCasts())) {
+    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
+  }
+
+  // If we have FunctionDecl and this argument exists, check its signedness
+  if (FD && argIndex < FD->getNumParams()) {
+    QualType paramType = FD->getParamDecl(argIndex)->getType();
+    if (paramType->isUnsignedIntegerType()) {
+      // Create unsigned version of the type
+      return cir::IntType::get(context, intTy.getWidth(), /*isSigned=*/false);
+    }
+  }
+
+  // Default: keep IIT type (signed)
+  return iitType;
+}
+
+static mlir::Value getCorrectedPtr(mlir::Value argValue, mlir::Type expectedTy,
+                                   CIRGenBuilderTy &builder) {
+  auto ptrType = mlir::dyn_cast<cir::PointerType>(argValue.getType());
+  assert(ptrType && "expected pointer type");
+
+  auto expectedPtrType = mlir::cast<cir::PointerType>(expectedTy);
+  assert(ptrType.getPointee() != expectedPtrType.getPointee() &&
+         "types should not match");
+
+  if (ptrType.getAddrSpace() != expectedPtrType.getAddrSpace()) {
+    auto newPtrType = cir::PointerType::get(ptrType.getPointee(),
+                                            expectedPtrType.getAddrSpace());
+    return builder.createAddrSpaceCast(argValue, newPtrType);
+  }
+
+  return argValue;
+}
+
+static cir::FuncType getIntrinsicType(mlir::MLIRContext *context,
+                                      llvm::Intrinsic::ID id) {
+  using namespace llvm::Intrinsic;
+
+  SmallVector<IITDescriptor, 8> table;
+  getIntrinsicInfoTableEntries(id, table);
+
+  ArrayRef<IITDescriptor> tableRef = table;
+  mlir::Type resultTy = decodeFixedType(tableRef, context);
+
+  SmallVector<mlir::Type, 8> argTypes;
+  bool isVarArg = false;
+  while (!tableRef.empty()) {
+    auto kind = tableRef.front().Kind;
+    if (kind == IITDescriptor::VarArg) {
+      isVarArg = true;
+      break; // VarArg is last
+    }
+    argTypes.push_back(decodeFixedType(tableRef, context));
+  }
+
+  // CIR convention: no explicit void return type
+  if (isa<cir::VoidType>(resultTy))
+    return cir::FuncType::get(context, argTypes, 
/*optionalReturnType=*/nullptr,
+                              isVarArg);
+
+  return cir::FuncType::get(context, argTypes, resultTy, isVarArg);
+}
+
 RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned 
builtinID,
                                        const CallExpr *e,
                                        ReturnValueSlot returnValue) {
@@ -1816,6 +1919,103 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     return emitLibraryCall(*this, fd, e,
                            cgm.getBuiltinLibFunction(fd, builtinID));
 
+  // See if we have a target specific intrinsic.
+  std::string name = getContext().BuiltinInfo.getName(builtinID);
+  Intrinsic::ID intrinsicID = Intrinsic::not_intrinsic;
+  StringRef prefix =
+      llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
+  if (!prefix.empty()) {
+    intrinsicID = Intrinsic::getIntrinsicForClangBuiltin(prefix.data(), name);
+    // NOTE we don't need to perform a compatibility flag check here since the
+    // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter 
the
+    // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
+    if (intrinsicID == Intrinsic::not_intrinsic)
+      intrinsicID = Intrinsic::getIntrinsicForMSBuiltin(prefix.data(), name);
+  }
+
+  if (intrinsicID != Intrinsic::not_intrinsic) {
+    unsigned iceArguments = 0;
+    ASTContext::GetBuiltinTypeError error;
+    getContext().GetBuiltinType(builtinID, error, &iceArguments);
+    assert(error == ASTContext::GE_None && "Should not codegen an error");
+
+    llvm::StringRef name = llvm::Intrinsic::getName(intrinsicID);
+    // cir::LLVMIntrinsicCallOp expects intrinsic name to not have prefix
+    // "llvm." For example, `llvm.nvvm.barrier0` should be passed as
+    // `nvvm.barrier0`.
+    if (!name.consume_front("llvm."))
+      assert(false && "bad intrinsic name!");
+
+    cir::FuncType intrinsicType =
+        getIntrinsicType(&getMLIRContext(), intrinsicID);
+
+    SmallVector<mlir::Value> args;
+    for (unsigned i = 0; i < e->getNumArgs(); i++) {
+      mlir::Value argValue =
+          emitScalarOrConstFoldImmArg(iceArguments, i, e->getArg(i));
+      // If the intrinsic arg type is different from the builtin arg type
+      // we need to do a bit cast.
+      mlir::Type argType = argValue.getType();
+      mlir::Type expectedTy = intrinsicType.getInput(i);
+
+      // Use helper to get the correct integer type based on AST signedness
+      mlir::Type correctedExpectedTy =
+          getIntrinsicArgumentTypeFromAST(expectedTy, e, i, &getMLIRContext());
+
+      if (argType != correctedExpectedTy)
+        argValue = getCorrectedPtr(argValue, expectedTy, builder);
+
+      args.push_back(argValue);
+    }
+
+    cir::LLVMIntrinsicCallOp intrinsicCall = cir::LLVMIntrinsicCallOp::create(
+        builder, getLoc(e->getExprLoc()), builder.getStringAttr(name),
+        intrinsicType.getReturnType(), args);
+
+    // Convert the intrinsic result to the CallExpr/AST expected return type if
+    // they differ. This can happen when an intrinsic's IIT uses a signed
+    // integer type while the AST declares an unsigned type, or when an
+    // intrinsic returns an integer but the AST expects a pointer (or vice
+    // versa). Coerce conservatively so subsequent stores/verifications 
succeed.
+    mlir::Value intrinsicRes = intrinsicCall.getResult();
+    mlir::Type builtinReturnType = intrinsicRes.getType();
+    mlir::Type expectedRetTy = convertType(e->getType());
+
+    if (builtinReturnType != expectedRetTy) {
+      // Integer -> Integer or width/signage differences.
+      if (cir::IntType fromInt =
+              mlir::dyn_cast<cir::IntType>(builtinReturnType)) {
+        if (cir::IntType toInt = mlir::dyn_cast<cir::IntType>(expectedRetTy))
+          intrinsicRes = builder.createIntCast(intrinsicRes, expectedRetTy);
+        else if (mlir::dyn_cast<cir::PointerType>(expectedRetTy))
+          intrinsicRes = builder.createIntToPtr(intrinsicRes, expectedRetTy);
+        else
+          intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
+
+      } else if (cir::PointerType fromPtr =
+                     mlir::dyn_cast<cir::PointerType>(builtinReturnType)) {
+        if (mlir::dyn_cast<cir::IntType>(expectedRetTy))
+          intrinsicRes = builder.createPtrToInt(intrinsicRes, expectedRetTy);
+        else if (cir::PointerType toPtr =
+                     mlir::dyn_cast<cir::PointerType>(expectedRetTy)) {
+          if (fromPtr.getAddrSpace() != toPtr.getAddrSpace())
+            intrinsicRes =
+                builder.createAddrSpaceCast(intrinsicRes, expectedRetTy);
+          else if (fromPtr.getPointee() != toPtr.getPointee())
+            intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
+        } else
+          intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
+
+      } else
+        intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
+    }
+
+    if (isa<cir::VoidType>(expectedRetTy))
+      return RValue::get(nullptr);
+
+    return RValue::get(intrinsicRes);
+  }
+
   // Some target-specific builtins can have aggregate return values, e.g.
   // __builtin_arm_mve_vld2q_u32. So if the result is an aggregate, force
   // returnValue to be non-null, so that the target-specific emission code can
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c 
b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
new file mode 100644
index 0000000000000..a1ac394110e39
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
@@ -0,0 +1,25 @@
+// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -S -emit-llvm %s -o 
%t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -S -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+#include <x86intrin.h>
+
+unsigned long long test_rdpmc(int a) {
+    // CIR-LABEL: test_rdpmc
+    // CIR: cir.call @__rdpmc
+    // CIR: cir.store %{{.*}}, %{{.*}} : !u64i, !cir.ptr<!u64i>
+    // CIR: cir.return %{{.*}} : !u64i
+    
+    // LLVM-LABEL: @test_rdpmc
+    // LLVM: call i64 @llvm.x86.rdpmc
+    // LLVM: store i64 %{{.*}}, ptr %{{.*}}, align 8
+    // LLVM: ret i64 %{{.*}}
+
+    // OGCG-LABEL: @test_rdpmc
+    // OGCG: call i64 @llvm.x86.rdpmc
+    // OGCG: ret i64 %{{.*}}
+    return _rdpmc(a);
+}

>From 440ac55b0d95f24c7fbaa0df3085ca43c225876f Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Sun, 1 Feb 2026 22:33:03 +0530
Subject: [PATCH 02/13] Update test

---
 clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c 
b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
index a1ac394110e39..a66302c50cec5 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
@@ -1,12 +1,16 @@
-// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux-gnu -fclangir 
-emit-cir %s -o %t.cir
 // RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
-// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -S -emit-llvm %s -o 
%t-cir.ll
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux-gnu -fclangir 
-emit-llvm %s -o %t-cir.ll
 // RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
-// RUN: %clang -target x86_64-unknown-linux-gnu -S -emit-llvm %s -o %t.ll
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux-gnu -emit-llvm 
%s -o %t.ll
 // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
 
 #include <x86intrin.h>
 
+// CIR-LABEL: @__rdpmc
+// CIR: cir.call_llvm_intrinsic "x86.rdpmc"
+// CIR: cir.cast integral %{{.*}} : !s64i -> !u64i
+
 unsigned long long test_rdpmc(int a) {
     // CIR-LABEL: test_rdpmc
     // CIR: cir.call @__rdpmc

>From e8cd250d9f5cf4545a4324b498e253137a67fc82 Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Tue, 3 Feb 2026 19:26:22 +0530
Subject: [PATCH 03/13] Adress reviews and update test

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       | 122 +++++++-----------
 .../CIR/CodeGenBuiltins/X86/rd-builtins.c     |   3 +-
 2 files changed, 47 insertions(+), 78 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 5fd70df43a5f6..2453489b67668 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -727,8 +727,10 @@ static RValue tryEmitFPMathIntrinsic(CIRGenFunction &cgf, 
const CallExpr *e,
   return RValue::getIgnored();
 }
 
+// FIXME: Remove cgf parameter when all descriptor kinds are implemented
 static mlir::Type
-decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> &infos,
+decodeFixedType(CIRGenFunction &cgf,
+                ArrayRef<llvm::Intrinsic::IITDescriptor> &infos,
                 mlir::MLIRContext *context) {
   using namespace llvm::Intrinsic;
 
@@ -738,6 +740,8 @@ decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> 
&infos,
   switch (descriptor.Kind) {
   case IITDescriptor::Void:
     return cir::VoidType::get(context);
+  // If the intrinsic expects unsigned integers, the signedness is corrected in
+  // correctIntegerSignedness()
   case IITDescriptor::Integer:
     return cir::IntType::get(context, descriptor.Integer_Width,
                              /*isSigned=*/true);
@@ -746,39 +750,23 @@ decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> 
&infos,
   case IITDescriptor::Double:
     return cir::DoubleType::get(context);
   default:
-    llvm_unreachable("NYI");
+    cgf.cgm.errorNYI("Unimplemented intrinsic type descriptor");
+    return cir::VoidType::get(context);
   }
 }
 
-/// Helper function to correct integer signedness for intrinsic arguments.
-/// IIT always returns signed integers, but the actual intrinsic may expect
-/// unsigned integers based on the AST FunctionDecl parameter types.
-static mlir::Type getIntrinsicArgumentTypeFromAST(mlir::Type iitType,
-                                                  const CallExpr *E,
-                                                  unsigned argIndex,
-                                                  mlir::MLIRContext *context) {
-  // If it's not an integer type, return as-is
+/// Helper function to correct integer signedness for intrinsic arguments and
+/// return type. IIT always returns signed integers, but the actual intrinsic
+/// may expect unsigned integers based on the AST FunctionDecl parameter types.
+static mlir::Type correctIntegerSignedness(mlir::Type iitType, QualType 
astType,
+                                           mlir::MLIRContext *context) {
   auto intTy = dyn_cast<cir::IntType>(iitType);
   if (!intTy)
     return iitType;
 
-  // Get the FunctionDecl from the CallExpr
-  const FunctionDecl *FD = nullptr;
-  if (const auto *DRE =
-          dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImpCasts())) {
-    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
-  }
-
-  // If we have FunctionDecl and this argument exists, check its signedness
-  if (FD && argIndex < FD->getNumParams()) {
-    QualType paramType = FD->getParamDecl(argIndex)->getType();
-    if (paramType->isUnsignedIntegerType()) {
-      // Create unsigned version of the type
-      return cir::IntType::get(context, intTy.getWidth(), /*isSigned=*/false);
-    }
+  if (astType->isUnsignedIntegerType()) {
+    return cir::IntType::get(context, intTy.getWidth(), /*isSigned=*/false);
   }
-
-  // Default: keep IIT type (signed)
   return iitType;
 }
 
@@ -788,8 +776,7 @@ static mlir::Value getCorrectedPtr(mlir::Value argValue, 
mlir::Type expectedTy,
   assert(ptrType && "expected pointer type");
 
   auto expectedPtrType = mlir::cast<cir::PointerType>(expectedTy);
-  assert(ptrType.getPointee() != expectedPtrType.getPointee() &&
-         "types should not match");
+  assert(ptrType != expectedPtrType && "types should not match");
 
   if (ptrType.getAddrSpace() != expectedPtrType.getAddrSpace()) {
     auto newPtrType = cir::PointerType::get(ptrType.getPointee(),
@@ -797,10 +784,11 @@ static mlir::Value getCorrectedPtr(mlir::Value argValue, 
mlir::Type expectedTy,
     return builder.createAddrSpaceCast(argValue, newPtrType);
   }
 
-  return argValue;
+  return builder.createBitcast(argValue, expectedTy);
 }
 
-static cir::FuncType getIntrinsicType(mlir::MLIRContext *context,
+static cir::FuncType getIntrinsicType(CIRGenFunction &cgf,
+                                      mlir::MLIRContext *context,
                                       llvm::Intrinsic::ID id) {
   using namespace llvm::Intrinsic;
 
@@ -808,17 +796,18 @@ static cir::FuncType getIntrinsicType(mlir::MLIRContext 
*context,
   getIntrinsicInfoTableEntries(id, table);
 
   ArrayRef<IITDescriptor> tableRef = table;
-  mlir::Type resultTy = decodeFixedType(tableRef, context);
+  mlir::Type resultTy = decodeFixedType(cgf, tableRef, context);
 
   SmallVector<mlir::Type, 8> argTypes;
   bool isVarArg = false;
   while (!tableRef.empty()) {
-    auto kind = tableRef.front().Kind;
+    llvm::Intrinsic::IITDescriptor::IITDescriptorKind kind =
+        tableRef.front().Kind;
     if (kind == IITDescriptor::VarArg) {
       isVarArg = true;
       break; // VarArg is last
     }
-    argTypes.push_back(decodeFixedType(tableRef, context));
+    argTypes.push_back(decodeFixedType(cgf, tableRef, context));
   }
 
   // CIR convention: no explicit void return type
@@ -836,8 +825,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 
   // See if we can constant fold this builtin.  If so, don't emit it at all.
   // TODO: Extend this handling to all builtin calls that we can constant-fold.
+  // Do not constant-fold immediate (target-specific) builtins; their ASTs can
+  // trigger the constant evaluator in cases it cannot safely handle.
+  // Skip EvaluateAsRValue for those.
   Expr::EvalResult result;
-  if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) &&
+  if (e->isPRValue() && !getContext().BuiltinInfo.isImmediate(builtinID) &&
+      e->EvaluateAsRValue(result, cgm.getASTContext()) &&
       !result.hasSideEffects()) {
     if (result.Val.isInt())
       return RValue::get(builder.getConstInt(loc, result.Val.getInt()));
@@ -1947,9 +1940,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
       assert(false && "bad intrinsic name!");
 
     cir::FuncType intrinsicType =
-        getIntrinsicType(&getMLIRContext(), intrinsicID);
+        getIntrinsicType(*this, &getMLIRContext(), intrinsicID);
 
     SmallVector<mlir::Value> args;
+    const FunctionDecl *fd = e->getDirectCallee();
     for (unsigned i = 0; i < e->getNumArgs(); i++) {
       mlir::Value argValue =
           emitScalarOrConstFoldImmArg(iceArguments, i, e->getArg(i));
@@ -1958,9 +1952,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
       mlir::Type argType = argValue.getType();
       mlir::Type expectedTy = intrinsicType.getInput(i);
 
-      // Use helper to get the correct integer type based on AST signedness
-      mlir::Type correctedExpectedTy =
-          getIntrinsicArgumentTypeFromAST(expectedTy, e, i, &getMLIRContext());
+      // Correct integer signedness based on AST parameter type
+      mlir::Type correctedExpectedTy = expectedTy;
+      if (fd && i < fd->getNumParams()) {
+        correctedExpectedTy = correctIntegerSignedness(
+            expectedTy, fd->getParamDecl(i)->getType(), &getMLIRContext());
+      }
 
       if (argType != correctedExpectedTy)
         argValue = getCorrectedPtr(argValue, expectedTy, builder);
@@ -1968,49 +1965,22 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
       args.push_back(argValue);
     }
 
+    // Correct return type signedness based on AST return type before creating
+    // the call, avoiding unnecessary casts in the IR.
+    mlir::Type correctedReturnType = intrinsicType.getReturnType();
+    if (fd) {
+      correctedReturnType =
+          correctIntegerSignedness(intrinsicType.getReturnType(),
+                                   fd->getReturnType(), &getMLIRContext());
+    }
+
     cir::LLVMIntrinsicCallOp intrinsicCall = cir::LLVMIntrinsicCallOp::create(
         builder, getLoc(e->getExprLoc()), builder.getStringAttr(name),
-        intrinsicType.getReturnType(), args);
+        correctedReturnType, args);
 
-    // Convert the intrinsic result to the CallExpr/AST expected return type if
-    // they differ. This can happen when an intrinsic's IIT uses a signed
-    // integer type while the AST declares an unsigned type, or when an
-    // intrinsic returns an integer but the AST expects a pointer (or vice
-    // versa). Coerce conservatively so subsequent stores/verifications 
succeed.
     mlir::Value intrinsicRes = intrinsicCall.getResult();
-    mlir::Type builtinReturnType = intrinsicRes.getType();
-    mlir::Type expectedRetTy = convertType(e->getType());
-
-    if (builtinReturnType != expectedRetTy) {
-      // Integer -> Integer or width/signage differences.
-      if (cir::IntType fromInt =
-              mlir::dyn_cast<cir::IntType>(builtinReturnType)) {
-        if (cir::IntType toInt = mlir::dyn_cast<cir::IntType>(expectedRetTy))
-          intrinsicRes = builder.createIntCast(intrinsicRes, expectedRetTy);
-        else if (mlir::dyn_cast<cir::PointerType>(expectedRetTy))
-          intrinsicRes = builder.createIntToPtr(intrinsicRes, expectedRetTy);
-        else
-          intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
-
-      } else if (cir::PointerType fromPtr =
-                     mlir::dyn_cast<cir::PointerType>(builtinReturnType)) {
-        if (mlir::dyn_cast<cir::IntType>(expectedRetTy))
-          intrinsicRes = builder.createPtrToInt(intrinsicRes, expectedRetTy);
-        else if (cir::PointerType toPtr =
-                     mlir::dyn_cast<cir::PointerType>(expectedRetTy)) {
-          if (fromPtr.getAddrSpace() != toPtr.getAddrSpace())
-            intrinsicRes =
-                builder.createAddrSpaceCast(intrinsicRes, expectedRetTy);
-          else if (fromPtr.getPointee() != toPtr.getPointee())
-            intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
-        } else
-          intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
-
-      } else
-        intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy);
-    }
 
-    if (isa<cir::VoidType>(expectedRetTy))
+    if (isa<cir::VoidType>(correctedReturnType))
       return RValue::get(nullptr);
 
     return RValue::get(intrinsicRes);
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c 
b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
index a66302c50cec5..28d4d6f06ddd1 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c
@@ -8,8 +8,7 @@
 #include <x86intrin.h>
 
 // CIR-LABEL: @__rdpmc
-// CIR: cir.call_llvm_intrinsic "x86.rdpmc"
-// CIR: cir.cast integral %{{.*}} : !s64i -> !u64i
+// CIR: cir.call_llvm_intrinsic "x86.rdpmc" %{{.*}} : (!s32i) -> !u64i
 
 unsigned long long test_rdpmc(int a) {
     // CIR-LABEL: test_rdpmc

>From 016ea30078db8bdcb3818d4abde0fc9f9ea2d6fe Mon Sep 17 00:00:00 2001
From: Priyanshu Kumar <[email protected]>
Date: Thu, 5 Feb 2026 00:19:57 +0530
Subject: [PATCH 04/13] Apply suggestion from @andykaylor

Co-authored-by: Andy Kaylor <[email protected]>
---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 2453489b67668..a32bbeb749caf 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1936,8 +1936,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     // cir::LLVMIntrinsicCallOp expects intrinsic name to not have prefix
     // "llvm." For example, `llvm.nvvm.barrier0` should be passed as
     // `nvvm.barrier0`.
-    if (!name.consume_front("llvm."))
-      assert(false && "bad intrinsic name!");
+    assert(name.starts_with("llvm.");
+    name = name.drop_front(/*strlen("llvm.")=*/5);
 
     cir::FuncType intrinsicType =
         getIntrinsicType(*this, &getMLIRContext(), intrinsicID);

>From 50afc771fd753edc07a13fa9d21216664b412953 Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Thu, 5 Feb 2026 01:07:49 +0530
Subject: [PATCH 05/13] Fix syntax error

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index a32bbeb749caf..4c0bb82848d4d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1936,7 +1936,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     // cir::LLVMIntrinsicCallOp expects intrinsic name to not have prefix
     // "llvm." For example, `llvm.nvvm.barrier0` should be passed as
     // `nvvm.barrier0`.
-    assert(name.starts_with("llvm.");
+    assert(name.starts_with("llvm.") && "expected llvm. prefix");
     name = name.drop_front(/*strlen("llvm.")=*/5);
 
     cir::FuncType intrinsicType =

>From 80431425ac91b035e4095eb4d067d0b72278c73f Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Thu, 5 Feb 2026 11:26:14 +0530
Subject: [PATCH 06/13] Add test

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp |  2 ++
 clang/test/CIR/CodeGen/builtins-x86.c   | 36 +++++++++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/builtins-x86.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 4c0bb82848d4d..0da9e3189f785 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -779,6 +779,8 @@ static mlir::Value getCorrectedPtr(mlir::Value argValue, 
mlir::Type expectedTy,
   assert(ptrType != expectedPtrType && "types should not match");
 
   if (ptrType.getAddrSpace() != expectedPtrType.getAddrSpace()) {
+    assert(!cir::MissingFeatures::addressSpace() &&
+           "address space handling not yet implemented");
     auto newPtrType = cir::PointerType::get(ptrType.getPointee(),
                                             expectedPtrType.getAddrSpace());
     return builder.createAddrSpaceCast(argValue, newPtrType);
diff --git a/clang/test/CIR/CodeGen/builtins-x86.c 
b/clang/test/CIR/CodeGen/builtins-x86.c
new file mode 100644
index 0000000000000..0748147bd5b57
--- /dev/null
+++ b/clang/test/CIR/CodeGen/builtins-x86.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t-ogcg.ll
+// RUN: FileCheck --input-file=%t-ogcg.ll %s -check-prefix=OGCG
+
+void test_sfence(void) {
+  // CIR-LABEL: @test_sfence
+  // CIR: cir.call_llvm_intrinsic "x86.sse.sfence"  : () -> !void
+  // LLVM-LABEL: @test_sfence
+  // LLVM: call void @llvm.x86.sse.sfence
+  // OGCG-LABEL: @test_sfence
+  // OGCG: call void @llvm.x86.sse.sfence
+  __builtin_ia32_sfence();
+}
+
+// CIR-LABEL: @test_lfence
+void test_lfence(void) {
+  // CIR: cir.call_llvm_intrinsic "x86.sse2.lfence"  : () -> !void
+  // LLVM-LABEL: @test_lfence
+  // LLVM: call void @llvm.x86.sse2.lfence()
+  // OGCG-LABEL: @test_lfence
+  // OGCG: call void @llvm.x86.sse2.lfence()
+  __builtin_ia32_lfence();
+}
+
+void test_pause(void) {
+  // CIR-LABEL: @test_pause
+  // CIR: cir.call_llvm_intrinsic "x86.sse2.pause"  : () -> !void
+  // LLVM-LABEL: @test_pause
+  // LLVM: call void @llvm.x86.sse2.pause()
+  // OGCG-LABEL: @test_pause
+  // OGCG: call void @llvm.x86.sse2.pause()
+  __builtin_ia32_pause();
+}

>From 591473f146bff182d403ce2baab8e3df0c80d619 Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Thu, 5 Feb 2026 11:34:56 +0530
Subject: [PATCH 07/13] Update test

---
 clang/test/CIR/CodeGen/builtins-x86.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang/test/CIR/CodeGen/builtins-x86.c 
b/clang/test/CIR/CodeGen/builtins-x86.c
index 0748147bd5b57..e03cd64e063dc 100644
--- a/clang/test/CIR/CodeGen/builtins-x86.c
+++ b/clang/test/CIR/CodeGen/builtins-x86.c
@@ -8,18 +8,22 @@
 void test_sfence(void) {
   // CIR-LABEL: @test_sfence
   // CIR: cir.call_llvm_intrinsic "x86.sse.sfence"  : () -> !void
+
   // LLVM-LABEL: @test_sfence
   // LLVM: call void @llvm.x86.sse.sfence
+
   // OGCG-LABEL: @test_sfence
   // OGCG: call void @llvm.x86.sse.sfence
   __builtin_ia32_sfence();
 }
 
-// CIR-LABEL: @test_lfence
 void test_lfence(void) {
+  // CIR-LABEL: @test_lfence
   // CIR: cir.call_llvm_intrinsic "x86.sse2.lfence"  : () -> !void
+
   // LLVM-LABEL: @test_lfence
   // LLVM: call void @llvm.x86.sse2.lfence()
+
   // OGCG-LABEL: @test_lfence
   // OGCG: call void @llvm.x86.sse2.lfence()
   __builtin_ia32_lfence();
@@ -28,8 +32,10 @@ void test_lfence(void) {
 void test_pause(void) {
   // CIR-LABEL: @test_pause
   // CIR: cir.call_llvm_intrinsic "x86.sse2.pause"  : () -> !void
+  
   // LLVM-LABEL: @test_pause
   // LLVM: call void @llvm.x86.sse2.pause()
+
   // OGCG-LABEL: @test_pause
   // OGCG: call void @llvm.x86.sse2.pause()
   __builtin_ia32_pause();

>From bcb49de67658a61b1fd3b2062e65a62a481e96fb Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Sun, 8 Feb 2026 10:11:26 +0530
Subject: [PATCH 08/13] Update CIRGenBuiltin.cpp

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 0da9e3189f785..6fc48f59e9d02 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -764,9 +764,9 @@ static mlir::Type correctIntegerSignedness(mlir::Type 
iitType, QualType astType,
   if (!intTy)
     return iitType;
 
-  if (astType->isUnsignedIntegerType()) {
+  if (astType->isUnsignedIntegerType())
     return cir::IntType::get(context, intTy.getWidth(), /*isSigned=*/false);
-  }
+
   return iitType;
 }
 
@@ -1953,6 +1953,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
       // we need to do a bit cast.
       mlir::Type argType = argValue.getType();
       mlir::Type expectedTy = intrinsicType.getInput(i);
+      if (!mlir::isa<cir::PointerType>(expectedTy)) {
+        cgm.errorNYI(e->getSourceRange(),
+                     "intrinsic expects a pointer type (NYI for non-pointer)");
+        return getUndefRValue(e->getType());
+      }
 
       // Correct integer signedness based on AST parameter type
       mlir::Type correctedExpectedTy = expectedTy;

>From 1a92a0d180cbec053b14c02aaff7209abb7d604d Mon Sep 17 00:00:00 2001
From: Priyanshu Kumar <[email protected]>
Date: Sun, 8 Feb 2026 10:30:22 +0530
Subject: [PATCH 09/13] Remove support for float/double arguments

Removed handling for Float and Double types in intrinsic type descriptor.
---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 6fc48f59e9d02..27cb87ef01498 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -745,10 +745,6 @@ decodeFixedType(CIRGenFunction &cgf,
   case IITDescriptor::Integer:
     return cir::IntType::get(context, descriptor.Integer_Width,
                              /*isSigned=*/true);
-  case IITDescriptor::Float:
-    return cir::SingleType::get(context);
-  case IITDescriptor::Double:
-    return cir::DoubleType::get(context);
   default:
     cgf.cgm.errorNYI("Unimplemented intrinsic type descriptor");
     return cir::VoidType::get(context);

>From b1370f8a8c8fb165d5281a6e75b94549a8e2fab5 Mon Sep 17 00:00:00 2001
From: Priyanshu <[email protected]>
Date: Sun, 8 Feb 2026 13:38:01 +0530
Subject: [PATCH 10/13] Update CIRGenBuiltin.cpp

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 30 +++++++++++++++++++------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 27cb87ef01498..c1c45d40f8296 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1949,11 +1949,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
       // we need to do a bit cast.
       mlir::Type argType = argValue.getType();
       mlir::Type expectedTy = intrinsicType.getInput(i);
-      if (!mlir::isa<cir::PointerType>(expectedTy)) {
-        cgm.errorNYI(e->getSourceRange(),
-                     "intrinsic expects a pointer type (NYI for non-pointer)");
-        return getUndefRValue(e->getType());
-      }
 
       // Correct integer signedness based on AST parameter type
       mlir::Type correctedExpectedTy = expectedTy;
@@ -1962,8 +1957,29 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
             expectedTy, fd->getParamDecl(i)->getType(), &getMLIRContext());
       }
 
-      if (argType != correctedExpectedTy)
-        argValue = getCorrectedPtr(argValue, expectedTy, builder);
+      if (mlir::isa<cir::PointerType>(expectedTy)) {
+        bool argIsPointer = mlir::isa<cir::PointerType>(argType);
+        bool argIsVectorOfPointer = false;
+        if (auto vecTy = dyn_cast<mlir::VectorType>(argType))
+          argIsVectorOfPointer =
+              mlir::isa<cir::PointerType>(vecTy.getElementType());
+
+        if (!argIsPointer && !argIsVectorOfPointer) {
+          cgm.errorNYI(
+              e->getSourceRange(),
+              "intrinsic expects a pointer type (NYI for non-pointer)");
+          return getUndefRValue(e->getType());
+        }
+
+        // Pointer handling (address-space cast / bitcast fallback).
+        if (argType != expectedTy)
+          argValue = getCorrectedPtr(argValue, expectedTy, builder);
+      } else {
+        // Non-pointer expected type: if needed, bitcast to the corrected
+        // expected type to match signedness/representation.
+        if (argType != correctedExpectedTy)
+          argValue = builder.createBitcast(argValue, correctedExpectedTy);
+      }
 
       args.push_back(argValue);
     }

>From 4a8a5bfd85e151d0ed401a230ec9a3c40f7b5934 Mon Sep 17 00:00:00 2001
From: Priyanshu Kumar <[email protected]>
Date: Tue, 10 Feb 2026 23:25:10 +0530
Subject: [PATCH 11/13] Update clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Co-authored-by: Andy Kaylor <[email protected]>
---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index c1c45d40f8296..b6ce5207039b7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -768,8 +768,7 @@ static mlir::Type correctIntegerSignedness(mlir::Type 
iitType, QualType astType,
 
 static mlir::Value getCorrectedPtr(mlir::Value argValue, mlir::Type expectedTy,
                                    CIRGenBuilderTy &builder) {
-  auto ptrType = mlir::dyn_cast<cir::PointerType>(argValue.getType());
-  assert(ptrType && "expected pointer type");
+  auto ptrType = mlir::cast<cir::PointerType>(argValue.getType());
 
   auto expectedPtrType = mlir::cast<cir::PointerType>(expectedTy);
   assert(ptrType != expectedPtrType && "types should not match");

>From 660efb74af20fd20f04836128c6eeca0c4a655d1 Mon Sep 17 00:00:00 2001
From: Priyanshu Kumar <[email protected]>
Date: Wed, 11 Feb 2026 05:59:23 +0530
Subject: [PATCH 12/13] [CIR][X86] Add support for vpshl/vpshr builtins
 (#179538)

This patch also adds support for fshl/fshr operations so that
vpshl/vpshr intrinsics can lower to them
Part of: #167765
---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       |  19 +-
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    |  13 +-
 .../X86/avx512vbmi2-builtins.c                | 401 ++++++++++++++++++
 .../CodeGenBuiltins/builtins-elementwise.c    |  87 ++++
 4 files changed, 514 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/avx512vbmi2-builtins.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index b6ce5207039b7..1b479dde8b718 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1339,8 +1339,23 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   case Builtin::BI__builtin_elementwise_canonicalize:
   case Builtin::BI__builtin_elementwise_copysign:
   case Builtin::BI__builtin_elementwise_fma:
-  case Builtin::BI__builtin_elementwise_fshl:
-  case Builtin::BI__builtin_elementwise_fshr:
+    return errorBuiltinNYI(*this, e, builtinID);
+  case Builtin::BI__builtin_elementwise_fshl: {
+    mlir::Location loc = getLoc(e->getExprLoc());
+    mlir::Value a = emitScalarExpr(e->getArg(0));
+    mlir::Value b = emitScalarExpr(e->getArg(1));
+    mlir::Value c = emitScalarExpr(e->getArg(2));
+    return RValue::get(builder.emitIntrinsicCallOp(loc, "fshl", a.getType(),
+                                                   mlir::ValueRange{a, b, c}));
+  }
+  case Builtin::BI__builtin_elementwise_fshr: {
+    mlir::Location loc = getLoc(e->getExprLoc());
+    mlir::Value a = emitScalarExpr(e->getArg(0));
+    mlir::Value b = emitScalarExpr(e->getArg(1));
+    mlir::Value c = emitScalarExpr(e->getArg(2));
+    return RValue::get(builder.emitIntrinsicCallOp(loc, "fshr", a.getType(),
+                                                   mlir::ValueRange{a, b, c}));
+  }
   case Builtin::BI__builtin_elementwise_add_sat:
   case Builtin::BI__builtin_elementwise_sub_sat:
   case Builtin::BI__builtin_elementwise_max:
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index cad80317cb870..7800e90d130b5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -2058,6 +2058,10 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_pternlogd256_maskz:
   case X86::BI__builtin_ia32_pternlogq128_maskz:
   case X86::BI__builtin_ia32_pternlogq256_maskz:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented X86 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
   case X86::BI__builtin_ia32_vpshldd128:
   case X86::BI__builtin_ia32_vpshldd256:
   case X86::BI__builtin_ia32_vpshldd512:
@@ -2067,6 +2071,8 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_vpshldw128:
   case X86::BI__builtin_ia32_vpshldw256:
   case X86::BI__builtin_ia32_vpshldw512:
+    return emitX86FunnelShift(builder, getLoc(expr->getExprLoc()), ops[0],
+                              ops[1], ops[2], false);
   case X86::BI__builtin_ia32_vpshrdd128:
   case X86::BI__builtin_ia32_vpshrdd256:
   case X86::BI__builtin_ia32_vpshrdd512:
@@ -2076,10 +2082,9 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_vpshrdw128:
   case X86::BI__builtin_ia32_vpshrdw256:
   case X86::BI__builtin_ia32_vpshrdw512:
-    cgm.errorNYI(expr->getSourceRange(),
-                 std::string("unimplemented X86 builtin call: ") +
-                     getContext().BuiltinInfo.getName(builtinID));
-    return mlir::Value{};
+    // Ops 0 and 1 are swapped.
+    return emitX86FunnelShift(builder, getLoc(expr->getExprLoc()), ops[1],
+                              ops[0], ops[2], true);
   case X86::BI__builtin_ia32_reduce_fadd_pd512:
   case X86::BI__builtin_ia32_reduce_fadd_ps512:
   case X86::BI__builtin_ia32_reduce_fadd_ph512:
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512vbmi2-builtins.c 
b/clang/test/CIR/CodeGenBuiltins/X86/avx512vbmi2-builtins.c
new file mode 100644
index 0000000000000..170c6fd48ac81
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512vbmi2-builtins.c
@@ -0,0 +1,401 @@
+// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding -triple 
x86_64-unknown-linux-gnu -fclangir -target-feature +avx512vbmi2 -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding -triple 
x86_64-unknown-linux-gnu -fclangir -target-feature +avx512vbmi2 -emit-llvm %s 
-o %t.ll
+// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
+// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +avx512vbmi2 -emit-llvm -o %t.ll 
-Wall -Werror -Wsign-conversion
+// RUN: FileCheck --check-prefixes=OGCG --input-file=%t.ll %s
+
+
+#include <immintrin.h>
+
+__m512i test_mm512_shldv_epi64(__m512i s, __m512i a, __m512i b) {
+  // CIR-LABEL: @_mm512_shldv_epi64
+  // CIR: %{{.*}} = cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> 
!cir.vector<8 x !u64i>
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !u64i>, !cir.vector<8 x !u64i>, !cir.vector<8 x !u64i>) -> 
!cir.vector<8 x !u64i>
+  // CIR: %{{.*}} = cir.cast bitcast %{{.*}} : !cir.vector<8 x !u64i> -> 
!cir.vector<8 x !s64i>
+  // CIR-LABEL: @test_mm512_shldv_epi64
+  // CIR: %{{.*}} = cir.call @_mm512_shldv_epi64
+  // LLVM-LABEL: @test_mm512_shldv_epi64
+  // LLVM: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64>
+  // OGCG-LABEL: @test_mm512_shldv_epi64
+  // OGCG: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64>
+  return _mm512_shldv_epi64(s, a, b);
+}
+
+__m512i test_mm512_mask_shldi_epi64(__m512i s, __mmask8 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: test_mm512_mask_shldi_epi64
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}}
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}})
+  // LLVM-LABEL: @test_mm512_mask_shldi_epi64
+  // LLVM: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64> splat (i64 47))
+  // LLVM: select <8 x i1> {{.*}}, <8 x i64> {{.*}}, <8 x i64>
+  // OGCG-LABEL: @test_mm512_mask_shldi_epi64
+  // OGCG: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64> splat (i64 47))
+  // OGCG: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_shldi_epi64(s, u, a, b, 47);
+}
+
+__m512i test_mm512_maskz_shldi_epi64(__mmask8 u, __m512i a, __m512i b) {
+  // CIR-LABEL: test_mm512_maskz_shldi_epi64
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !u64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<8 x 
!cir.int<s, 1>>, !cir.vector<8 x !s64i>
+  // LLVM-LABEL: @test_mm512_maskz_shldi_epi64
+  // LLVM: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64> splat (i64 63))
+  // LLVM: select <8 x i1> {{.*}}, <8 x i64> {{.*}}, <8 x i64>
+  // OGCG-LABEL: @test_mm512_maskz_shldi_epi64
+  // OGCG: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64> splat (i64 63))
+  // OGCG: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_maskz_shldi_epi64(u, a, b, 63);
+}
+
+__m512i test_mm512_shldi_epi64(__m512i a, __m512i b) {
+  // CIR-LABEL: @test_mm512_shldi_epi64
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !u64i>) -> 
!cir.vector<8 x !s64i>
+  // LLVM-LABEL: @test_mm512_shldi_epi64
+  // LLVM: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64> splat (i64 31))
+  // OGCG-LABEL: @test_mm512_shldi_epi64
+  // OGCG: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64> splat (i64 31))
+  return _mm512_shldi_epi64(a, b, 31);
+}
+
+__m512i test_mm512_mask_shldi_epi32(__m512i s, __mmask16 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: test_mm512_mask_shldi_epi32
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<16 x !s32i>, !cir.vector<16 x !s32i>, !cir.vector<16 x !u32i>) -> 
!cir.vector<16 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<16 x !s32i> -> !cir.vector<8 
x !s64i>
+  // LLVM-LABEL: @test_mm512_mask_shldi_epi32
+  // LLVM: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32> splat (i32 7))
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_mask_shldi_epi32
+  // OGCG: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32> splat (i32 7))
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_shldi_epi32(s, u, a, b, 7);
+}
+
+__m512i test_mm512_maskz_shldi_epi32(__mmask16 u, __m512i a, __m512i b) {
+  // CIR-LABEL: test_mm512_maskz_shldi_epi32
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<16 x !s32i>, !cir.vector<16 x !s32i>, !cir.vector<16 x !u32i>) -> 
!cir.vector<16 x !s32i>
+  // LLVM-LABEL: @test_mm512_maskz_shldi_epi32
+  // LLVM: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32> splat (i32 15))
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_maskz_shldi_epi32
+  // OGCG: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32> splat (i32 15))
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_shldi_epi32(u, a, b, 15);
+}
+
+__m512i test_mm512_shldi_epi32(__m512i a, __m512i b) {
+  // CIR-LABEL: test_mm512_shldi_epi32
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<16 x !s32i>, !cir.vector<16 x !s32i>, !cir.vector<16 x !u32i>) -> 
!cir.vector<16 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<16 x !s32i> -> !cir.vector<8 
x !s64i>
+  // LLVM-LABEL: @test_mm512_shldi_epi32
+  // LLVM: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32> splat (i32 31))
+  // OGCG-LABEL: @test_mm512_shldi_epi32
+  // OGCG: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32> splat (i32 31))
+  return _mm512_shldi_epi32(a, b, 31);
+}
+
+__m512i test_mm512_mask_shldi_epi16(__m512i s, __mmask32 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: test_mm512_mask_shldi_epi16
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<32 x !s16i>, !cir.vector<32 x !s16i>, !cir.vector<32 x !u16i>) -> 
!cir.vector<32 x !s16i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<32 x !s16i> -> !cir.vector<8 
x !s64i>
+  // LLVM-LABEL: @test_mm512_mask_shldi_epi16
+  // LLVM: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16> splat (i16 3))
+  // LLVM: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_mask_shldi_epi16
+  // OGCG: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16> splat (i16 3))
+  // OGCG: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_mask_shldi_epi16(s, u, a, b, 3);
+}
+
+__m512i test_mm512_maskz_shldi_epi16(__mmask32 u, __m512i a, __m512i b) {
+  // CIR-LABEL: test_mm512_maskz_shldi_epi16
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<32 x !s16i>, !cir.vector<32 x !s16i>, !cir.vector<32 x !u16i>) -> 
!cir.vector<32 x !s16i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<32 x !s16i> -> !cir.vector<8 
x !s64i>
+  // LLVM-LABEL: @test_mm512_maskz_shldi_epi16
+  // LLVM: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16> splat (i16 15))
+  // LLVM: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_maskz_shldi_epi16
+  // OGCG: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16> splat (i16 15))
+  // OGCG: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_maskz_shldi_epi16(u, a, b, 15);
+}
+
+__m512i test_mm512_shldi_epi16(__m512i a, __m512i b) {
+  // CIR-LABEL: test_mm512_shldi_epi16
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<32 x !s16i>, !cir.vector<32 x !s16i>, !cir.vector<32 x !u16i>) -> 
!cir.vector<32 x !s16i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<32 x !s16i> -> !cir.vector<8 
x !s64i>
+  // LLVM-LABEL: @test_mm512_shldi_epi16
+  // LLVM: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16> splat (i16 31))
+  // OGCG-LABEL: @test_mm512_shldi_epi16
+  // OGCG: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16> splat (i16 31))
+  return _mm512_shldi_epi16(a, b, 31);
+}
+
+__m512i test_mm512_mask_shldv_epi64(__m512i s, __mmask8 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: _mm512_mask_shldv_epi64
+  // CIR: cir.call @_mm512_shldv_epi64(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !u8i -> !cir.vector<8 x !cir.int<s, 1>>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<8 x 
!cir.int<s, 1>>, !cir.vector<8 x !s64i>
+  // CIR-LABEL: test_mm512_mask_shldv_epi64
+  // CIR: cir.call @_mm512_mask_shldv_epi64
+  // LLVM-LABEL: @test_mm512_mask_shldv_epi64
+  // LLVM: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64>
+  // LLVM: select <8 x i1> {{.*}}, <8 x i64> {{.*}}, <8 x i64>
+  // OGCG-LABEL: @test_mm512_mask_shldv_epi64
+  // OGCG: call <8 x i64> @llvm.fshl.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64>
+  // OGCG: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_shldv_epi64(s, u, a, b);
+}
+
+__m512i test_mm512_shldv_epi32(__m512i s, __m512i a, __m512i b) {
+  // CIR-LABEL: _mm512_shldv_epi32
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<16 x !u32i>, !cir.vector<16 x !u32i>, !cir.vector<16 x !u32i>) -> 
!cir.vector<16 x !u32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<16 x !u32i> -> !cir.vector<8 
x !s64i>
+  // CIR-LABEL: test_mm512_shldv_epi32
+  // CIR: cir.call @_mm512_shldv_epi32
+  // LLVM-LABEL: @test_mm512_shldv_epi32
+  // LLVM: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_shldv_epi32
+  // OGCG: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32>
+  return _mm512_shldv_epi32(s, a, b);
+}
+
+__m512i test_mm512_mask_shldv_epi16(__m512i s, __mmask32 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: @_mm512_mask_shldv_epi16
+  // CIR: cir.call @_mm512_shldv_epi16(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<32 
x !s16i>
+  // CIR-LABEL: @test_mm512_mask_shldv_epi16
+  // CIR: cir.call @_mm512_mask_shldv_epi16
+  // LLVM-LABEL: @test_mm512_mask_shldv_epi16
+  // LLVM: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16>
+  // LLVM: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_mask_shldv_epi16
+  // OGCG: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16>
+  // OGCG: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_mask_shldv_epi16(s, u, a, b);
+}
+
+__m512i test_mm512_maskz_shldv_epi16(__mmask32 u, __m512i s, __m512i a, 
__m512i b) {
+  // CIR-LABEL: _mm512_maskz_shldv_epi16
+  // CIR: cir.call @_mm512_shldv_epi16(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<32 
x !s16i>
+  // CIR-LABEL: @test_mm512_maskz_shldv_epi16
+  // CIR: cir.call @_mm512_maskz_shldv_epi16
+  // LLVM-LABEL: @test_mm512_maskz_shldv_epi16
+  // LLVM: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16>
+  // LLVM: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_maskz_shldv_epi16
+  // OGCG: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16>
+  // OGCG: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_maskz_shldv_epi16(u, s, a, b);
+}
+
+__m512i test_mm512_shldv_epi16(__m512i s, __m512i a, __m512i b) {
+  // CIR-LABEL: _mm512_shldv_epi16
+  // CIR: cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}}{{.*}} : 
(!cir.vector<32 x !u16i>, !cir.vector<32 x !u16i>, !cir.vector<32 x !u16i>) -> 
!cir.vector<32 x !u16i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<32 x !u16i> -> !cir.vector<8 
x !s64i>
+  // CIR-LABEL: @test_mm512_shldv_epi16
+  // CIR: cir.call @_mm512_shldv_epi16
+  // LLVM-LABEL: @test_mm512_shldv_epi16
+  // LLVM: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_shldv_epi16
+  // OGCG: call <32 x i16> @llvm.fshl.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16>
+  return _mm512_shldv_epi16(s, a, b);
+}
+
+__m512i test_mm512_mask_shrdi_epi64(__m512i s, __mmask8 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: @test_mm512_mask_shrdi_epi64
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !u64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<8 x 
!cir.int<s, 1>>, !cir.vector<8 x !s64i>
+  // LLVM-LABEL: @test_mm512_mask_shrdi_epi64
+  // LLVM: call <8 x i64> @llvm.fshr.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64> splat (i64 47))
+  // LLVM: select <8 x i1> {{.*}}, <8 x i64> {{.*}}, <8 x i64>
+  // OGCG-LABEL: @test_mm512_mask_shrdi_epi64
+  // OGCG: call <8 x i64> @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64> splat (i64 47))
+  // OGCG: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_mask_shrdi_epi64(s, u, a, b, 47);
+}
+
+__m512i test_mm512_maskz_shrdi_epi64(__mmask8 u, __m512i a, __m512i b) {
+  // CIR-LABEL: @test_mm512_maskz_shrdi_epi64
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !u64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.call @_mm512_setzero_si512() {{.*}} : () -> !cir.vector<8 x 
!s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !u8i -> !cir.vector<8 x !cir.int<s, 1>>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<8 x 
!cir.int<s, 1>>, !cir.vector<8 x !s64i>
+  // LLVM-LABEL: @test_mm512_maskz_shrdi_epi64
+  // LLVM: call <8 x i64> @llvm.fshr.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64> splat (i64 63))
+  // LLVM: select <8 x i1> {{.*}}, <8 x i64> {{.*}}, <8 x i64>
+  // OGCG-LABEL: @test_mm512_maskz_shrdi_epi64
+  // OGCG: call <8 x i64> @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64> splat (i64 63))
+  // OGCG: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
+  return _mm512_maskz_shrdi_epi64(u, a, b, 63);
+}
+
+__m512i test_mm512_shrdi_epi64(__m512i a, __m512i b) {
+  // CIR-LABEL: @test_mm512_shrdi_epi64
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !u64i>) -> 
!cir.vector<8 x !s64i>
+  // LLVM-LABEL: @test_mm512_shrdi_epi64
+  // LLVM: call <8 x i64> @llvm.fshr.v8i64(<8 x i64> {{.*}}, <8 x i64> {{.*}}, 
<8 x i64> splat (i64 31))
+  // OGCG-LABEL: @test_mm512_shrdi_epi64
+  // OGCG: call <8 x i64> @llvm.fshr.v8i64(<8 x i64> %{{.*}}, <8 x i64> 
%{{.*}}, <8 x i64> splat (i64 31))
+  return _mm512_shrdi_epi64(a, b, 31);
+}
+
+__m512i test_mm512_mask_shrdi_epi32(__m512i s, __mmask16 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: @test_mm512_mask_shrdi_epi32
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<16 x !s32i>, !cir.vector<16 x !s32i>, !cir.vector<16 x !u32i>) -> 
!cir.vector<16 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<16 x !s32i> -> !cir.vector<8 
x !s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<16 x 
!cir.int<s, 1>>, !cir.vector<16 x !s32i>
+  // LLVM-LABEL: @test_mm512_mask_shrdi_epi32
+  // LLVM: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32> splat (i32 7))
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_mask_shrdi_epi32
+  // OGCG: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32> splat (i32 7))
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_shrdi_epi32(s, u, a, b, 7);
+}
+
+__m512i test_mm512_maskz_shrdi_epi32(__mmask16 u, __m512i a, __m512i b) {
+  // CIR-LABEL: @test_mm512_maskz_shrdi_epi32
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<16 x !s32i>, !cir.vector<16 x !s32i>, !cir.vector<16 x !u32i>) -> 
!cir.vector<16 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<16 x !s32i> -> !cir.vector<8 
x !s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<16 x 
!cir.int<s, 1>>, !cir.vector<16 x !s32i>
+  // LLVM-LABEL: @test_mm512_maskz_shrdi_epi32
+  // LLVM: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32> splat (i32 15))
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_maskz_shrdi_epi32
+  // OGCG: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32> splat (i32 15))
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_shrdi_epi32(u, a, b, 15);
+}
+
+__m512i test_mm512_shrdi_epi32(__m512i a, __m512i b) {
+  // CIR-LABEL: @test_mm512_shrdi_epi32
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<16 x !s32i>, !cir.vector<16 x !s32i>, !cir.vector<16 x !u32i>) -> 
!cir.vector<16 x !s32i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<16 x !s32i> -> !cir.vector<8 
x !s64i>
+  // LLVM-LABEL: @test_mm512_shrdi_epi32
+  // LLVM: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32> splat (i32 31))
+  // OGCG-LABEL: @test_mm512_shrdi_epi32
+  // OGCG: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32> splat (i32 31))
+  return _mm512_shrdi_epi32(a, b, 31);
+}
+
+__m512i test_mm512_mask_shrdi_epi16(__m512i s, __mmask32 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: @test_mm512_mask_shrdi_epi16
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<32 x !s16i>, !cir.vector<32 x !s16i>, !cir.vector<32 x !u16i>) -> 
!cir.vector<32 x !s16i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<32 x !s16i> -> !cir.vector<8 
x !s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<32 x 
!cir.int<s, 1>>, !cir.vector<32 x !s16i>
+  // LLVM-LABEL: @test_mm512_mask_shrdi_epi16
+  // LLVM: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16> splat (i16 3))
+  // LLVM: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_mask_shrdi_epi16
+  // OGCG: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16> splat (i16 3))
+  // OGCG: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_mask_shrdi_epi16(s, u, a, b, 3);
+}
+
+__m512i test_mm512_maskz_shrdi_epi16(__mmask32 u, __m512i a, __m512i b) {
+  // CIR-LABEL: @test_mm512_maskz_shrdi_epi16
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<32 x !s16i>, !cir.vector<32 x !s16i>, !cir.vector<32 x !u16i>) -> 
!cir.vector<32 x !s16i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<32 x !s16i> -> !cir.vector<8 
x !s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<32 x 
!cir.int<s, 1>>, !cir.vector<32 x !s16i>
+  // LLVM-LABEL: @test_mm512_maskz_shrdi_epi16
+  // LLVM: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16> splat (i16 15))
+  // LLVM: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_maskz_shrdi_epi16
+  // OGCG: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16> splat (i16 15))
+  // OGCG: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_maskz_shrdi_epi16(u, a, b, 15);
+}
+
+__m512i test_mm512_shrdi_epi16(__m512i a, __m512i b) {
+  // CIR-LABEL: @test_mm512_shrdi_epi16
+  // CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<32 x !s16i>, !cir.vector<32 x !s16i>, !cir.vector<32 x !u16i>) -> 
!cir.vector<32 x !s16i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<32 x !s16i> -> !cir.vector<8 
x !s64i>
+  // LLVM-LABEL: @test_mm512_shrdi_epi16
+  // LLVM: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16> splat (i16 31))
+  // OGCG-LABEL: @test_mm512_shrdi_epi16
+  // OGCG: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16> splat (i16 31))
+  return _mm512_shrdi_epi16(a, b, 31);
+}
+
+__m512i test_mm512_mask_shldv_epi32(__m512i s, __mmask16 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: _mm512_mask_shldv_epi32
+  // CIR: cir.call @_mm512_shldv_epi32(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<16 
x !s32i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<16 x 
!cir.int<s, 1>>, !cir.vector<16 x !s32i>
+  // CIR-LABEL: test_mm512_mask_shldv_epi32
+  // CIR: cir.call @_mm512_mask_shldv_epi32
+  // LLVM-LABEL: @test_mm512_mask_shldv_epi32
+  // LLVM: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32>
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_mask_shldv_epi32
+  // OGCG: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32>
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_shldv_epi32(s, u, a, b);
+}
+
+__m512i test_mm512_maskz_shldv_epi32(__mmask16 u, __m512i s, __m512i a, 
__m512i b) {
+  // CIR-LABEL: _mm512_maskz_shldv_epi32
+  // CIR: cir.call @_mm512_shldv_epi32(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<16 
x !s32i>
+  // CIR: cir.call @_mm512_setzero_si512() {{.*}} : () -> !cir.vector<8 x 
!s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<16 x 
!cir.int<s, 1>>, !cir.vector<16 x !s32i>
+  // CIR-LABEL: test_mm512_maskz_shldv_epi32
+  // CIR: cir.call @_mm512_maskz_shldv_epi32
+  // LLVM-LABEL: @test_mm512_maskz_shldv_epi32
+  // LLVM: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32>
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_maskz_shldv_epi32
+  // OGCG: call <16 x i32> @llvm.fshl.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32>
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_shldv_epi32(u, s, a, b);
+}
+
+__m512i test_mm512_mask_shrdv_epi32(__m512i s, __mmask16 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: @_mm512_shrdv_epi32
+  // CIR: cir.call @_mm512_shrdv_epi32(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<16 
x !s32i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<16 x 
!cir.int<s, 1>>, !cir.vector<16 x !s32i>
+  // CIR-LABEL: @test_mm512_mask_shrdv_epi32
+  // CIR: cir.call @_mm512_mask_shrdv_epi32
+  // LLVM-LABEL: @test_mm512_mask_shrdv_epi32
+  // LLVM: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32>
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_mask_shrdv_epi32
+  // OGCG: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32>
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_mask_shrdv_epi32(s, u, a, b);
+}
+
+__m512i test_mm512_maskz_shrdv_epi32(__mmask16 u, __m512i s, __m512i a, 
__m512i b) {
+  // CIR-LABEL: _mm512_maskz_shrdv_epi32
+  // CIR: cir.call @_mm512_shrdv_epi32(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<16 
x !s32i>
+  // CIR: cir.call @_mm512_setzero_si512() {{.*}} : () -> !cir.vector<8 x 
!s64i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<16 x 
!cir.int<s, 1>>, !cir.vector<16 x !s32i>
+  // CIR-LABEL: test_mm512_maskz_shrdv_epi32
+  // CIR: cir.call @_mm512_maskz_shrdv_epi32
+  // LLVM-LABEL: @test_mm512_maskz_shrdv_epi32
+  // LLVM: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> {{.*}}, <16 x i32> 
{{.*}}, <16 x i32>
+  // LLVM: select <16 x i1> {{.*}}, <16 x i32> {{.*}}, <16 x i32>
+  // OGCG-LABEL: @test_mm512_maskz_shrdv_epi32
+  // OGCG: call <16 x i32> @llvm.fshr.v16i32(<16 x i32> %{{.*}}, <16 x i32> 
%{{.*}}, <16 x i32>
+  // OGCG: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
+  return _mm512_maskz_shrdv_epi32(u, s, a, b);
+}
+
+__m512i test_mm512_mask_shrdv_epi16(__m512i s, __mmask32 u, __m512i a, __m512i 
b) {
+  // CIR-LABEL: _mm512_mask_shrdv_epi16
+  // CIR: cir.call @_mm512_shrdv_epi16(%{{.*}}, %{{.*}}, %{{.*}}){{.*}} : 
(!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>) -> 
!cir.vector<8 x !s64i>
+  // CIR: cir.cast bitcast %{{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<32 
x !s16i>
+  // CIR: cir.vec.ternary(%{{.*}}, %{{.*}}, %{{.*}}) : !cir.vector<32 x 
!cir.int<s, 1>>, !cir.vector<32 x !s16i>
+  // CIR-LABEL: test_mm512_mask_shrdv_epi16
+  // CIR: cir.call @_mm512_mask_shrdv_epi16
+  // LLVM: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> {{.*}}, <32 x i16> 
{{.*}}, <32 x i16>
+  // LLVM: select <32 x i1> {{.*}}, <32 x i16> {{.*}}, <32 x i16>
+  // OGCG-LABEL: @test_mm512_mask_shrdv_epi16
+  // OGCG: call <32 x i16> @llvm.fshr.v32i16(<32 x i16> %{{.*}}, <32 x i16> 
%{{.*}}, <32 x i16>
+  // OGCG: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+  return _mm512_mask_shrdv_epi16(s, u, a, b);
+}
diff --git a/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c 
b/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c
index f64080b829bdf..80fc0682f8126 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c
+++ b/clang/test/CIR/CodeGenBuiltins/builtins-elementwise.c
@@ -6,6 +6,7 @@
 // RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
 
 typedef int vint4 __attribute__((ext_vector_type(4)));
+typedef short vshort8 __attribute__((ext_vector_type(8)));
 typedef float vfloat4 __attribute__((ext_vector_type(4)));
 typedef double vdouble4 __attribute__((ext_vector_type(4)));
 
@@ -116,3 +117,89 @@ void test_builtin_elementwise_cos(float f, double d, 
vfloat4 vf4,
   // OGCG: {{%.*}} = call <4 x double> @llvm.cos.v4f64(<4 x double> {{%.*}})
   vd4 = __builtin_elementwise_cos(vd4);
 }
+
+void test_builtin_elementwise_fshl(long long int i1, long long int i2,
+                                   long long int i3, unsigned short us1,
+                                   unsigned short us2, unsigned short us3,
+                                   char c1, char c2, char c3,
+                                   unsigned char uc1, unsigned char uc2,
+                                   unsigned char uc3, vshort8 vi1,
+                                   vshort8 vi2, vshort8 vi3, vint4 vu1,
+                                   vint4 vu2, vint4 vu3) {
+  // CIR-LABEL: test_builtin_elementwise_fshl
+  // LLVM-LABEL: test_builtin_elementwise_fshl
+  // OGCG-LABEL: test_builtin_elementwise_fshl
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!s64i, !s64i, !s64i) -> !s64i
+  // LLVM: %{{.*}} = call i64 @llvm.fshl.i64(i64 %{{.*}}, i64 %{{.*}}, i64 
%{{.*}})
+  // OGCG: %{{.*}} = call i64 @llvm.fshl.i64(i64 %{{.*}}, i64 %{{.*}}, i64 
%{{.*}})
+  i1 = __builtin_elementwise_fshl(i1, i2, i3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!u16i, !u16i, !u16i) -> !u16i
+  // LLVM: %{{.*}} = call i16 @llvm.fshl.i16(i16 %{{.*}}, i16 %{{.*}}, i16 
%{{.*}})
+  // OGCG: %{{.*}} = call i16 @llvm.fshl.i16(i16 %{{.*}}, i16 %{{.*}}, i16 
%{{.*}})
+  us1 = __builtin_elementwise_fshl(us1, us2, us3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!s8i, !s8i, !s8i) -> !s8i
+  // LLVM: %{{.*}} = call i8 @llvm.fshl.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  // OGCG: %{{.*}} = call i8 @llvm.fshl.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  c1 = __builtin_elementwise_fshl(c1, c2, c3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!u8i, !u8i, !u8i) -> !u8i
+  // LLVM: %{{.*}} = call i8 @llvm.fshl.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  // OGCG: %{{.*}} = call i8 @llvm.fshl.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  uc1 = __builtin_elementwise_fshl(uc1, uc2, uc3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> 
!cir.vector<8 x !s16i>
+  // LLVM: %{{.*}} = call <8 x i16> @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x 
i16> %{{.*}}, <8 x i16> %{{.*}})
+  // OGCG: %{{.*}} = call <8 x i16> @llvm.fshl.v8i16(<8 x i16> %{{.*}}, <8 x 
i16> %{{.*}}, <8 x i16> %{{.*}})
+  vi1 = __builtin_elementwise_fshl(vi1, vi2, vi3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshl" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> 
!cir.vector<4 x !s32i>
+  // LLVM: %{{.*}} = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x 
i32> %{{.*}}, <4 x i32> %{{.*}})
+  // OGCG: %{{.*}} = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %{{.*}}, <4 x 
i32> %{{.*}}, <4 x i32> %{{.*}})
+  vu1 = __builtin_elementwise_fshl(vu1, vu2, vu3);
+}
+
+void test_builtin_elementwise_fshr(long long int i1, long long int i2,
+                                   long long int i3, unsigned short us1,
+                                   unsigned short us2, unsigned short us3,
+                                   char c1, char c2, char c3,
+                                   unsigned char uc1, unsigned char uc2,
+                                   unsigned char uc3, vshort8 vi1,
+                                   vshort8 vi2, vshort8 vi3, vint4 vu1,
+                                   vint4 vu2, vint4 vu3) {
+  // CIR-LABEL: test_builtin_elementwise_fshr
+  // LLVM-LABEL: test_builtin_elementwise_fshr
+  // OGCG-LABEL: test_builtin_elementwise_fshr
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!s64i, !s64i, !s64i) -> !s64i
+  // LLVM: %{{.*}} = call i64 @llvm.fshr.i64(i64 %{{.*}}, i64 %{{.*}}, i64 
%{{.*}})
+  // OGCG: %{{.*}} = call i64 @llvm.fshr.i64(i64 %{{.*}}, i64 %{{.*}}, i64 
%{{.*}})
+  i1 = __builtin_elementwise_fshr(i1, i2, i3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!u16i, !u16i, !u16i) -> !u16i
+  // LLVM: %{{.*}} = call i16 @llvm.fshr.i16(i16 %{{.*}}, i16 %{{.*}}, i16 
%{{.*}})
+  // OGCG: %{{.*}} = call i16 @llvm.fshr.i16(i16 %{{.*}}, i16 %{{.*}}, i16 
%{{.*}})
+  us1 = __builtin_elementwise_fshr(us1, us2, us3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!s8i, !s8i, !s8i) -> !s8i
+  // LLVM: %{{.*}} = call i8 @llvm.fshr.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  // OGCG: %{{.*}} = call i8 @llvm.fshr.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  c1 = __builtin_elementwise_fshr(c1, c2, c3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!u8i, !u8i, !u8i) -> !u8i
+  // LLVM: %{{.*}} = call i8 @llvm.fshr.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  // OGCG: %{{.*}} = call i8 @llvm.fshr.i8(i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}})
+  uc1 = __builtin_elementwise_fshr(uc1, uc2, uc3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> 
!cir.vector<8 x !s16i>
+  // LLVM: %{{.*}} = call <8 x i16> @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x 
i16> %{{.*}}, <8 x i16> %{{.*}})
+  // OGCG: %{{.*}} = call <8 x i16> @llvm.fshr.v8i16(<8 x i16> %{{.*}}, <8 x 
i16> %{{.*}}, <8 x i16> %{{.*}})
+  vi1 = __builtin_elementwise_fshr(vi1, vi2, vi3);
+
+  // CIR: %{{.*}} = cir.call_llvm_intrinsic "fshr" %{{.*}}, %{{.*}}, %{{.*}} : 
(!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> 
!cir.vector<4 x !s32i>
+  // LLVM: %{{.*}} = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x 
i32> %{{.*}}, <4 x i32> %{{.*}})
+  // OGCG: %{{.*}} = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %{{.*}}, <4 x 
i32> %{{.*}}, <4 x i32> %{{.*}})
+  vu1 = __builtin_elementwise_fshr(vu1, vu2, vu3);
+}

>From 1de953cd5929f5a8c8249738e671ae862fbc083e Mon Sep 17 00:00:00 2001
From: Priyanshu Kumar <[email protected]>
Date: Tue, 10 Feb 2026 23:25:10 +0530
Subject: [PATCH 13/13] Update clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Co-authored-by: Andy Kaylor <[email protected]>
---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 1b479dde8b718..9af00b805c37e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1924,6 +1924,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     return emitLibraryCall(*this, fd, e,
                            cgm.getBuiltinLibFunction(fd, builtinID));
 
+  // If this is a predefined lib function (e.g. malloc), emit the call
+  // using exactly the normal call path.
+  if (getContext().BuiltinInfo.isPredefinedLibFunction(builtinID))
+    return emitLibraryCall(*this, fd, e,
+                           emitScalarExpr(e->getCallee()).getDefiningOp());
+
   // See if we have a target specific intrinsic.
   std::string name = getContext().BuiltinInfo.getName(builtinID);
   Intrinsic::ID intrinsicID = Intrinsic::not_intrinsic;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to