https://github.com/Nayan0112 updated 
https://github.com/llvm/llvm-project/pull/234304

>From c4c6fa8c3bc71b552697191b282963ee0a1e237e Mon Sep 17 00:00:00 2001
From: Nayan112 <[email protected]>
Date: Wed, 21 Oct 2026 12:04:12 +0530
Subject: [PATCH 1/6] [CIR][X86] Add MSVC bit scan builtins

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 51 ++++++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenFunction.h     |  1 +
 2 files changed, 52 insertions(+)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index febcaa7459edb0..7540cdeb303411 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1077,6 +1077,50 @@ mlir::Value 
CIRGenFunction::emitX86CpuInit(mlir::Location loc) {
   return builder.createCallOp(loc, initFunc, {}).getResult();
 }
 
+mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, const 
CallExpr *E) {
+  Address indexAddress(emitPointerWithAlignment(E->getArg(0)));
+  mlir::Value argValue = emitScalarExpr(E->getArg(1));
+
+  mlir::Location loc = getLoc(E->getExprLoc());
+  mlir::Type argType = argValue.getType();
+  mlir::Type indexType = indexAddress.getElementType();
+  mlir::Type resultType = convertType(E->getType());
+
+  mlir::Value argZero = builder.getNullValue(argType, loc);
+  mlir::Value notZero = cir::CmpOp::create(
+    builder, loc, cir::CmpOpKind::ne, argValue, argZero);
+  
+  cir::IfOp::create(
+    builder, loc, notZero, /*no else branch*/false,
+    [&](mlir::OpBuilder &b, mlir::Location){
+      //TODO: forward or reverse scan
+      if (builtinID == X86::BI_BitScanForward ||
+          builtinID == X86::BI_BitScanForward64){
+          auto zeroCount = cir::BitCtzOp::create(builder, loc, argValue, true)
+                            .getResult();
+          mlir::Value castCount = builder.createCast(
+            loc, cir::CastKind::integral, zeroCount, indexType);
+          builder.createStore(loc, castCount, indexAddress, false);
+        } else {
+          unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth();
+          mlir::Value argTypeLastIndex = builder.getConstantInt(
+            loc, indexType, argWidth - 1);
+    
+          auto zeroCount = cir::BitClzOp::create(builder, loc, argValue, true)
+                            .getResult();
+          mlir::Value castCount = builder.createCast(
+            loc, cir::CastKind::integral, zeroCount, indexType);
+          mlir::Value index = builder.createNSWSub(
+            loc, argTypeLastIndex, castCount);
+          builder.createStore(loc, index, indexAddress, false);
+        }
+      builder.createYield(loc);
+    }
+  );
+  return
+    builder.createCast(loc, cir::CastKind::bool_to_int, notZero, resultType);
+}
+
 std::optional<mlir::Value>
 CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
   if (builtinID == Builtin::BI__builtin_cpu_is)
@@ -1088,6 +1132,13 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
 
   // Handle MSVC intrinsics before argument evaluation to prevent double
   // evaluation.
+
+  if (builtinID == X86::BI_BitScanForward ||
+      builtinID == X86::BI_BitScanForward64 ||
+      builtinID == X86::BI_BitScanReverse ||
+      builtinID == X86::BI_BitScanReverse64)
+      return emitX86MSVCIntrin(builtinID, expr);
+
   assert(!cir::MissingFeatures::msvcBuiltins());
 
   // Find out if any arguments are required to be integer constant expressions.
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 6ca9f27748b28c..f1a196868126a4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -2553,6 +2553,7 @@ class CIRGenFunction : public CIRGenTypeCache {
   mlir::Value emitX86CpuSupports(mlir::Location loc,
                                  std::array<uint32_t, 4> FeatureMask);
   mlir::Value emitX86CpuInit(mlir::Location loc);
+  mlir::Value emitX86MSVCIntrin(unsigned builtinID, const CallExpr *E);
   std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID,
                                                 const CallExpr *expr);
 

>From 2b385917fe01431ebbeb70b00784b91042fde0f0 Mon Sep 17 00:00:00 2001
From: dwbh21 <[email protected]>
Date: Wed, 21 Oct 2026 23:14:40 +0530
Subject: [PATCH 2/6] test added + clang formatting

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 52 +++++++--------
 clang/test/CIR/CodeGen/ms-bitscan.c        | 76 ++++++++++++++++++++++
 2 files changed, 102 insertions(+), 26 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/ms-bitscan.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 7540cdeb303411..6faf52659d8a60 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1077,7 +1077,8 @@ mlir::Value CIRGenFunction::emitX86CpuInit(mlir::Location 
loc) {
   return builder.createCallOp(loc, initFunc, {}).getResult();
 }
 
-mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, const 
CallExpr *E) {
+mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID,
+                                              const CallExpr *E) {
   Address indexAddress(emitPointerWithAlignment(E->getArg(0)));
   mlir::Value argValue = emitScalarExpr(E->getArg(1));
 
@@ -1087,38 +1088,37 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned 
builtinID, const CallExpr
   mlir::Type resultType = convertType(E->getType());
 
   mlir::Value argZero = builder.getNullValue(argType, loc);
-  mlir::Value notZero = cir::CmpOp::create(
-    builder, loc, cir::CmpOpKind::ne, argValue, argZero);
-  
+  mlir::Value notZero =
+      cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne, argValue, argZero);
+
   cir::IfOp::create(
-    builder, loc, notZero, /*no else branch*/false,
-    [&](mlir::OpBuilder &b, mlir::Location){
-      //TODO: forward or reverse scan
-      if (builtinID == X86::BI_BitScanForward ||
-          builtinID == X86::BI_BitScanForward64){
-          auto zeroCount = cir::BitCtzOp::create(builder, loc, argValue, true)
-                            .getResult();
+      builder, loc, notZero, /*no else branch*/ false,
+      [&](mlir::OpBuilder &b, mlir::Location) {
+        // TODO: forward or reverse scan
+        if (builtinID == X86::BI_BitScanForward ||
+            builtinID == X86::BI_BitScanForward64) {
+          auto zeroCount =
+              cir::BitCtzOp::create(builder, loc, argValue, true).getResult();
           mlir::Value castCount = builder.createCast(
-            loc, cir::CastKind::integral, zeroCount, indexType);
+              loc, cir::CastKind::integral, zeroCount, indexType);
           builder.createStore(loc, castCount, indexAddress, false);
         } else {
           unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth();
-          mlir::Value argTypeLastIndex = builder.getConstantInt(
-            loc, indexType, argWidth - 1);
-    
-          auto zeroCount = cir::BitClzOp::create(builder, loc, argValue, true)
-                            .getResult();
+          mlir::Value argTypeLastIndex =
+              builder.getConstantInt(loc, indexType, argWidth - 1);
+
+          auto zeroCount =
+              cir::BitClzOp::create(builder, loc, argValue, true).getResult();
           mlir::Value castCount = builder.createCast(
-            loc, cir::CastKind::integral, zeroCount, indexType);
-          mlir::Value index = builder.createNSWSub(
-            loc, argTypeLastIndex, castCount);
+              loc, cir::CastKind::integral, zeroCount, indexType);
+          mlir::Value index =
+              builder.createNSWSub(loc, argTypeLastIndex, castCount);
           builder.createStore(loc, index, indexAddress, false);
         }
-      builder.createYield(loc);
-    }
-  );
-  return
-    builder.createCast(loc, cir::CastKind::bool_to_int, notZero, resultType);
+        builder.createYield(loc);
+      });
+  return builder.createCast(loc, cir::CastKind::bool_to_int, notZero,
+                            resultType);
 }
 
 std::optional<mlir::Value>
@@ -1137,7 +1137,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
       builtinID == X86::BI_BitScanForward64 ||
       builtinID == X86::BI_BitScanReverse ||
       builtinID == X86::BI_BitScanReverse64)
-      return emitX86MSVCIntrin(builtinID, expr);
+    return emitX86MSVCIntrin(builtinID, expr);
 
   assert(!cir::MissingFeatures::msvcBuiltins());
 
