[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-19 Thread Zhihui Yang via cfe-commits

https://github.com/YGGkk edited https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-19 Thread Zhihui Yang via cfe-commits


@@ -152,6 +153,41 @@ 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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+indices.reserve(numElems);
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(0, numElems))
+  indices.push_back(cir::IntAttr::get(i32Ty, i));
+
+maskVec = builder.createVecShuffle(loc, maskVec, maskVec, indices);
+  }
+  return maskVec;
+}
+
+static mlir::Value emitX86Select(CIRGenBuilderTy &builder, mlir::Location loc,
+ mlir::Value mask, mlir::Value op0,
+ mlir::Value op1) {
+  auto constOp = mlir::dyn_cast_or_null(mask.getDefiningOp());

YGGkk wrote:

Hi, I have a question for this cast code. The mask in this function is a 
castOp, so when the mask cat to ConstOp, the constOp is always the nullptr

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Jasmine Tang via cfe-commits

https://github.com/badumbatish closed 
https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Jasmine Tang via cfe-commits

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 
Date: Tue, 2 Dec 2025 22:17:28 -0800
Subject: [PATCH 1/6] 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:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr()) {
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }
+
+  // Check for constant vectors with splat values
+  if (cir::VectorType v = dyn_cast(constOp.getType())) {
+if (auto vecAttr = 

[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Henrich Lauko via cfe-commits

https://github.com/xlauko commented:

can you also add invalid select op test please

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Henrich Lauko via cfe-commits


@@ -2330,6 +2330,28 @@ OpFoldResult cir::SelectOp::fold(FoldAdaptor adaptor) {
 
   return {};
 }
+LogicalResult cir::SelectOp::verify() {

xlauko wrote:

```suggestion
}

LogicalResult cir::SelectOp::verify() {
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Henrich Lauko via cfe-commits


@@ -425,6 +425,27 @@ def CIR_ConstantOp : CIR_Op<"const", [
 return boolAttr.getValue();
   llvm_unreachable("Expected a BoolAttr in ConstantOp");
 }
+bool isAllOnesValue() {

xlauko wrote:

```suggestion
}

bool isAllOnesValue() {
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Henrich Lauko via cfe-commits


@@ -425,6 +425,27 @@ def CIR_ConstantOp : CIR_Op<"const", [
 return boolAttr.getValue();
   llvm_unreachable("Expected a BoolAttr in ConstantOp");
 }
+bool isAllOnesValue() {

xlauko wrote:

```suggestion
}

bool isAllOnesValue() {
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Henrich Lauko via cfe-commits


@@ -2330,6 +2330,28 @@ OpFoldResult cir::SelectOp::fold(FoldAdaptor adaptor) {
 
   return {};
 }
+LogicalResult cir::SelectOp::verify() {
+  // INFO: No need to check if trueTy == falseTy here, it's verified by
+  // the AllTypesMatch trait already.
+  // We can go straight into getting the vector type.
+
+  auto condVecTy =
+  mlir::dyn_cast(this->getCondition().getType());
+  auto trueVecTy =
+  mlir::dyn_cast(this->getTrueValue().getType());
+  auto falseVecTy =
+  mlir::dyn_cast(this->getFalseValue().getType());
+
+  if (condVecTy && (!trueVecTy || !falseVecTy)) {
+// INFO: No need to check for size of vector here, it's verified by
+// the AllTypesMatch trait already
+return emitOpError()
+   << "second and third operand must both be of the same "
+  "vector type when"
+  " the conditional operand is of vector boolean type";
+  }
+  return mlir::success();
+}

xlauko wrote:

```suggestion
}

LogicalResult cir::SelectOp::verify() {
  // AllTypesMatch already guarantees trueVal and falseVal have matching types.
  auto condTy = dyn_cast(getCondition().getType());

  // If condition is not a vector, no further checks are needed.
  if (!condTy)
return success();

  // When condition is a vector, both other operands must also be vectors.
  if (!isa(getTrueValue().getType()) ||
  !isa(getFalseValue().getType())) {
return emitOpError()
   << "expected both true and false operands to be vector types "
  "when the condition is a vector boolean type";
  }

  return success();
}
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Henrich Lauko via cfe-commits

https://github.com/xlauko approved this pull request.

Few last nits otherwise lgtm.

Also plese next time you can split unrelated changes like in this case changes 
to SelectOp and the builtin implementation.

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Henrich Lauko via cfe-commits

https://github.com/xlauko edited 
https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-10 Thread Jasmine Tang via cfe-commits

badumbatish wrote:

if it's alright with you @xlauko, i'll give this a merge?

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-09 Thread Jasmine Tang via cfe-commits

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 
Date: Tue, 2 Dec 2025 22:17:28 -0800
Subject: [PATCH 1/5] 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:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr()) {
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }
+
+  // Check for constant vectors with splat values
+  if (cir::VectorType v = dyn_cast(constOp.getType())) {
+if (auto vecAttr = 

[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-09 Thread Jasmine Tang via cfe-commits

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 
Date: Tue, 2 Dec 2025 22:17:28 -0800
Subject: [PATCH 1/4] 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:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr()) {
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }
+
+  // Check for constant vectors with splat values
+  if (cir::VectorType v = dyn_cast(constOp.getType())) {
+if (auto vecAttr = 

[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-09 Thread Jasmine Tang via cfe-commits

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 
Date: Tue, 2 Dec 2025 22:17:28 -0800
Subject: [PATCH 1/4] 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:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr()) {
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }
+
+  // Check for constant vectors with splat values
+  if (cir::VectorType v = dyn_cast(constOp.getType())) {
+if (auto vecAttr = 

[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-09 Thread Jasmine Tang via cfe-commits


@@ -1870,8 +1896,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.

badumbatish wrote:

yep

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-09 Thread Jasmine Tang via cfe-commits


@@ -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) {

badumbatish wrote:

i can redo this

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -887,7 +921,30 @@ 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(convertType(expr->getType()));
+unsigned numElts = dstTy.getSize();
+unsigned srcNumElts = cast(ops[0].getType()).getSize();
+unsigned subVectors = srcNumElts / numElts;
+assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 
subvectors");
+unsigned index =
+ops[1].getDefiningOp().getIntValue().getZExtValue();
+
+index &= subVectors - 1; // Remove any extra bits.
+index *= numElts;
+
+int64_t indices[16];
+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));

andykaylor wrote:

```suggestion
builder.createVecShuffle(loc, ops[0], poison, ArrayRef(indices, 
numElts));
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -152,6 +152,40 @@ 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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;

andykaylor wrote:

```suggestion
SmallVector indices;
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -887,7 +921,30 @@ 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(convertType(expr->getType()));
+unsigned numElts = dstTy.getSize();
+unsigned srcNumElts = cast(ops[0].getType()).getSize();
+unsigned subVectors = srcNumElts / numElts;
+assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 
subvectors");
+unsigned index =
+ops[1].getDefiningOp().getIntValue().getZExtValue();
+
+index &= subVectors - 1; // Remove any extra bits.
+index *= numElts;
+
+int64_t indices[16];
+std::iota(indices, indices + numElts, index);
+
+mlir::Value zero = builder.getNullValue(ops[0].getType(), loc);

andykaylor wrote:

```suggestion
mlir::Value
poison = builder.getConstant(loc, cir::PoisonAttr::get(ops[0].getType()));
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -250,8 +250,8 @@ def CIR_PtrToArray : CIR_PtrToType;
 
 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"
 > {

andykaylor wrote:

```suggestion
def CIR_VectorElementType
def CIR_VectorElementType
   : AnyTypeOf<[CIR_AnyBoolType, CIR_AnyIntOrFloatType, CIR_AnyPtrType],
"any boolean, integer, floating point or pointer type"> {
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -1870,8 +1896,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

andykaylor wrote:

Please reformat this to fit in 80 columns.

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -1885,8 +1911,12 @@ def CIR_SelectOp : CIR_Op<"select", [
 ```
   }];
 
-  let arguments = (ins CIR_BoolType:$condition, CIR_AnyType:$true_value,
-   CIR_AnyType:$false_value);
+  let arguments = (ins 
+CIR_ScalarOrVectorOf:$condition,
+CIR_AnyType:$true_value,
+CIR_AnyType:$false_value
+  );
+

andykaylor wrote:

This probably needs a verifier for the case where the arguments are vectors.

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr())
+return intAttr.getValue().isAllOnes();
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr())
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+

andykaylor wrote:

Can you remove the extra blank line here?

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -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) {

andykaylor wrote:

This feels weird as a static function. @xlauko is that what you had in mind? I 
would have expected the dynamic cast to ConstantOp to happen at the callsite 
with this as a non-static function.

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-05 Thread Andy Kaylor via cfe-commits


@@ -1870,8 +1896,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.

andykaylor wrote:

Can you describe the behavior in the case where the first operand is a vector 
of bool? In that case the second and third arguments must be vectors with the 
same number of elements as the first argument, right?

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-03 Thread Jasmine Tang via cfe-commits

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 
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:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr()) {
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }
+
+  // Check for constant vectors with splat values
+  if (cir::VectorType v = dyn_cast(constOp.getType())) {
+if (auto vecAttr = 

[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -85,6 +85,71 @@ static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return maskVec;
 }
 
+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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr()) {
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }
+
+  // Check for constant vectors with splat values
+  if (cir::VectorType v = dyn_cast(constOp.getType())) {
+if (auto vecAttr = constOp.getValueAttr()) {
+  if (vecAttr.isSplat()) {
+auto splatAttr = vecAttr.getSplatValue();
+if (auto splatInt = mlir::dyn_cast(splatAttr)) {
+  return splatInt.getValue().isAllOnes();
+}
+  }
+}
+  }
+
+  return false;
+}

xlauko wrote:

add this as method of `ConstatOp`

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -85,6 +85,71 @@ static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return maskVec;
 }
 
+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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }

xlauko wrote:

```suggestion
  if (auto intAttr = constOp.getValueAttr())
return intAttr.getValue().isAllOnes();
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -701,7 +766,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(convertType(expr->getType()));
+unsigned numElts = dstTy.getSize();
+unsigned srcNumElts = cast(ops[0].getType()).getSize();
+unsigned subVectors = srcNumElts / numElts;
+unsigned index =
+ops[1].getDefiningOp().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;

xlauko wrote:

std::iota(indices, indices + numElts, index);
```suggestion
int64_t indices[16];
std::iota(indices, indices + numElts, index);
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -701,7 +766,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(convertType(expr->getType()));
+unsigned numElts = dstTy.getSize();
+unsigned srcNumElts = cast(ops[0].getType()).getSize();
+unsigned subVectors = srcNumElts / numElts;
+unsigned index =
+ops[1].getDefiningOp().getIntValue().getZExtValue();
+

xlauko wrote:

missing:
```
 assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 subvectors");
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -85,6 +85,71 @@ static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return maskVec;
 }
 
+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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return intAttr.getValue().isAllOnes();
+  }
+
+  // Check for FP which are bitcasted from -1 integers
+  if (auto fpAttr = constOp.getValueAttr()) {
+return fpAttr.getValue().bitcastToAPInt().isAllOnes();
+  }

xlauko wrote:

```suggestion
  if (auto fpAttr = constOp.getValueAttr())
return fpAttr.getValue().bitcastToAPInt().isAllOnes();
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -85,6 +85,71 @@ static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return maskVec;
 }
 
+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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;

xlauko wrote:

```suggestion
SmallVector indices;
indices.reserve(numElems);
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -701,7 +766,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(convertType(expr->getType()));
+unsigned numElts = dstTy.getSize();
+unsigned srcNumElts = cast(ops[0].getType()).getSize();
+unsigned subVectors = srcNumElts / numElts;
+unsigned index =
+ops[1].getDefiningOp().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]);
+}

xlauko wrote:

```suggestion
if (ops.size() == 4)
  res = emitX86Select(builder, loc, ops[3], res, ops[2]);
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -266,6 +266,16 @@ class CIR_VectorTypeOf types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "CIR vector of " # T.summary>;
+
+// Type constraint accepting a either a type T or a vector of type T
+// Mimicking LLVMIR's LLVM_ScalarOrVectorOf

xlauko wrote:

```suggestion
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -266,6 +266,16 @@ class CIR_VectorTypeOf types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "CIR vector of " # T.summary>;

xlauko wrote:

```suggestion
// Element type constraint bases
class CIR_ElementTypePred : SubstLeaves<"$_self",
"::mlir::cast<::cir::VectorType>($_self).getElementType()", pred>;

class CIR_VectorTypeOf types, string summary = "">
: CIR_ConfinedType)>],
!if(!empty(summary),
"vector of " # CIR_TypeSummaries.value,
summary)>;
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -1856,7 +1856,7 @@ def CIR_SelectOp : CIR_Op<"select", [
 ```
   }];
 
-  let arguments = (ins CIR_BoolType:$condition, CIR_AnyType:$true_value,
+  let arguments = (ins CIR_ScalarOrVectorOf:$condition, 
CIR_AnyType:$true_value,
CIR_AnyType:$false_value);

xlauko wrote:

```suggestion
  let arguments = (ins 
CIR_ScalarOrVectorOf:$condition, 
CIR_AnyType:$true_value,
CIR_AnyType:$false_value
  );
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Henrich Lauko via cfe-commits


@@ -266,6 +266,16 @@ class CIR_VectorTypeOf types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;

xlauko wrote:

```suggestion
class CIR_ScalarOrVectorOf : AnyTypeOf<[T, CIR_VectorOf]>;
```

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Jasmine Tang (badumbatish)


Changes

Implement builtin extractf, tests are from 
clang/test/CodeGen/X86/avx512f-builtins.c.

I'm not sure why the OG tests are very succinct but i'm porting the same 
testing format over from OG.

I added a new type constraint "element or vector of element" since LLVMIR also 
has said constraint. The new getBoolMaskValue is because the existing SelectOp 
already accepts only a boolean condition; it'd make more sense for it to accept 
a vector of boolean instead of a vector of i32.

---
Full diff: https://github.com/llvm/llvm-project/pull/170427.diff


4 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+3-3) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td (+12-2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp (+90-1) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c (+178) 


``diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4b64fc56c57ad..40203e21c8f18 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1841,8 +1841,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.
 
@@ -1856,7 +1856,7 @@ def CIR_SelectOp : CIR_Op<"select", [
 ```
   }];
 
-  let arguments = (ins CIR_BoolType:$condition, CIR_AnyType:$true_value,
+  let arguments = (ins CIR_ScalarOrVectorOf:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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 224a182ed17d1..97e25136ba3eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -85,6 +85,71 @@ static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return maskVec;
 }
 
+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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return 

[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clangir

Author: Jasmine Tang (badumbatish)


Changes

Implement builtin extractf, tests are from 
clang/test/CodeGen/X86/avx512f-builtins.c.

I'm not sure why the OG tests are very succinct but i'm porting the same 
testing format over from OG.

I added a new type constraint "element or vector of element" since LLVMIR also 
has said constraint. The new getBoolMaskValue is because the existing SelectOp 
already accepts only a boolean condition; it'd make more sense for it to accept 
a vector of boolean instead of a vector of i32.

---
Full diff: https://github.com/llvm/llvm-project/pull/170427.diff


4 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+3-3) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td (+12-2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp (+90-1) 
- (modified) clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c (+178) 


``diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4b64fc56c57ad..40203e21c8f18 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1841,8 +1841,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.
 
@@ -1856,7 +1856,7 @@ def CIR_SelectOp : CIR_Op<"select", [
 ```
   }];
 
-  let arguments = (ins CIR_BoolType:$condition, CIR_AnyType:$true_value,
+  let arguments = (ins CIR_ScalarOrVectorOf:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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 224a182ed17d1..97e25136ba3eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -85,6 +85,71 @@ static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return maskVec;
 }
 
+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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if (!constOp)
+return false;
+
+  // Check for -1 integers
+  if (auto intAttr = constOp.getValueAttr()) {
+return 

[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Jasmine Tang via cfe-commits

badumbatish wrote:

merge conflict, will fix soon

https://github.com/llvm/llvm-project/pull/170427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement builtin extractf (PR #170427)

2025-12-02 Thread Jasmine Tang via cfe-commits

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

Implement builtin extractf, tests are from 
clang/test/CodeGen/X86/avx512f-builtins.c.

I'm not sure why the OG tests are very succinct but i'm porting the same 
testing format over from OG.

I added a new type constraint "element or vector of element" since LLVMIR also 
has said constraint. The new getBoolMaskValue is because the existing SelectOp 
already accepts only a boolean condition; it'd make more sense for it to accept 
a vector of boolean instead of a vector of i32.

>From 6f8a0e7a7bff68b2488b832dae7a2d3dd12eecd4 Mon Sep 17 00:00:00 2001
From: Jasmine Tang 
Date: Tue, 2 Dec 2025 22:17:28 -0800
Subject: [PATCH] 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 4b64fc56c57ad..40203e21c8f18 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1841,8 +1841,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.
 
@@ -1856,7 +1856,7 @@ def CIR_SelectOp : CIR_Op<"select", [
 ```
   }];
 
-  let arguments = (ins CIR_BoolType:$condition, CIR_AnyType:$true_value,
+  let arguments = (ins CIR_ScalarOrVectorOf:$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;
 
 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 types, string summary = 
"">
 "vector of " # CIR_TypeSummaries.value,
 summary)>;
 
+class CIR_VectorOf : CIR_ConfinedType<
+  CIR_AnyVectorType,
+  [CIR_ElementTypePred],
+  "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 :
+AnyTypeOf<[T, CIR_VectorOf]>;
+
 // 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 224a182ed17d1..97e25136ba3eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -85,6 +85,71 @@ static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return maskVec;
 }
 
+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(mask.getType()).getWidth());
+  mlir::Value maskVec = builder.createBitcast(mask, maskTy);
+
+  if (numElems < 8) {
+SmallVector indices;
+mlir::Type i32Ty = builder.getSInt32Ty();
+for (auto i : llvm::seq(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(value.getDefiningOp());
+  if