https://github.com/badumbatish updated 
https://github.com/llvm/llvm-project/pull/170427

>From 4ceae744833df00df8929d8660d438da71982352 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <[email protected]>
Date: Tue, 2 Dec 2025 22:17:28 -0800
Subject: [PATCH 1/2] Implement extractf, tests are from
 clang/test/CodeGen/X86/avx512f-builtins.c

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |   6 +-
 .../CIR/Dialect/IR/CIRTypeConstraints.td      |  14 +-
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    |  91 ++++++++-
 .../CodeGenBuiltins/X86/avx512f-builtins.c    | 178 ++++++++++++++++++
 4 files changed, 283 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index ae199f35cb10e..1540fd022860b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1870,8 +1870,8 @@ def CIR_SelectOp : CIR_Op<"select", [
   let summary = "Yield one of two values based on a boolean value";
   let description = [{
     The `cir.select` operation takes three operands. The first operand
-    `condition` is a boolean value of type `!cir.bool`. The second and the 
third
-    operand can be of any CIR types, but their types must be the same. If the
+    `condition` is either a boolean value of type `!cir.bool` or a boolean 
vector of type `!cir.bool`. 
+    The second and the third operand can be of any CIR types, but their types 
must be the same. If the
     first operand is `true`, the operation yields its second operand. 
Otherwise,
     the operation yields its third operand.
 
@@ -1885,7 +1885,7 @@ def CIR_SelectOp : CIR_Op<"select", [
     ```
   }];
 
-  let arguments = (ins CIR_BoolType:$condition, CIR_AnyType:$true_value,
+  let arguments = (ins CIR_ScalarOrVectorOf<CIR_BoolType>:$condition, 
CIR_AnyType:$true_value,
                        CIR_AnyType:$false_value);
   let results = (outs CIR_AnyType:$result);
 
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
index ddca98eac93ab..dd514d755ce24 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
@@ -250,8 +250,8 @@ def CIR_PtrToArray : CIR_PtrToType<CIR_AnyArrayType>;
 
 def CIR_AnyVectorType : CIR_TypeBase<"::cir::VectorType", "vector type">;
 
-def CIR_VectorElementType : AnyTypeOf<[CIR_AnyIntOrFloatType, CIR_AnyPtrType],
-    "any cir integer, floating point or pointer type"
+def CIR_VectorElementType : AnyTypeOf<[CIR_AnyBoolType, CIR_AnyIntOrFloatType, 
CIR_AnyPtrType],
+    "any cir boolean, integer, floating point or pointer type"
 > {
     let cppFunctionName = "isValidVectorTypeElementType";
 }
@@ -266,6 +266,16 @@ class CIR_VectorTypeOf<list<Type> types, string summary = 
"">
             "vector of " # CIR_TypeSummaries<types>.value,
             summary)>;
 
+class CIR_VectorOf<Type T> : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred<T.predicate>],
+  "CIR vector of " # T.summary>;
+
+// Type constraint accepting a either a type T or a vector of type T
+// Mimicking LLVMIR's LLVM_ScalarOrVectorOf
+class CIR_ScalarOrVectorOf<Type T> :
+    AnyTypeOf<[T, CIR_VectorOf<T>]>;
+
 // Vector of integral type
 def IntegerVector : Type<
     And<[
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 1b2e3f41479db..16d23e1ae0bfc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -152,6 +152,71 @@ computeFullLaneShuffleMask(CIRGenFunction &cgf, const 
mlir::Value vec,
   outIndices.resize(numElts);
 }
 
+static mlir::Value getBoolMaskVecValue(CIRGenBuilderTy &builder,
+                                       mlir::Location loc, mlir::Value mask,
+                                       unsigned numElems) {
+
+  cir::BoolType boolTy = builder.getBoolTy();
+  auto maskTy = cir::VectorType::get(
+      boolTy, cast<cir::IntType>(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+    SmallVector<mlir::Attribute, 4> indices;
+    mlir::Type i32Ty = builder.getSInt32Ty();
+    for (auto i : llvm::seq<unsigned>(0, numElems))
+      indices.push_back(cir::IntAttr::get(i32Ty, i));
+
+    maskVec = builder.createVecShuffle(loc, maskVec, maskVec, indices);
+  }
+  return maskVec;
+}
+
+// Helper function mirroring OG's bool Constant::isAllOnesValue()
+static bool isAllOnesValue(mlir::Value value) {
+  auto constOp = 
mlir::dyn_cast_or_null<cir::ConstantOp>(value.getDefiningOp());
+  if (!constOp)
+    return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr<cir::IntAttr>()) {
+    return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr<cir::FPAttr>()) {
+    return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }
+
+  // Check for constant vectors with splat values
+  if (cir::VectorType v = dyn_cast<cir::VectorType>(constOp.getType())) {
+    if (auto vecAttr = constOp.getValueAttr<mlir::DenseElementsAttr>()) {
+      if (vecAttr.isSplat()) {
+        auto splatAttr = vecAttr.getSplatValue<mlir::Attribute>();
+        if (auto splatInt = mlir::dyn_cast<cir::IntAttr>(splatAttr)) {
+          return splatInt.getValue().isAllOnes();
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
+static mlir::Value emitX86Select(CIRGenBuilderTy &builder, mlir::Location loc,
+                                 mlir::Value mask, mlir::Value op0,
+                                 mlir::Value op1) {
+
+  // If the mask is all ones just return first argument.
+  if (isAllOnesValue(mask))
+    return op0;
+
+  mask = getBoolMaskVecValue(builder, loc, mask,
+                             cast<cir::VectorType>(op0.getType()).getSize());
+
+  return builder.createSelect(loc, mask, op0, op1);
+}
+
 static mlir::Value emitX86MaskAddLogic(CIRGenBuilderTy &builder,
                                        mlir::Location loc,
                                        const std::string &intrinsicName,
@@ -887,7 +952,31 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
   case X86::BI__builtin_ia32_extractf64x2_256_mask:
   case X86::BI__builtin_ia32_extracti64x2_256_mask:
   case X86::BI__builtin_ia32_extractf64x2_512_mask:
-  case X86::BI__builtin_ia32_extracti64x2_512_mask:
+  case X86::BI__builtin_ia32_extracti64x2_512_mask: {
+    mlir::Location loc = getLoc(expr->getExprLoc());
+    cir::VectorType dstTy = 
cast<cir::VectorType>(convertType(expr->getType()));
+    unsigned numElts = dstTy.getSize();
+    unsigned srcNumElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned subVectors = srcNumElts / numElts;
+    unsigned index =
+        ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
+
+    index &= subVectors - 1; // Remove any extra bits.
+    index *= numElts;
+
+    int64_t indices[16];
+    for (unsigned i = 0; i != numElts; ++i)
+      indices[i] = i + index;
+
+    mlir::Value zero = builder.getNullValue(ops[0].getType(), loc);
+    mlir::Value res =
+        builder.createVecShuffle(loc, ops[0], zero, ArrayRef(indices, 
numElts));
+    if (ops.size() == 4) {
+      res = emitX86Select(builder, loc, ops[3], res, ops[2]);
+    }
+
+    return res;
+  }
   case X86::BI__builtin_ia32_vinsertf128_pd256:
   case X86::BI__builtin_ia32_vinsertf128_ps256:
   case X86::BI__builtin_ia32_vinsertf128_si256:
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c 
b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
index cdcdad42b2845..31ba14c88fae9 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
@@ -695,3 +695,181 @@ void test_mm512_mask_i64scatter_epi32(void *__addr, 
__mmask8 __mask, __m512i __i
   // OGCG: @llvm.x86.avx512.mask.scatter.qpi.512
   return _mm512_mask_i64scatter_epi32(__addr, __mask, __index, __v1, 2);
 }
+
+__m256d test_mm512_extractf64x4_pd(__m512d a)
+{
+  // CIR-LABEL: test_mm512_extractf64x4_pd
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<8 x !cir.double>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<8 x !cir.double>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !cir.double>
+
+  // LLVM-LABEL: test_mm512_extractf64x4_pd
+  // LLVM: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, 
<4 x i32> <i32 4, i32 5, i32 6, i32 7>
+
+  // OGCG-LABEL: test_mm512_extractf64x4_pd
+  // OGCG: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> 
<i32 4, i32 5, i32 6, i32 7>
+  return _mm512_extractf64x4_pd(a, 1);
+}
+
+__m256d test_mm512_mask_extractf64x4_pd(__m256d  __W,__mmask8  __U,__m512d 
__A){
+  // CIR-LABEL: test_mm512_mask_extractf64x4_pd
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<8 x !cir.double>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<8 x !cir.double>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !cir.double>
+  // CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x 
!cir.bool>, !cir.vector<4 x !cir.double>, !cir.vector<4 x !cir.double>) -> 
!cir.vector<4 x !cir.double>
+
+  // LLVM-LABEL: test_mm512_mask_extractf64x4_pd
+  // LLVM: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, 
<4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_mask_extractf64x4_pd
+  // OGCG: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> 
<i32 4, i32 5, i32 6, i32 7>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
+  return _mm512_mask_extractf64x4_pd( __W, __U, __A, 1);
+}
+
+__m256d test_mm512_maskz_extractf64x4_pd(__mmask8  __U,__m512d __A){
+  // CIR-LABEL: test_mm512_maskz_extractf64x4_pd
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<8 x !cir.double>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<8 x !cir.double>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !cir.double>
+  // CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x 
!cir.bool>, !cir.vector<4 x !cir.double>, !cir.vector<4 x !cir.double>) -> 
!cir.vector<4 x !cir.double>
+
+  // LLVM-LABEL: test_mm512_maskz_extractf64x4_pd
+  // LLVM: shufflevector <8 x double> %{{.*}}, <8 x double> zeroinitializer, 
<4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_maskz_extractf64x4_pd
+  // OGCG: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> 
<i32 4, i32 5, i32 6, i32 7>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
+  return _mm512_maskz_extractf64x4_pd( __U, __A, 1);
+}
+
+__m128 test_mm512_extractf32x4_ps(__m512 a)
+{
+  // CIR-LABEL: test_mm512_extractf32x4_ps
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<16 x !cir.float>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<16 x !cir.float>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: test_mm512_extractf32x4_ps
+  // LLVM: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, 
<4 x i32> <i32 4, i32 5, i32 6, i32 7>
+
+  // OGCG-LABEL: test_mm512_extractf32x4_ps
+  // OGCG: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> 
<i32 4, i32 5, i32 6, i32 7>
+  return _mm512_extractf32x4_ps(a, 1);
+}
+
+__m128 test_mm512_mask_extractf32x4_ps(__m128 __W, __mmask8  __U,__m512 __A){
+  // CIR-LABEL: test_mm512_mask_extractf32x4_ps
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<16 x !cir.float>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<16 x !cir.float>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: test_mm512_mask_extractf32x4_ps
+  // LLVM: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, 
<4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_mask_extractf32x4_ps
+  // OGCG: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> 
<i32 4, i32 5, i32 6, i32 7>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
+  return _mm512_mask_extractf32x4_ps( __W, __U, __A, 1);
+}
+
+__m128 test_mm512_maskz_extractf32x4_ps( __mmask8  __U,__m512 __A){
+  // CIR-LABEL: test_mm512_maskz_extractf32x4_ps
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<16 x !cir.float>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<16 x !cir.float>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !cir.float>
+
+  // LLVM-LABEL: test_mm512_maskz_extractf32x4_ps
+  // LLVM: shufflevector <16 x float> %{{.*}}, <16 x float> zeroinitializer, 
<4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_maskz_extractf32x4_ps
+  // OGCG: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> 
<i32 4, i32 5, i32 6, i32 7>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
+  return _mm512_maskz_extractf32x4_ps(__U, __A, 1);
+}
+
+__m128i test_mm512_extracti32x4_epi32(__m512i __A) {
+  // CIR-LABEL: test_mm512_extracti32x4_epi32
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<16 x !s32i>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<16 x !s32i>) 
[#cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> 
: !s32i] : !cir.vector<4 x !s32i>
+
+  // LLVM-LABEL: test_mm512_extracti32x4_epi32
+  // LLVM: shufflevector <16 x i32> %{{.*}}, <16 x i32> zeroinitializer, <4 x 
i32> <i32 12, i32 13, i32 14, i32 15>
+
+  // OGCG-LABEL: test_mm512_extracti32x4_epi32
+  // OGCG: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 
12, i32 13, i32 14, i32 15>
+  return _mm512_extracti32x4_epi32(__A, 3);
+}
+
+__m128i test_mm512_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m512i 
__A) {
+  // CIR-LABEL: test_mm512_mask_extracti32x4_epi32
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<16 x !s32i>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<16 x !s32i>) 
[#cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> 
: !s32i] : !cir.vector<4 x !s32i>
+  // CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x 
!cir.bool>, !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x 
!s32i>
+
+  // LLVM-LABEL: test_mm512_mask_extracti32x4_epi32
+  // LLVM: shufflevector <16 x i32> %{{.*}}, <16 x i32> zeroinitializer, <4 x 
i32> <i32 12, i32 13, i32 14, i32 15>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_mask_extracti32x4_epi32
+  // OGCG: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 
12, i32 13, i32 14, i32 15>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm512_mask_extracti32x4_epi32(__W, __U, __A, 3);
+}
+
+__m128i test_mm512_maskz_extracti32x4_epi32(__mmask8 __U, __m512i __A) {
+  // CIR-LABEL: test_mm512_maskz_extracti32x4_epi32
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<16 x !s32i>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<16 x !s32i>) 
[#cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> 
: !s32i] : !cir.vector<4 x !s32i>
+  // CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x 
!cir.bool>, !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x 
!s32i>
+
+  // LLVM-LABEL: test_mm512_maskz_extracti32x4_epi32
+  // LLVM: shufflevector <16 x i32> %{{.*}}, <16 x i32> zeroinitializer, <4 x 
i32> <i32 12, i32 13, i32 14, i32 15>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_maskz_extracti32x4_epi32
+  // OGCG: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 
12, i32 13, i32 14, i32 15>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
+  return _mm512_maskz_extracti32x4_epi32(__U, __A, 3);
+}
+
+__m256i test_mm512_extracti64x4_epi64(__m512i __A) {
+  // CIR-LABEL: test_mm512_extracti64x4_epi64
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<8 x !s64i>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<8 x !s64i>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !s64i>
+
+  // LLVM-LABEL: test_mm512_extracti64x4_epi64
+  // LLVM: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <4 x 
i32> <i32 4, i32 5, i32 6, i32 7>
+
+  // OGCG-LABEL: test_mm512_extracti64x4_epi64
+  // OGCG: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 
4, i32 5, i32 6, i32 7>
+  return _mm512_extracti64x4_epi64(__A, 1);
+}
+
+__m256i test_mm512_mask_extracti64x4_epi64(__m256i __W, __mmask8 __U, __m512i 
__A) {
+  // CIR-LABEL: test_mm512_mask_extracti64x4_epi64
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<8 x !s64i>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<8 x !s64i>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !s64i>
+
+  // LLVM-LABEL: test_mm512_mask_extracti64x4_epi64
+  // LLVM: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <4 x 
i32> <i32 4, i32 5, i32 6, i32 7>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_mask_extracti64x4_epi64
+  // OGCG: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 
4, i32 5, i32 6, i32 7>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm512_mask_extracti64x4_epi64(__W, __U, __A, 1);
+}
+
+__m256i test_mm512_maskz_extracti64x4_epi64(__mmask8 __U, __m512i __A) {
+  // CIR-LABEL: test_mm512_maskz_extracti64x4_epi64
+  // CIR: [[ZERO:%.*]] = cir.const #cir.zero : !cir.vector<8 x !s64i>
+  // CIR: cir.vec.shuffle(%{{.*}}, [[ZERO]] : !cir.vector<8 x !s64i>) 
[#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : 
!s32i] : !cir.vector<4 x !s64i>
+
+  // LLVM-LABEL: test_mm512_maskz_extracti64x4_epi64
+  // LLVM: shufflevector <8 x i64> %{{.*}}, <8 x i64> zeroinitializer, <4 x 
i32> <i32 4, i32 5, i32 6, i32 7>
+  // LLVM: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+
+  // OGCG-LABEL: test_mm512_maskz_extracti64x4_epi64
+  // OGCG: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 
4, i32 5, i32 6, i32 7>
+  // OGCG: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
+  return _mm512_maskz_extracti64x4_epi64(__U, __A, 1);
+}

>From 7de533b101132f647d4239d1e911bd8a4aef650c Mon Sep 17 00:00:00 2001
From: Jasmine Tang <[email protected]>
Date: Wed, 3 Dec 2025 10:56:56 -0800
Subject: [PATCH 2/2] Resolve PR reviews

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 34 ++++++++++++++-
 .../CIR/Dialect/IR/CIRTypeConstraints.td      |  9 +---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    | 42 +++----------------
 3 files changed, 38 insertions(+), 47 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 1540fd022860b..731243cd1ba92 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -425,6 +425,32 @@ def CIR_ConstantOp : CIR_Op<"const", [
         return boolAttr.getValue();
       llvm_unreachable("Expected a BoolAttr in ConstantOp");
     }
+    static bool isAllOnesValue(mlir::Value value) {
+      auto constOp = 
mlir::dyn_cast_or_null<cir::ConstantOp>(value.getDefiningOp());
+      if (!constOp)
+        return false;
+
+      // Check for -1 integers
+      if (auto intAttr = constOp.getValueAttr<cir::IntAttr>())
+        return intAttr.getValue().isAllOnes();
+
+      // Check for FP which are bitcasted from -1 integers
+      if (auto fpAttr = constOp.getValueAttr<cir::FPAttr>())
+        return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+
+
+      // Check for constant vectors with splat values
+      if (cir::VectorType v = 
mlir::dyn_cast<cir::VectorType>(constOp.getType()))
+        if (auto vecAttr = constOp.getValueAttr<mlir::DenseElementsAttr>())
+          if (vecAttr.isSplat()) {
+            auto splatAttr = vecAttr.getSplatValue<mlir::Attribute>();
+            if (auto splatInt = mlir::dyn_cast<cir::IntAttr>(splatAttr)) {
+              return splatInt.getValue().isAllOnes();
+          }
+      }
+
+      return false;
+    }
   }];
 
   let hasFolder = 1;
@@ -1885,8 +1911,12 @@ def CIR_SelectOp : CIR_Op<"select", [
     ```
   }];
 
-  let arguments = (ins CIR_ScalarOrVectorOf<CIR_BoolType>:$condition, 
CIR_AnyType:$true_value,
-                       CIR_AnyType:$false_value);
+  let arguments = (ins 
+    CIR_ScalarOrVectorOf<CIR_BoolType>:$condition,
+    CIR_AnyType:$true_value,
+    CIR_AnyType:$false_value
+  );
+
   let results = (outs CIR_AnyType:$result);
 
   let assemblyFormat = [{
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
index dd514d755ce24..fa315c60587fb 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
@@ -266,15 +266,8 @@ class CIR_VectorTypeOf<list<Type> types, string summary = 
"">
             "vector of " # CIR_TypeSummaries<types>.value,
             summary)>;
 
-class CIR_VectorOf<Type T> : CIR_ConfinedType<
-  CIR_AnyVectorType,
-  [CIR_ElementTypePred<T.predicate>],
-  "CIR vector of " # T.summary>;
-
 // Type constraint accepting a either a type T or a vector of type T
-// Mimicking LLVMIR's LLVM_ScalarOrVectorOf
-class CIR_ScalarOrVectorOf<Type T> :
-    AnyTypeOf<[T, CIR_VectorOf<T>]>;
+class CIR_ScalarOrVectorOf<Type T> : AnyTypeOf<[T, CIR_VectorTypeOf<[T]>]>;
 
 // Vector of integral type
 def IntegerVector : Type<
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 16d23e1ae0bfc..3a4d9caa76e0c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -163,6 +163,7 @@ static mlir::Value getBoolMaskVecValue(CIRGenBuilderTy 
&builder,
 
   if (numElems < 8) {
     SmallVector<mlir::Attribute, 4> indices;
+    indices.reserve(numElems);
     mlir::Type i32Ty = builder.getSInt32Ty();
     for (auto i : llvm::seq<unsigned>(0, numElems))
       indices.push_back(cir::IntAttr::get(i32Ty, i));
@@ -172,43 +173,11 @@ static mlir::Value getBoolMaskVecValue(CIRGenBuilderTy 
&builder,
   return maskVec;
 }
 
-// Helper function mirroring OG's bool Constant::isAllOnesValue()
-static bool isAllOnesValue(mlir::Value value) {
-  auto constOp = 
mlir::dyn_cast_or_null<cir::ConstantOp>(value.getDefiningOp());
-  if (!constOp)
-    return false;
-
-  // Check for -1 integers
-  if (auto intAttr = constOp.getValueAttr<cir::IntAttr>()) {
-    return intAttr.getValue().isAllOnes();
-  }
-
-  // Check for FP which are bitcasted from -1 integers
-  if (auto fpAttr = constOp.getValueAttr<cir::FPAttr>()) {
-    return fpAttr.getValue().bitcastToAPInt().isAllOnes();
-  }
-
-  // Check for constant vectors with splat values
-  if (cir::VectorType v = dyn_cast<cir::VectorType>(constOp.getType())) {
-    if (auto vecAttr = constOp.getValueAttr<mlir::DenseElementsAttr>()) {
-      if (vecAttr.isSplat()) {
-        auto splatAttr = vecAttr.getSplatValue<mlir::Attribute>();
-        if (auto splatInt = mlir::dyn_cast<cir::IntAttr>(splatAttr)) {
-          return splatInt.getValue().isAllOnes();
-        }
-      }
-    }
-  }
-
-  return false;
-}
-
 static mlir::Value emitX86Select(CIRGenBuilderTy &builder, mlir::Location loc,
                                  mlir::Value mask, mlir::Value op0,
                                  mlir::Value op1) {
-
   // If the mask is all ones just return first argument.
-  if (isAllOnesValue(mask))
+  if (cir::ConstantOp::isAllOnesValue(mask))
     return op0;
 
   mask = getBoolMaskVecValue(builder, loc, mask,
@@ -958,6 +927,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     unsigned numElts = dstTy.getSize();
     unsigned srcNumElts = cast<cir::VectorType>(ops[0].getType()).getSize();
     unsigned subVectors = srcNumElts / numElts;
+    assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 
subvectors");
     unsigned index =
         ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
 
@@ -965,15 +935,13 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     index *= numElts;
 
     int64_t indices[16];
-    for (unsigned i = 0; i != numElts; ++i)
-      indices[i] = i + index;
+    std::iota(indices, indices + numElts, index);
 
     mlir::Value zero = builder.getNullValue(ops[0].getType(), loc);
     mlir::Value res =
         builder.createVecShuffle(loc, ops[0], zero, ArrayRef(indices, 
numElts));
-    if (ops.size() == 4) {
+    if (ops.size() == 4)
       res = emitX86Select(builder, loc, ops[3], res, ops[2]);
-    }
 
     return res;
   }

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

Reply via email to