diff --git a/clang/test/CIR/CodeGen/ms-bitscan.c 
b/clang/test/CIR/CodeGen/ms-bitscan.c
new file mode 100644
index 00000000000000..4ecacce2e4b4c5
--- /dev/null
+++ b/clang/test/CIR/CodeGen/ms-bitscan.c
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \
+// RUN:   -Wno-implicit-function-declaration -fclangir \
+// RUN:   -triple x86_64-unknown-linux -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+#ifdef __LP64__
+#define LONG int
+#else
+#define LONG long
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned char test_BitScanForward(unsigned LONG *Index, unsigned LONG Mask) {
+  return _BitScanForward(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanForward
+// CIR: [[ZERO_FWD:%.*]] = cir.const #cir.int<0> : !u32i
+// CIR: [[NONZERO_FWD:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD]] : !u32i
+// CIR: cir.if [[NONZERO_FWD]] {
+// CIR: cir.ctz {{%.*}} poison_zero : !u32i
+// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
+// CIR: cir.cast bool_to_int [[NONZERO_FWD]] : !cir.bool -> !u8i
+
+unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) {
+  return _BitScanReverse(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse
+// CIR: [[ZERO_REV:%.*]] = cir.const #cir.int<0> : !u32i
+// CIR: [[NONZERO_REV:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV]] : !u32i
+// CIR: cir.if [[NONZERO_REV]] {
+// CIR: cir.const #cir.int<31> : !u32i
+// CIR: cir.clz {{%.*}} poison_zero : !u32i
+// CIR: cir.sub nsw {{%.*}}, {{%.*}} : !u32i
+// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
+// CIR: cir.cast bool_to_int [[NONZERO_REV]] : !cir.bool -> !u8i
+
+#if defined(__x86_64__)
+unsigned char test_BitScanForward64(unsigned LONG *Index,
+                                    unsigned __int64 Mask) {
+  return _BitScanForward64(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanForward64
+// CIR: [[ZERO_FWD64:%.*]] = cir.const #cir.int<0> : !u64i
+// CIR: [[NONZERO_FWD64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD64]] : !u64i
+// CIR: cir.if [[NONZERO_FWD64]] {
+// CIR: cir.ctz {{%.*}} poison_zero : !u64i
+// CIR: cir.cast integral {{%.*}} : !u64i -> !u32i
+// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
+// CIR: cir.cast bool_to_int [[NONZERO_FWD64]] : !cir.bool -> !u8i
+
+unsigned char test_BitScanReverse64(unsigned LONG *Index,
+                                    unsigned __int64 Mask) {
+  return _BitScanReverse64(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse64
+// CIR: [[ZERO_REV64:%.*]] = cir.const #cir.int<0> : !u64i
+// CIR: [[NONZERO_REV64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV64]] : !u64i
+// CIR: cir.if [[NONZERO_REV64]] {
+// CIR: cir.const #cir.int<63> : !u32i
+// CIR: cir.clz {{%.*}} poison_zero : !u64i
+// CIR: cir.cast integral {{%.*}} : !u64i -> !u32i
+// CIR: cir.sub nsw {{%.*}}, {{%.*}} : !u32i
+// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
+// CIR: cir.cast bool_to_int [[NONZERO_REV64]] : !cir.bool -> !u8i
+#endif
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file

>From defd4578b0336383b47f18090d77f082f8b23a1f Mon Sep 17 00:00:00 2001
From: dwbh21 <[email protected]>
Date: Wed, 21 Oct 2026 23:19:56 +0530
Subject: [PATCH 3/6] removed auto

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 6faf52659d8a60..e0ccde3b4705cb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1097,7 +1097,7 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned 
builtinID,
         // TODO: forward or reverse scan
         if (builtinID == X86::BI_BitScanForward ||
             builtinID == X86::BI_BitScanForward64) {
-          auto zeroCount =
+          mlir::Value zeroCount =
               cir::BitCtzOp::create(builder, loc, argValue, true).getResult();
           mlir::Value castCount = builder.createCast(
               loc, cir::CastKind::integral, zeroCount, indexType);
@@ -1107,7 +1107,7 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned 
builtinID,
           mlir::Value argTypeLastIndex =
               builder.getConstantInt(loc, indexType, argWidth - 1);
 
-          auto zeroCount =
+          mlir::Value zeroCount =
               cir::BitClzOp::create(builder, loc, argValue, true).getResult();
           mlir::Value castCount = builder.createCast(
               loc, cir::CastKind::integral, zeroCount, indexType);

>From b126c47b6a8bf0d3480eaa2ccbc758a266d56b89 Mon Sep 17 00:00:00 2001
From: Nayan112 <[email protected]>
Date: Thu, 22 Oct 2026 13:00:47 +0530
Subject: [PATCH 4/6] [CIR][X86] Share MSVC intrinsic translation with CodeGen

---
 .../include/clang/CodeGenUtils/TargetUtils.h  | 50 ++++++++++
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    | 99 ++++++++++---------
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  4 +-
 clang/lib/CodeGen/CGBuiltin.h                 | 45 ---------
 clang/lib/CodeGen/CodeGenFunction.h           |  3 +-
 clang/lib/CodeGen/TargetBuiltins/X86.cpp      | 38 +------
 clang/lib/CodeGenUtils/TargetUtils.cpp        | 39 ++++++++
 7 files changed, 148 insertions(+), 130 deletions(-)

diff --git a/clang/include/clang/CodeGenUtils/TargetUtils.h 
b/clang/include/clang/CodeGenUtils/TargetUtils.h
index 1d1ada1644efc8..ff3ee3488278a4 100644
--- a/clang/include/clang/CodeGenUtils/TargetUtils.h
+++ b/clang/include/clang/CodeGenUtils/TargetUtils.h
@@ -17,6 +17,7 @@
 #include "clang/Basic/BitmaskEnum.h"
 
 #include <cstdint>
+#include <optional>
 
 namespace llvm {
 class Triple;
@@ -63,6 +64,55 @@ bool hasExtraNeonArgument(unsigned BuiltinID);
 /// Helper method to check if the underlying ABI is AAPCS
 bool isAAPCS(const TargetInfo &TargetInfo);
 
+//===----------------------------------------------------------------------===//
+// X86
+//===----------------------------------------------------------------------===//
+enum class MSVCIntrin {
+  _BitScanForward,
+  _BitScanReverse,
+  _InterlockedAnd,
+  _InterlockedCompareExchange,
+  _InterlockedDecrement,
+  _InterlockedExchange,
+  _InterlockedExchangeAdd,
+  _InterlockedExchangeSub,
+  _InterlockedIncrement,
+  _InterlockedOr,
+  _InterlockedXor,
+  _InterlockedExchangeAdd_acq,
+  _InterlockedExchangeAdd_rel,
+  _InterlockedExchangeAdd_nf,
+  _InterlockedExchange_acq,
+  _InterlockedExchange_rel,
+  _InterlockedExchange_nf,
+  _InterlockedCompareExchange_acq,
+  _InterlockedCompareExchange_rel,
+  _InterlockedCompareExchange_nf,
+  _InterlockedCompareExchange128,
+  _InterlockedCompareExchange128_acq,
+  _InterlockedCompareExchange128_rel,
+  _InterlockedCompareExchange128_nf,
+  _InterlockedOr_acq,
+  _InterlockedOr_rel,
+  _InterlockedOr_nf,
+  _InterlockedXor_acq,
+  _InterlockedXor_rel,
+  _InterlockedXor_nf,
+  _InterlockedAnd_acq,
+  _InterlockedAnd_rel,
+  _InterlockedAnd_nf,
+  _InterlockedIncrement_acq,
+  _InterlockedIncrement_rel,
+  _InterlockedIncrement_nf,
+  _InterlockedDecrement_acq,
+  _InterlockedDecrement_rel,
+  _InterlockedDecrement_nf,
+  __fastfail,
+};
+
+std::optional<MSVCIntrin>
+translateX86ToMsvcIntrin(unsigned BuiltinID);
+
 
//===----------------------------------------------------------------------===//
 // AMDGPU
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index e0ccde3b4705cb..74199ae87bc532 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -24,6 +24,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
 #include "clang/CIR/MissingFeatures.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/TargetParser/X86TargetParser.h"
@@ -1077,48 +1078,54 @@ mlir::Value 
CIRGenFunction::emitX86CpuInit(mlir::Location loc) {
   return builder.createCallOp(loc, initFunc, {}).getResult();
 }
 
-mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID,
+mlir::Value CIRGenFunction::emitX86MSVCIntrin(MSVCIntrin builtinID,
                                               const CallExpr *E) {
-  Address indexAddress(emitPointerWithAlignment(E->getArg(0)));
-  mlir::Value argValue = emitScalarExpr(E->getArg(1));
-
-  mlir::Location loc = getLoc(E->getExprLoc());
-  mlir::Type argType = argValue.getType();
-  mlir::Type indexType = indexAddress.getElementType();
-  mlir::Type resultType = convertType(E->getType());
-
-  mlir::Value argZero = builder.getNullValue(argType, loc);
-  mlir::Value notZero =
-      cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne, argValue, argZero);
-
-  cir::IfOp::create(
-      builder, loc, notZero, /*no else branch*/ false,
-      [&](mlir::OpBuilder &b, mlir::Location) {
-        // TODO: forward or reverse scan
-        if (builtinID == X86::BI_BitScanForward ||
-            builtinID == X86::BI_BitScanForward64) {
-          mlir::Value zeroCount =
-              cir::BitCtzOp::create(builder, loc, argValue, true).getResult();
-          mlir::Value castCount = builder.createCast(
-              loc, cir::CastKind::integral, zeroCount, indexType);
-          builder.createStore(loc, castCount, indexAddress, false);
-        } else {
-          unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth();
-          mlir::Value argTypeLastIndex =
-              builder.getConstantInt(loc, indexType, argWidth - 1);
-
-          mlir::Value zeroCount =
-              cir::BitClzOp::create(builder, loc, argValue, true).getResult();
-          mlir::Value castCount = builder.createCast(
-              loc, cir::CastKind::integral, zeroCount, indexType);
-          mlir::Value index =
-              builder.createNSWSub(loc, argTypeLastIndex, castCount);
-          builder.createStore(loc, index, indexAddress, false);
-        }
-        builder.createYield(loc);
-      });
-  return builder.createCast(loc, cir::CastKind::bool_to_int, notZero,
-                            resultType);
+  switch (builtinID) {
+  case MSVCIntrin::_BitScanForward:
+  case MSVCIntrin::_BitScanReverse: {
+    Address indexAddress(emitPointerWithAlignment(E->getArg(0)));
+    mlir::Value argValue = emitScalarExpr(E->getArg(1));
+
+    mlir::Location loc = getLoc(E->getExprLoc());
+    mlir::Type argType = argValue.getType();
+    mlir::Type indexType = indexAddress.getElementType();
+    mlir::Type resultType = convertType(E->getType());
+
+    mlir::Value argZero = builder.getNullValue(argType, loc);
+    mlir::Value notZero =
+        cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne, argValue, 
argZero);
+
+    cir::IfOp::create(
+        builder, loc, notZero, /*no else branch*/ false,
+        [&](mlir::OpBuilder &b, mlir::Location) {
+          if (builtinID == MSVCIntrin::_BitScanForward) {
+            mlir::Value zeroCount =
+                cir::BitCtzOp::create(builder, loc, argValue, 
true).getResult();
+            mlir::Value castCount = builder.createCast(
+                loc, cir::CastKind::integral, zeroCount, indexType);
+            builder.createStore(loc, castCount, indexAddress, false);
+          } else {
+            unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth();
+            mlir::Value argTypeLastIndex =
+                builder.getConstantInt(loc, indexType, argWidth - 1);
+
+            mlir::Value zeroCount =
+                cir::BitClzOp::create(builder, loc, argValue, 
true).getResult();
+            mlir::Value castCount = builder.createCast(
+                loc, cir::CastKind::integral, zeroCount, indexType);
+            mlir::Value index =
+                builder.createNSWSub(loc, argTypeLastIndex, castCount);
+            builder.createStore(loc, index, indexAddress, false);
+          }
+          builder.createYield(loc);
+        });
+    return builder.createCast(loc, cir::CastKind::bool_to_int, notZero,
+                              resultType);
+  }
+  default:
+    cgm.errorNYI(E->getExprLoc(), "MSVC intrinsic");
+    return {};
+  }
 }
 
 std::optional<mlir::Value>
@@ -1133,13 +1140,9 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   // Handle MSVC intrinsics before argument evaluation to prevent double
   // evaluation.
 
-  if (builtinID == X86::BI_BitScanForward ||
-      builtinID == X86::BI_BitScanForward64 ||
-      builtinID == X86::BI_BitScanReverse ||
-      builtinID == X86::BI_BitScanReverse64)
-    return emitX86MSVCIntrin(builtinID, expr);
-
-  assert(!cir::MissingFeatures::msvcBuiltins());
+  if (std::optional<MSVCIntrin> MsvcIntId =
+      CodeGenUtils::translateX86ToMsvcIntrin(builtinID))
+    return emitX86MSVCIntrin(*MsvcIntId, expr);
 
   // Find out if any arguments are required to be integer constant expressions.
   assert(!cir::MissingFeatures::handleBuiltinICEArguments());
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index f1a196868126a4..1e9641023d6b4d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -37,6 +37,7 @@
 #include "clang/CIR/MissingFeatures.h"
 #include "clang/CIR/TypeEvaluationKind.h"
 #include "clang/CodeGenUtils/StmtUtils.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include "llvm/ADT/ScopedHashTable.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Intrinsics.h"
@@ -2553,7 +2554,8 @@ class CIRGenFunction : public CIRGenTypeCache {
   mlir::Value emitX86CpuSupports(mlir::Location loc,
                                  std::array<uint32_t, 4> FeatureMask);
   mlir::Value emitX86CpuInit(mlir::Location loc);
-  mlir::Value emitX86MSVCIntrin(unsigned builtinID, const CallExpr *E);
+  using MSVCIntrin = CodeGenUtils::MSVCIntrin;
+  mlir::Value emitX86MSVCIntrin(MSVCIntrin builtinID, const CallExpr *E);
   std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID,
                                                 const CallExpr *expr);
 
diff --git a/clang/lib/CodeGen/CGBuiltin.h b/clang/lib/CodeGen/CGBuiltin.h
index 394b397fde6a9f..ddc324dbcac125 100644
--- a/clang/lib/CodeGen/CGBuiltin.h
+++ b/clang/lib/CodeGen/CGBuiltin.h
@@ -11,51 +11,6 @@
 
 #include "CodeGenFunction.h"
 
-// Many of MSVC builtins are on x64, ARM and AArch64; to avoid repeating code,
-// we handle them here.
-enum class clang::CodeGen::CodeGenFunction::MSVCIntrin {
-  _BitScanForward,
-  _BitScanReverse,
-  _InterlockedAnd,
-  _InterlockedCompareExchange,
-  _InterlockedDecrement,
-  _InterlockedExchange,
-  _InterlockedExchangeAdd,
-  _InterlockedExchangeSub,
-  _InterlockedIncrement,
-  _InterlockedOr,
-  _InterlockedXor,
-  _InterlockedExchangeAdd_acq,
-  _InterlockedExchangeAdd_rel,
-  _InterlockedExchangeAdd_nf,
-  _InterlockedExchange_acq,
-  _InterlockedExchange_rel,
-  _InterlockedExchange_nf,
-  _InterlockedCompareExchange_acq,
-  _InterlockedCompareExchange_rel,
-  _InterlockedCompareExchange_nf,
-  _InterlockedCompareExchange128,
-  _InterlockedCompareExchange128_acq,
-  _InterlockedCompareExchange128_rel,
-  _InterlockedCompareExchange128_nf,
-  _InterlockedOr_acq,
-  _InterlockedOr_rel,
-  _InterlockedOr_nf,
-  _InterlockedXor_acq,
-  _InterlockedXor_rel,
-  _InterlockedXor_nf,
-  _InterlockedAnd_acq,
-  _InterlockedAnd_rel,
-  _InterlockedAnd_nf,
-  _InterlockedIncrement_acq,
-  _InterlockedIncrement_rel,
-  _InterlockedIncrement_nf,
-  _InterlockedDecrement_acq,
-  _InterlockedDecrement_rel,
-  _InterlockedDecrement_nf,
-  __fastfail,
-};
-
 // Emit a simple intrinsic that has N scalar arguments and a return type
 // matching the argument type. It is assumed that only the first argument is
 // overloaded.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 00294ad547d5ec..3bbe632be939a8 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -35,6 +35,7 @@
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/MapVector.h"
@@ -5083,7 +5084,7 @@ class CodeGenFunction : public CodeGenTypeCache {
                                llvm::AtomicOrdering &AO,
                                llvm::SyncScope::ID &SSID);
 
-  enum class MSVCIntrin;
+  using MSVCIntrin = CodeGenUtils::MSVCIntrin;
   llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);
 
   llvm::Value *EmitBuiltinAvailable(const VersionTuple &Version);
diff --git a/clang/lib/CodeGen/TargetBuiltins/X86.cpp 
b/clang/lib/CodeGen/TargetBuiltins/X86.cpp
index e9b7e28eba31ce..acf63d414c16c9 100644
--- a/clang/lib/CodeGen/TargetBuiltins/X86.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/X86.cpp
@@ -12,6 +12,7 @@
 
 #include "CGBuiltin.h"
 #include "clang/Basic/TargetBuiltins.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/IntrinsicsX86.h"
 #include "llvm/TargetParser/X86TargetParser.h"
@@ -20,40 +21,6 @@ using namespace clang;
 using namespace CodeGen;
 using namespace llvm;
 
-static std::optional<CodeGenFunction::MSVCIntrin>
-translateX86ToMsvcIntrin(unsigned BuiltinID) {
-  using MSVCIntrin = CodeGenFunction::MSVCIntrin;
-  switch (BuiltinID) {
-  default:
-    return std::nullopt;
-  case clang::X86::BI_BitScanForward:
-  case clang::X86::BI_BitScanForward64:
-    return MSVCIntrin::_BitScanForward;
-  case clang::X86::BI_BitScanReverse:
-  case clang::X86::BI_BitScanReverse64:
-    return MSVCIntrin::_BitScanReverse;
-  case clang::X86::BI_InterlockedAnd64:
-    return MSVCIntrin::_InterlockedAnd;
-  case clang::X86::BI_InterlockedCompareExchange128:
-    return MSVCIntrin::_InterlockedCompareExchange128;
-  case clang::X86::BI_InterlockedExchange64:
-    return MSVCIntrin::_InterlockedExchange;
-  case clang::X86::BI_InterlockedExchangeAdd64:
-    return MSVCIntrin::_InterlockedExchangeAdd;
-  case clang::X86::BI_InterlockedExchangeSub64:
-    return MSVCIntrin::_InterlockedExchangeSub;
-  case clang::X86::BI_InterlockedOr64:
-    return MSVCIntrin::_InterlockedOr;
-  case clang::X86::BI_InterlockedXor64:
-    return MSVCIntrin::_InterlockedXor;
-  case clang::X86::BI_InterlockedDecrement64:
-    return MSVCIntrin::_InterlockedDecrement;
-  case clang::X86::BI_InterlockedIncrement64:
-    return MSVCIntrin::_InterlockedIncrement;
-  }
-  llvm_unreachable("must return from switch");
-}
-
 // Convert the mask from an integer type to a vector of i1.
 static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask,
                               unsigned NumElts) {
@@ -792,7 +759,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned 
BuiltinID,
 
   // Handle MSVC intrinsics before argument evaluation to prevent double
   // evaluation.
-  if (std::optional<MSVCIntrin> MsvcIntId = 
translateX86ToMsvcIntrin(BuiltinID))
+  if (std::optional<CodeGenUtils::MSVCIntrin> MsvcIntId =
+      CodeGenUtils::translateX86ToMsvcIntrin(BuiltinID))
     return EmitMSVCBuiltinExpr(*MsvcIntId, E);
 
   SmallVector<Value*, 4> Ops;
diff --git a/clang/lib/CodeGenUtils/TargetUtils.cpp 
b/clang/lib/CodeGenUtils/TargetUtils.cpp
index c2ddc7ec69da4b..67258190102167 100644
--- a/clang/lib/CodeGenUtils/TargetUtils.cpp
+++ b/clang/lib/CodeGenUtils/TargetUtils.cpp
@@ -84,6 +84,45 @@ bool isAAPCS(const TargetInfo &TargetInfo) {
   return TargetInfo.getABI().starts_with("aapcs");
 }
 
+//===----------------------------------------------------------------------===//
+// X86
+//===----------------------------------------------------------------------===//
+
+// Many of MSVC builtins are on x64, ARM and AArch64; to avoid repeating code,
+// we handle them here.
+std::optional<MSVCIntrin>
+translateX86ToMsvcIntrin(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+    return std::nullopt;
+  case clang::X86::BI_BitScanForward:
+  case clang::X86::BI_BitScanForward64:
+    return MSVCIntrin::_BitScanForward;
+  case clang::X86::BI_BitScanReverse:
+  case clang::X86::BI_BitScanReverse64:
+    return MSVCIntrin::_BitScanReverse;
+  case clang::X86::BI_InterlockedAnd64:
+    return MSVCIntrin::_InterlockedAnd;
+  case clang::X86::BI_InterlockedCompareExchange128:
+    return MSVCIntrin::_InterlockedCompareExchange128;
+  case clang::X86::BI_InterlockedExchange64:
+    return MSVCIntrin::_InterlockedExchange;
+  case clang::X86::BI_InterlockedExchangeAdd64:
+    return MSVCIntrin::_InterlockedExchangeAdd;
+  case clang::X86::BI_InterlockedExchangeSub64:
+    return MSVCIntrin::_InterlockedExchangeSub;
+  case clang::X86::BI_InterlockedOr64:
+    return MSVCIntrin::_InterlockedOr;
+  case clang::X86::BI_InterlockedXor64:
+    return MSVCIntrin::_InterlockedXor;
+  case clang::X86::BI_InterlockedDecrement64:
+    return MSVCIntrin::_InterlockedDecrement;
+  case clang::X86::BI_InterlockedIncrement64:
+    return MSVCIntrin::_InterlockedIncrement;
+  }
+  llvm_unreachable("must return from switch");
+}
+
 
//===----------------------------------------------------------------------===//
 // AMDGPU
 
//===----------------------------------------------------------------------===//

>From bd809648556b2204f061eb7a74c5f8548cb48378 Mon Sep 17 00:00:00 2001
From: Nayan112 <[email protected]>
Date: Fri, 23 Oct 2026 01:29:31 +0530
Subject: [PATCH 5/6] [CIR][X86] Address MSVC bit scan review feedback

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp   |  43 ++++++-
 clang/test/CIR/CodeGen/ms-bitscan.c          |  76 ------------
 clang/test/CIR/CodeGen/ms-intrinsics-other.c | 116 +++++++++++++++++++
 3 files changed, 156 insertions(+), 79 deletions(-)
 delete mode 100644 clang/test/CIR/CodeGen/ms-bitscan.c
 create mode 100644 clang/test/CIR/CodeGen/ms-intrinsics-other.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 4da82a3cf1fb80..3882c787a9e79c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1195,7 +1195,7 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(MSVCIntrin 
builtinID,
         [&](mlir::OpBuilder &b, mlir::Location) {
           if (builtinID == MSVCIntrin::_BitScanForward) {
             mlir::Value zeroCount =
-                cir::BitCtzOp::create(builder, loc, argValue, 
true).getResult();
+                cir::BitCtzOp::create(builder, loc, argValue, true);
             mlir::Value castCount = builder.createCast(
                 loc, cir::CastKind::integral, zeroCount, indexType);
             builder.createStore(loc, castCount, indexAddress, false);
@@ -1205,7 +1205,7 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(MSVCIntrin 
builtinID,
                 builder.getConstantInt(loc, indexType, argWidth - 1);
 
             mlir::Value zeroCount =
-                cir::BitClzOp::create(builder, loc, argValue, 
true).getResult();
+                cir::BitClzOp::create(builder, loc, argValue, true);
             mlir::Value castCount = builder.createCast(
                 loc, cir::CastKind::integral, zeroCount, indexType);
             mlir::Value index =
@@ -1217,7 +1217,44 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(MSVCIntrin 
builtinID,
     return builder.createCast(loc, cir::CastKind::bool_to_int, notZero,
                               resultType);
   }
-  default:
+  case MSVCIntrin::_InterlockedAnd:
+  case MSVCIntrin::_InterlockedExchange:
+  case MSVCIntrin::_InterlockedExchangeAdd:
+  case MSVCIntrin::_InterlockedExchangeSub:
+  case MSVCIntrin::_InterlockedOr:
+  case MSVCIntrin::_InterlockedXor:
+  case MSVCIntrin::_InterlockedExchangeAdd_acq:
+  case MSVCIntrin::_InterlockedExchangeAdd_rel:
+  case MSVCIntrin::_InterlockedExchangeAdd_nf:
+  case MSVCIntrin::_InterlockedExchange_acq:
+  case MSVCIntrin::_InterlockedExchange_rel:
+  case MSVCIntrin::_InterlockedExchange_nf:
+  case MSVCIntrin::_InterlockedCompareExchange:
+  case MSVCIntrin::_InterlockedCompareExchange_acq:
+  case MSVCIntrin::_InterlockedCompareExchange_rel:
+  case MSVCIntrin::_InterlockedCompareExchange_nf:
+  case MSVCIntrin::_InterlockedCompareExchange128:
+  case MSVCIntrin::_InterlockedCompareExchange128_acq:
+  case MSVCIntrin::_InterlockedCompareExchange128_rel:
+  case MSVCIntrin::_InterlockedCompareExchange128_nf:
+  case MSVCIntrin::_InterlockedOr_acq:
+  case MSVCIntrin::_InterlockedOr_rel:
+  case MSVCIntrin::_InterlockedOr_nf:
+  case MSVCIntrin::_InterlockedXor_acq:
+  case MSVCIntrin::_InterlockedXor_rel:
+  case MSVCIntrin::_InterlockedXor_nf:
+  case MSVCIntrin::_InterlockedAnd_acq:
+  case MSVCIntrin::_InterlockedAnd_rel:
+  case MSVCIntrin::_InterlockedAnd_nf:
+  case MSVCIntrin::_InterlockedIncrement_acq:
+  case MSVCIntrin::_InterlockedIncrement_rel:
+  case MSVCIntrin::_InterlockedIncrement_nf:
+  case MSVCIntrin::_InterlockedDecrement_acq:
+  case MSVCIntrin::_InterlockedDecrement_rel:
+  case MSVCIntrin::_InterlockedDecrement_nf:
+  case MSVCIntrin::_InterlockedDecrement:
+  case MSVCIntrin::_InterlockedIncrement:
+  case MSVCIntrin::__fastfail:
     cgm.errorNYI(E->getExprLoc(), "MSVC intrinsic");
     return {};
   }
diff --git a/clang/test/CIR/CodeGen/ms-bitscan.c 
b/clang/test/CIR/CodeGen/ms-bitscan.c
deleted file mode 100644
index 4ecacce2e4b4c5..00000000000000
--- a/clang/test/CIR/CodeGen/ms-bitscan.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \
-// RUN:   -Wno-implicit-function-declaration -fclangir \
-// RUN:   -triple x86_64-unknown-linux -emit-cir -o %t.cir %s
-// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
-
-#ifdef __LP64__
-#define LONG int
-#else
-#define LONG long
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-unsigned char test_BitScanForward(unsigned LONG *Index, unsigned LONG Mask) {
-  return _BitScanForward(Index, Mask);
-}
-
-// CIR-LABEL: cir.func{{.*}}@test_BitScanForward
-// CIR: [[ZERO_FWD:%.*]] = cir.const #cir.int<0> : !u32i
-// CIR: [[NONZERO_FWD:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD]] : !u32i
-// CIR: cir.if [[NONZERO_FWD]] {
-// CIR: cir.ctz {{%.*}} poison_zero : !u32i
-// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
-// CIR: cir.cast bool_to_int [[NONZERO_FWD]] : !cir.bool -> !u8i
-
-unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) {
-  return _BitScanReverse(Index, Mask);
-}
-
-// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse
-// CIR: [[ZERO_REV:%.*]] = cir.const #cir.int<0> : !u32i
-// CIR: [[NONZERO_REV:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV]] : !u32i
-// CIR: cir.if [[NONZERO_REV]] {
-// CIR: cir.const #cir.int<31> : !u32i
-// CIR: cir.clz {{%.*}} poison_zero : !u32i
-// CIR: cir.sub nsw {{%.*}}, {{%.*}} : !u32i
-// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
-// CIR: cir.cast bool_to_int [[NONZERO_REV]] : !cir.bool -> !u8i
-
-#if defined(__x86_64__)
-unsigned char test_BitScanForward64(unsigned LONG *Index,
-                                    unsigned __int64 Mask) {
-  return _BitScanForward64(Index, Mask);
-}
-
-// CIR-LABEL: cir.func{{.*}}@test_BitScanForward64
-// CIR: [[ZERO_FWD64:%.*]] = cir.const #cir.int<0> : !u64i
-// CIR: [[NONZERO_FWD64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD64]] : !u64i
-// CIR: cir.if [[NONZERO_FWD64]] {
-// CIR: cir.ctz {{%.*}} poison_zero : !u64i
-// CIR: cir.cast integral {{%.*}} : !u64i -> !u32i
-// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
-// CIR: cir.cast bool_to_int [[NONZERO_FWD64]] : !cir.bool -> !u8i
-
-unsigned char test_BitScanReverse64(unsigned LONG *Index,
-                                    unsigned __int64 Mask) {
-  return _BitScanReverse64(Index, Mask);
-}
-
-// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse64
-// CIR: [[ZERO_REV64:%.*]] = cir.const #cir.int<0> : !u64i
-// CIR: [[NONZERO_REV64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV64]] : !u64i
-// CIR: cir.if [[NONZERO_REV64]] {
-// CIR: cir.const #cir.int<63> : !u32i
-// CIR: cir.clz {{%.*}} poison_zero : !u64i
-// CIR: cir.cast integral {{%.*}} : !u64i -> !u32i
-// CIR: cir.sub nsw {{%.*}}, {{%.*}} : !u32i
-// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i>
-// CIR: cir.cast bool_to_int [[NONZERO_REV64]] : !cir.bool -> !u8i
-#endif
-
-#ifdef __cplusplus
-}
-#endif
\ No newline at end of file
diff --git a/clang/test/CIR/CodeGen/ms-intrinsics-other.c 
b/clang/test/CIR/CodeGen/ms-intrinsics-other.c
new file mode 100644
index 00000000000000..26d05eb6baddae
--- /dev/null
+++ b/clang/test/CIR/CodeGen/ms-intrinsics-other.c
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \
+// RUN:   -Wno-implicit-function-declaration -fclangir \
+// RUN:   -triple x86_64-unknown-linux -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+//
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \
+// RUN:   -Wno-implicit-function-declaration -fclangir \
+// RUN:   -triple x86_64-unknown-linux -emit-llvm -o %t-cir.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+//
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \
+// RUN:   -Wno-implicit-function-declaration \
+// RUN:   -triple x86_64-unknown-linux -emit-llvm -o %t-ogcg.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-ogcg.ll %s
+
+#ifdef __LP64__
+#define LONG int
+#else
+#define LONG long
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned char test_BitScanForward(unsigned LONG *Index, unsigned LONG Mask) {
+  return _BitScanForward(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanForward
+// CIR:         [[ZERO_FWD:%.*]] = cir.const #cir.int<0> : !u32i
+// CIR:         [[NONZERO_FWD:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD]] : !u32i
+// CIR:         cir.if [[NONZERO_FWD]] {
+// CIR:           [[COUNT_FWD:%.*]] = cir.ctz {{%.*}} poison_zero : !u32i
+// CIR:           cir.store align(4) [[COUNT_FWD]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:         }
+// CIR:         cir.cast bool_to_int [[NONZERO_FWD]] : !cir.bool -> !u8i
+
+// LLVM-LABEL: define{{.*}} @test_BitScanForward(
+// LLVM-DAG:     icmp {{(eq|ne)}} i32 %[[MASK_FWD:.*]], 0
+// LLVM-DAG:     %[[COUNT_FWD:.*]] = call i32 @llvm.cttz.i32(i32 
%[[MASK_FWD]], i1 true)
+// LLVM-DAG:     store i32 %[[COUNT_FWD]], ptr %{{.*}}, align 4
+// LLVM-DAG:     ret i8
+
+unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) {
+  return _BitScanReverse(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse
+// CIR:         [[ZERO_REV:%.*]] = cir.const #cir.int<0> : !u32i
+// CIR:         [[NONZERO_REV:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV]] : !u32i
+// CIR:         cir.if [[NONZERO_REV]] {
+// CIR:           [[LAST_REV:%.*]] = cir.const #cir.int<31> : !u32i
+// CIR:           [[COUNT_REV:%.*]] = cir.clz {{%.*}} poison_zero : !u32i
+// CIR:           [[INDEX_REV:%.*]] = cir.sub nsw [[LAST_REV]], [[COUNT_REV]] 
: !u32i
+// CIR:           cir.store align(4) [[INDEX_REV]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:         }
+// CIR:         cir.cast bool_to_int [[NONZERO_REV]] : !cir.bool -> !u8i
+
+// LLVM-LABEL: define{{.*}} @test_BitScanReverse(
+// LLVM-DAG:     icmp {{(eq|ne)}} i32 %[[MASK_REV:.*]], 0
+// LLVM-DAG:     %[[CLZ_REV:.*]] = call i32 @llvm.ctlz.i32(i32 %[[MASK_REV]], 
i1 true)
+// LLVM-DAG:     %[[INDEX_REV:.*]] = sub nsw i32 31, %[[CLZ_REV]]
+// LLVM-DAG:     store i32 %[[INDEX_REV]], ptr %{{.*}}, align 4
+// LLVM-DAG:     ret i8
+
+#if defined(__x86_64__)
+unsigned char test_BitScanForward64(unsigned LONG *Index, unsigned __int64 
Mask) {
+  return _BitScanForward64(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanForward64
+// CIR:         [[ZERO_FWD64:%.*]] = cir.const #cir.int<0> : !u64i
+// CIR:         [[NONZERO_FWD64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD64]] : 
!u64i
+// CIR:         cir.if [[NONZERO_FWD64]] {
+// CIR:           [[COUNT_FWD64:%.*]] = cir.ctz {{%.*}} poison_zero : !u64i
+// CIR:           [[INDEX_FWD64:%.*]] = cir.cast integral [[COUNT_FWD64]] : 
!u64i -> !u32i
+// CIR:           cir.store align(4) [[INDEX_FWD64]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:         }
+// CIR:         cir.cast bool_to_int [[NONZERO_FWD64]] : !cir.bool -> !u8i
+
+// LLVM-LABEL: define{{.*}} @test_BitScanForward64(
+// LLVM-DAG:     icmp {{(eq|ne)}} i64 %[[MASK_FWD64:.*]], 0
+// LLVM-DAG:     %[[COUNT_FWD64:.*]] = call i64 @llvm.cttz.i64(i64 
%[[MASK_FWD64]], i1 true)
+// LLVM-DAG:     %[[TRUNC_FWD64:.*]] = trunc i64 %[[COUNT_FWD64]] to i32
+// LLVM-DAG:     store i32 %[[TRUNC_FWD64]], ptr %{{.*}}, align 4
+// LLVM-DAG:     ret i8
+
+unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 
Mask) {
+  return _BitScanReverse64(Index, Mask);
+}
+
+// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse64
+// CIR:         [[ZERO_REV64:%.*]] = cir.const #cir.int<0> : !u64i
+// CIR:         [[NONZERO_REV64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV64]] : 
!u64i
+// CIR:         cir.if [[NONZERO_REV64]] {
+// CIR:           [[LAST_REV64:%.*]] = cir.const #cir.int<63> : !u32i
+// CIR:           [[COUNT_REV64:%.*]] = cir.clz {{%.*}} poison_zero : !u64i
+// CIR:           [[CAST_REV64:%.*]] = cir.cast integral [[COUNT_REV64]] : 
!u64i -> !u32i
+// CIR:           [[INDEX_REV64:%.*]] = cir.sub nsw [[LAST_REV64]], 
[[CAST_REV64]] : !u32i
+// CIR:           cir.store align(4) [[INDEX_REV64]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:         }
+// CIR:         cir.cast bool_to_int [[NONZERO_REV64]] : !cir.bool -> !u8i
+
+// LLVM-LABEL: define{{.*}} @test_BitScanReverse64(
+// LLVM-DAG:     icmp {{(eq|ne)}} i64 %[[MASK_REV64:.*]], 0
+// LLVM-DAG:     %[[CLZ_REV64:.*]] = call i64 @llvm.ctlz.i64(i64 
%[[MASK_REV64]], i1 true)
+// LLVM-DAG:     %[[TRUNC_REV64:.*]] = trunc i64 %[[CLZ_REV64]] to i32
+// LLVM-DAG:     %[[INDEX_REV64:.*]] = sub nsw i32 63, %[[TRUNC_REV64]]
+// LLVM-DAG:     store i32 %[[INDEX_REV64]], ptr %{{.*}}, align 4
+// LLVM-DAG:     ret i8
+#endif
+
+#ifdef __cplusplus
+}
+#endif

>From e7ee8addd52e9d0eda47c13cbb76c502c44703b6 Mon Sep 17 00:00:00 2001
From: Nayan112 <[email protected]>
Date: Mon, 26 Oct 2026 13:32:31 +0530
Subject: [PATCH 6/6] [CIR][X86] Added test without DAG

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp   |   1 +
 clang/test/CIR/CodeGen/ms-intrinsics-other.c | 182 +++++++++++++------
 2 files changed, 127 insertions(+), 56 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 3882c787a9e79c..2432ec28a5f54d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1258,6 +1258,7 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(MSVCIntrin 
builtinID,
     cgm.errorNYI(E->getExprLoc(), "MSVC intrinsic");
     return {};
   }
+  llvm_unreachable("Incorrect MSVC intrinsic!");
 }
 
 std::optional<mlir::Value>
diff --git a/clang/test/CIR/CodeGen/ms-intrinsics-other.c 
b/clang/test/CIR/CodeGen/ms-intrinsics-other.c
index 26d05eb6baddae..5d34b3693035f1 100644
--- a/clang/test/CIR/CodeGen/ms-intrinsics-other.c
+++ b/clang/test/CIR/CodeGen/ms-intrinsics-other.c
@@ -6,12 +6,12 @@
 // RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \
 // RUN:   -Wno-implicit-function-declaration -fclangir \
 // RUN:   -triple x86_64-unknown-linux -emit-llvm -o %t-cir.ll %s
-// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: FileCheck --check-prefixes=LLVM,LLVMCIR --input-file=%t-cir.ll %s
 //
 // RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \
 // RUN:   -Wno-implicit-function-declaration \
 // RUN:   -triple x86_64-unknown-linux -emit-llvm -o %t-ogcg.ll %s
-// RUN: FileCheck --check-prefix=LLVM --input-file=%t-ogcg.ll %s
+// RUN: FileCheck --check-prefixes=LLVM,OGCG --input-file=%t-ogcg.ll %s
 
 #ifdef __LP64__
 #define LONG int
@@ -28,41 +28,77 @@ unsigned char test_BitScanForward(unsigned LONG *Index, 
unsigned LONG Mask) {
 }
 
 // CIR-LABEL: cir.func{{.*}}@test_BitScanForward
-// CIR:         [[ZERO_FWD:%.*]] = cir.const #cir.int<0> : !u32i
-// CIR:         [[NONZERO_FWD:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD]] : !u32i
-// CIR:         cir.if [[NONZERO_FWD]] {
-// CIR:           [[COUNT_FWD:%.*]] = cir.ctz {{%.*}} poison_zero : !u32i
-// CIR:           cir.store align(4) [[COUNT_FWD]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
-// CIR:         }
-// CIR:         cir.cast bool_to_int [[NONZERO_FWD]] : !cir.bool -> !u8i
+// CIR:       [[ZERO_FWD:%.*]] = cir.const #cir.int<0> : !u32i
+// CIR:       [[NONZERO_FWD:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD]] : !u32i
+// CIR:       cir.if [[NONZERO_FWD]] {
+// CIR:         [[COUNT_FWD:%.*]] = cir.ctz {{%.*}} poison_zero : !u32i
+// CIR:         cir.store align(4) [[COUNT_FWD]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:       }
+// CIR:       cir.cast bool_to_int [[NONZERO_FWD]] : !cir.bool -> !u8i
+
+// The CIR pipeline branches to the bit-scan block when Mask != 0.
+// OGCG branches to the end block when Mask == 0. The condition and
+// destinations are reversed, but both paths execute the bit scan only
+// for a nonzero Mask and then rejoin the end block.
 
 // LLVM-LABEL: define{{.*}} @test_BitScanForward(
-// LLVM-DAG:     icmp {{(eq|ne)}} i32 %[[MASK_FWD:.*]], 0
-// LLVM-DAG:     %[[COUNT_FWD:.*]] = call i32 @llvm.cttz.i32(i32 
%[[MASK_FWD]], i1 true)
-// LLVM-DAG:     store i32 %[[COUNT_FWD]], ptr %{{.*}}, align 4
-// LLVM-DAG:     ret i8
+// LLVMCIR:       [[COND_FWD:%.*]] = icmp ne i32 [[MASK_FWD:%.*]], 0
+// LLVMCIR:   br i1 [[COND_FWD]], label %[[NOT_ZERO_FWD:.*]], label 
%[[END_FWD:.*]]
+// LLVMCIR:       [[NOT_ZERO_FWD]]:
+// LLVMCIR:   [[COUNT_FWD:%.*]] = call i32 @llvm.cttz.i32(i32 [[MASK_FWD]], i1 
true)
+// LLVMCIR:   store i32 [[COUNT_FWD]], ptr [[INDEX_FWD:%.*]], align 4
+// LLVMCIR:   br label %[[END_FWD]]
+// LLVMCIR:       [[END_FWD]]:
+// LLVMCIR:         zext i1 [[COND_FWD]] to i8
+// LLVMCIR:         ret i8
+//
+// OGCG:         [[COND_FWD:%.*]] = icmp eq i32 [[MASK_FWD:%.*]], 0
+// OGCG:     br i1 [[COND_FWD]], label %[[END_FWD:.*]], label 
%[[NOT_ZERO_FWD:.*]]
+// OGCG:       [[END_FWD]]:
+// OGCG:     phi i8 [ 0, %{{.*}} ], [ 1, %[[NOT_ZERO_FWD]] ]
+// OGCG:     ret i8
+// OGCG:       [[NOT_ZERO_FWD]]:
+// OGCG:     [[COUNT_FWD:%.*]] = call i32 @llvm.cttz.i32(i32 [[MASK_FWD]], i1 
true)
+// OGCG:     store i32 [[COUNT_FWD]], ptr [[INDEX_FWD:%.*]], align 4
+// OGCG:     br label %[[END_FWD]]
 
 unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) {
   return _BitScanReverse(Index, Mask);
 }
 
 // CIR-LABEL: cir.func{{.*}}@test_BitScanReverse
