[clang] [CIR] Implement builtin extractf (PR #170427)
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)
@@ -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)
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)
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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
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)
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)
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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
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)
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