-// CIR:         [[ZERO_REV:%.*]] = cir.const #cir.int<0> : !u32i
-// CIR:         [[NONZERO_REV:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV]] : !u32i
-// CIR:         cir.if [[NONZERO_REV]] {
-// CIR:           [[LAST_REV:%.*]] = cir.const #cir.int<31> : !u32i
-// CIR:           [[COUNT_REV:%.*]] = cir.clz {{%.*}} poison_zero : !u32i
-// CIR:           [[INDEX_REV:%.*]] = cir.sub nsw [[LAST_REV]], [[COUNT_REV]] 
: !u32i
-// CIR:           cir.store align(4) [[INDEX_REV]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
-// CIR:         }
-// CIR:         cir.cast bool_to_int [[NONZERO_REV]] : !cir.bool -> !u8i
+// CIR:       [[ZERO_REV:%.*]] = cir.const #cir.int<0> : !u32i
+// CIR:       [[NONZERO_REV:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV]] : !u32i
+// CIR:       cir.if [[NONZERO_REV]] {
+// CIR:         [[LAST_REV:%.*]] = cir.const #cir.int<31> : !u32i
+// CIR:         [[COUNT_REV:%.*]] = cir.clz {{%.*}} poison_zero : !u32i
+// CIR:         [[INDEX_REV:%.*]] = cir.sub nsw [[LAST_REV]], [[COUNT_REV]] : 
!u32i
+// CIR:         cir.store align(4) [[INDEX_REV]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:       }
+// CIR:       cir.cast bool_to_int [[NONZERO_REV]] : !cir.bool -> !u8i
 
 // LLVM-LABEL: define{{.*}} @test_BitScanReverse(
-// LLVM-DAG:     icmp {{(eq|ne)}} i32 %[[MASK_REV:.*]], 0
-// LLVM-DAG:     %[[CLZ_REV:.*]] = call i32 @llvm.ctlz.i32(i32 %[[MASK_REV]], 
i1 true)
-// LLVM-DAG:     %[[INDEX_REV:.*]] = sub nsw i32 31, %[[CLZ_REV]]
-// LLVM-DAG:     store i32 %[[INDEX_REV]], ptr %{{.*}}, align 4
-// LLVM-DAG:     ret i8
+// LLVMCIR:       [[COND_REV:%.*]] = icmp ne i32 [[MASK_REV:%.*]], 0
+// LLVMCIR:   br i1 [[COND_REV]], label %[[NOT_ZERO_REV:.*]], label 
%[[END_REV:.*]]
+// LLVMCIR:       [[NOT_ZERO_REV]]:
+// LLVMCIR:   [[CLZ_REV:%.*]] = call i32 @llvm.ctlz.i32(i32 [[MASK_REV]], i1 
true)
+// LLVMCIR:   [[INDEX_REV:%.*]] = sub nsw i32 31, [[CLZ_REV]]
+// LLVMCIR:   store i32 [[INDEX_REV]], ptr [[INDEX_PTR_REV:%.*]], align 4
+// LLVMCIR:   br label %[[END_REV]]
+// LLVMCIR:       [[END_REV]]:
+// LLVMCIR:         zext i1 [[COND_REV]] to i8
+// LLVMCIR:         ret i8
+//
+// OGCG:         [[COND_REV:%.*]] = icmp eq i32 [[MASK_REV:%.*]], 0
+// OGCG:     br i1 [[COND_REV]], label %[[END_REV:.*]], label 
%[[NOT_ZERO_REV:.*]]
+// OGCG:       [[END_REV]]:
+// OGCG:     phi i8 [ 0, %{{.*}} ], [ 1, %[[NOT_ZERO_REV]] ]
+// OGCG:     ret i8
+// OGCG:       [[NOT_ZERO_REV]]:
+// OGCG:     [[CLZ_REV:%.*]] = call i32 @llvm.ctlz.i32(i32 [[MASK_REV]], i1 
true)
+// OGCG:     [[INDEX_REV:%.*]] = sub nsw i32 31, [[CLZ_REV]]
+// OGCG:     store i32 [[INDEX_REV]], ptr [[INDEX_PTR_REV:%.*]], align 4
+// OGCG:     br label %[[END_REV]]
 
 #if defined(__x86_64__)
 unsigned char test_BitScanForward64(unsigned LONG *Index, unsigned __int64 
Mask) {
@@ -70,45 +106,79 @@ unsigned char test_BitScanForward64(unsigned LONG *Index, 
unsigned __int64 Mask)
 }
 
 // CIR-LABEL: cir.func{{.*}}@test_BitScanForward64
-// CIR:         [[ZERO_FWD64:%.*]] = cir.const #cir.int<0> : !u64i
-// CIR:         [[NONZERO_FWD64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD64]] : 
!u64i
-// CIR:         cir.if [[NONZERO_FWD64]] {
-// CIR:           [[COUNT_FWD64:%.*]] = cir.ctz {{%.*}} poison_zero : !u64i
-// CIR:           [[INDEX_FWD64:%.*]] = cir.cast integral [[COUNT_FWD64]] : 
!u64i -> !u32i
-// CIR:           cir.store align(4) [[INDEX_FWD64]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
-// CIR:         }
-// CIR:         cir.cast bool_to_int [[NONZERO_FWD64]] : !cir.bool -> !u8i
+// CIR:       [[ZERO_FWD64:%.*]] = cir.const #cir.int<0> : !u64i
+// CIR:       [[NONZERO_FWD64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD64]] : 
!u64i
+// CIR:       cir.if [[NONZERO_FWD64]] {
+// CIR:         [[COUNT_FWD64:%.*]] = cir.ctz {{%.*}} poison_zero : !u64i
+// CIR:         [[INDEX_FWD64:%.*]] = cir.cast integral [[COUNT_FWD64]] : 
!u64i -> !u32i
+// CIR:         cir.store align(4) [[INDEX_FWD64]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:       }
+// CIR:       cir.cast bool_to_int [[NONZERO_FWD64]] : !cir.bool -> !u8i
 
 // LLVM-LABEL: define{{.*}} @test_BitScanForward64(
-// LLVM-DAG:     icmp {{(eq|ne)}} i64 %[[MASK_FWD64:.*]], 0
-// LLVM-DAG:     %[[COUNT_FWD64:.*]] = call i64 @llvm.cttz.i64(i64 
%[[MASK_FWD64]], i1 true)
-// LLVM-DAG:     %[[TRUNC_FWD64:.*]] = trunc i64 %[[COUNT_FWD64]] to i32
-// LLVM-DAG:     store i32 %[[TRUNC_FWD64]], ptr %{{.*}}, align 4
-// LLVM-DAG:     ret i8
+// LLVMCIR:       [[COND_FWD64:%.*]] = icmp ne i64 [[MASK_FWD64:%.*]], 0
+// LLVMCIR:   br i1 [[COND_FWD64]], label %[[NOT_ZERO_FWD64:.*]], label 
%[[END_FWD64:.*]]
+// LLVMCIR:       [[NOT_ZERO_FWD64]]:
+// LLVMCIR:   [[COUNT_FWD64:%.*]] = call i64 @llvm.cttz.i64(i64 
[[MASK_FWD64]], i1 true)
+// LLVMCIR:   [[TRUNC_FWD64:%.*]] = trunc i64 [[COUNT_FWD64]] to i32
+// LLVMCIR:   store i32 [[TRUNC_FWD64]], ptr [[INDEX_FWD64:%.*]], align 4
+// LLVMCIR:   br label %[[END_FWD64]]
+// LLVMCIR:       [[END_FWD64]]:
+// LLVMCIR:         zext i1 [[COND_FWD64]] to i8
+// LLVMCIR:         ret i8
+//
+// OGCG:         [[COND_FWD64:%.*]] = icmp eq i64 [[MASK_FWD64:%.*]], 0
+// OGCG:     br i1 [[COND_FWD64]], label %[[END_FWD64:.*]], label 
%[[NOT_ZERO_FWD64:.*]]
+// OGCG:       [[END_FWD64]]:
+// OGCG:     phi i8 [ 0, %{{.*}} ], [ 1, %[[NOT_ZERO_FWD64]] ]
+// OGCG:     ret i8
+// OGCG:       [[NOT_ZERO_FWD64]]:
+// OGCG:     [[COUNT_FWD64:%.*]] = call i64 @llvm.cttz.i64(i64 [[MASK_FWD64]], 
i1 true)
+// OGCG:     [[TRUNC_FWD64:%.*]] = trunc i64 [[COUNT_FWD64]] to i32
+// OGCG:     store i32 [[TRUNC_FWD64]], ptr [[INDEX_PTR_FWD64:%.*]], align 4
+// OGCG:     br label %[[END_FWD64]]
 
 unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 
Mask) {
   return _BitScanReverse64(Index, Mask);
 }
 
 // CIR-LABEL: cir.func{{.*}}@test_BitScanReverse64
-// CIR:         [[ZERO_REV64:%.*]] = cir.const #cir.int<0> : !u64i
-// CIR:         [[NONZERO_REV64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV64]] : 
!u64i
-// CIR:         cir.if [[NONZERO_REV64]] {
-// CIR:           [[LAST_REV64:%.*]] = cir.const #cir.int<63> : !u32i
-// CIR:           [[COUNT_REV64:%.*]] = cir.clz {{%.*}} poison_zero : !u64i
-// CIR:           [[CAST_REV64:%.*]] = cir.cast integral [[COUNT_REV64]] : 
!u64i -> !u32i
-// CIR:           [[INDEX_REV64:%.*]] = cir.sub nsw [[LAST_REV64]], 
[[CAST_REV64]] : !u32i
-// CIR:           cir.store align(4) [[INDEX_REV64]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
-// CIR:         }
-// CIR:         cir.cast bool_to_int [[NONZERO_REV64]] : !cir.bool -> !u8i
+// CIR:       [[ZERO_REV64:%.*]] = cir.const #cir.int<0> : !u64i
+// CIR:       [[NONZERO_REV64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV64]] : 
!u64i
+// CIR:       cir.if [[NONZERO_REV64]] {
+// CIR:         [[LAST_REV64:%.*]] = cir.const #cir.int<63> : !u32i
+// CIR:         [[COUNT_REV64:%.*]] = cir.clz {{%.*}} poison_zero : !u64i
+// CIR:         [[CAST_REV64:%.*]] = cir.cast integral [[COUNT_REV64]] : !u64i 
-> !u32i
+// CIR:         [[INDEX_REV64:%.*]] = cir.sub nsw [[LAST_REV64]], 
[[CAST_REV64]] : !u32i
+// CIR:         cir.store align(4) [[INDEX_REV64]], {{%.*}} : !u32i, 
!cir.ptr<!u32i>
+// CIR:       }
+// CIR:       cir.cast bool_to_int [[NONZERO_REV64]] : !cir.bool -> !u8i
 
 // LLVM-LABEL: define{{.*}} @test_BitScanReverse64(
-// LLVM-DAG:     icmp {{(eq|ne)}} i64 %[[MASK_REV64:.*]], 0
-// LLVM-DAG:     %[[CLZ_REV64:.*]] = call i64 @llvm.ctlz.i64(i64 
%[[MASK_REV64]], i1 true)
-// LLVM-DAG:     %[[TRUNC_REV64:.*]] = trunc i64 %[[CLZ_REV64]] to i32
-// LLVM-DAG:     %[[INDEX_REV64:.*]] = sub nsw i32 63, %[[TRUNC_REV64]]
-// LLVM-DAG:     store i32 %[[INDEX_REV64]], ptr %{{.*}}, align 4
-// LLVM-DAG:     ret i8
+// LLVMCIR:       [[COND_REV64:%.*]] = icmp ne i64 [[MASK_REV64:%.*]], 0
+// LLVMCIR:   br i1 [[COND_REV64]], label %[[NOT_ZERO_REV64:.*]], label 
%[[END_REV64:.*]]
+// LLVMCIR:       [[NOT_ZERO_REV64]]:
+// LLVMCIR:   [[CLZ_REV64:%.*]] = call i64 @llvm.ctlz.i64(i64 [[MASK_REV64]], 
i1 true)
+// LLVMCIR:   [[TRUNC_REV64:%.*]] = trunc i64 [[CLZ_REV64]] to i32
+// LLVMCIR:   [[INDEX_REV64:%.*]] = sub nsw i32 63, [[TRUNC_REV64]]
+// LLVMCIR:   store i32 [[INDEX_REV64]], ptr [[INDEX_PTR_REV64:%.*]], align 4
+// LLVMCIR:   br label %[[END_REV64]]
+// LLVMCIR:       [[END_REV64]]:
+// LLVMCIR:         zext i1 [[COND_REV64]] to i8
+// LLVMCIR:         ret i8
+//
+// OGCG:         [[COND_REV64:%.*]] = icmp eq i64 [[MASK_REV64:%.*]], 0
+// OGCG:     br i1 [[COND_REV64]], label %[[END_REV64:.*]], label 
%[[NOT_ZERO_REV64:.*]]
+// OGCG:       [[END_REV64]]:
+// OGCG:     phi i8 [ 0, %{{.*}} ], [ 1, %[[NOT_ZERO_REV64]] ]
+// OGCG:     ret i8
+// OGCG:       [[NOT_ZERO_REV64]]:
+// OGCG:     [[CLZ_REV64:%.*]] = call i64 @llvm.ctlz.i64(i64 [[MASK_REV64]], 
i1 true)
+// OGCG:     [[TRUNC_REV64:%.*]] = trunc i64 [[CLZ_REV64]] to i32
+// OGCG:     [[INDEX_REV64:%.*]] = sub nsw i32 63, [[TRUNC_REV64]]
+// OGCG:     store i32 [[INDEX_REV64]], ptr [[INDEX_PTR_REV64:.*]], align 4
+// OGCG:     br label %[[END_REV64]]
+
 #endif
 
 #ifdef __cplusplus

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

Reply via email to