[clang] [CIR] Upstream converting vector types (PR #142012)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 29 12:02:47 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Amr Hesham (AmrDeveloper)
<details>
<summary>Changes</summary>
This change adds support for ConvertVectorExpr to convert between vector types with the same size
Issue https://github.com/llvm/llvm-project/issues/136487
---
Full diff: https://github.com/llvm/llvm-project/pull/142012.diff
4 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+14-1)
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+10-2)
- (modified) clang/test/CIR/CodeGen/vector-ext.cpp (+18)
- (modified) clang/test/CIR/CodeGen/vector.cpp (+18)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 058015ca55729..d547bf2e2fc03 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -171,6 +171,14 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
return emitLoadOfLValue(e);
}
+ mlir::Value VisitConvertVectorExpr(ConvertVectorExpr *e) {
+ // __builtin_convertvector is an element-wise cast, and is implemented as a
+ // regular cast. The back end handles casts of vectors correctly.
+ return emitScalarConversion(Visit(e->getSrcExpr()),
+ e->getSrcExpr()->getType(), e->getType(),
+ e->getSourceRange().getBegin());
+ }
+
mlir::Value VisitMemberExpr(MemberExpr *e);
mlir::Value VisitInitListExpr(InitListExpr *e);
@@ -263,7 +271,12 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
"Obsolete code. Don't use mlir::IntegerType with CIR.");
mlir::Type fullDstTy = dstTy;
- assert(!cir::MissingFeatures::vectorType());
+ if (mlir::isa<cir::VectorType>(srcTy) &&
+ mlir::isa<cir::VectorType>(dstTy)) {
+ // Use the element types of the vectors to figure out the CastKind.
+ srcTy = mlir::dyn_cast<cir::VectorType>(srcTy).getElementType();
+ dstTy = mlir::dyn_cast<cir::VectorType>(dstTy).getElementType();
+ }
std::optional<cir::CastKind> castKind;
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 9e2b2908b22d8..bfdc585d2a195 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -286,8 +286,16 @@ LogicalResult cir::ContinueOp::verify() {
//===----------------------------------------------------------------------===//
LogicalResult cir::CastOp::verify() {
- const mlir::Type resType = getResult().getType();
- const mlir::Type srcType = getSrc().getType();
+ mlir::Type resType = getResult().getType();
+ mlir::Type srcType = getSrc().getType();
+
+ if (mlir::isa<cir::VectorType>(srcType) &&
+ mlir::isa<cir::VectorType>(resType)) {
+ // Use the element type of the vector to verify the cast kind. (Except for
+ // bitcast, see below.)
+ srcType = mlir::dyn_cast<cir::VectorType>(srcType).getElementType();
+ resType = mlir::dyn_cast<cir::VectorType>(resType).getElementType();
+ }
switch (getKind()) {
case cir::CastKind::int_to_bool: {
diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp
index aab723f041edf..15e5f75fca6bd 100644
--- a/clang/test/CIR/CodeGen/vector-ext.cpp
+++ b/clang/test/CIR/CodeGen/vector-ext.cpp
@@ -5,6 +5,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+typedef unsigned short vus2 __attribute__((ext_vector_type(2)));
typedef int vi4 __attribute__((ext_vector_type(4)));
typedef unsigned int uvi4 __attribute__((ext_vector_type(4)));
typedef int vi3 __attribute__((ext_vector_type(3)));
@@ -988,3 +989,20 @@ void foo14() {
// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16
// OGCG: %[[GE:.*]] = fcmp oge <4 x float> %[[TMP_A]], %[[TMP_B]]
// OGCG: %[[RES:.*]] = sext <4 x i1> %[[GE]] to <4 x i32>
+
+void foo17() {
+ vd2 a;
+ vus2 W = __builtin_convertvector(a, vus2);
+}
+
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<2 x !cir.double>, !cir.ptr<!cir.vector<2 x !cir.double>>, ["a"]
+// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<2 x !cir.double>>, !cir.vector<2 x !cir.double>
+// CIR: %[[RES:.*]] = cir.cast(float_to_int, %[[TMP]] : !cir.vector<2 x !cir.double>), !cir.vector<2 x !u16i>
+
+// LLVM: %[[VEC_A:.*]] = alloca <2 x double>, i64 1, align 16
+// LLVM: %[[TMP:.*]] = load <2 x double>, ptr %[[VEC_A]], align 16
+// LLVM: %[[RES:.*]]= fptoui <2 x double> %[[TMP]] to <2 x i16>
+
+// OGCG: %[[VEC_A:.*]] = alloca <2 x double>, align 16
+// OGCG: %[[TMP:.*]] = load <2 x double>, ptr %[[VEC_A]], align 16
+// OGCG: %[[RES:.*]]= fptoui <2 x double> %[[TMP]] to <2 x i16>
diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp
index f5a4fcacac4d4..099aa39aa7fab 100644
--- a/clang/test/CIR/CodeGen/vector.cpp
+++ b/clang/test/CIR/CodeGen/vector.cpp
@@ -5,6 +5,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+typedef unsigned short vus2 __attribute__((vector_size(4)));
typedef int vi4 __attribute__((vector_size(16)));
typedef unsigned int uvi4 __attribute__((vector_size(16)));
typedef float vf4 __attribute__((vector_size(16)));
@@ -967,3 +968,20 @@ void foo14() {
// OGCG: %[[GE:.*]] = fcmp oge <4 x float> %[[TMP_A]], %[[TMP_B]]
// OGCG: %[[RES:.*]] = sext <4 x i1> %[[GE]] to <4 x i32>
// OGCG: store <4 x i32> %[[RES]], ptr {{.*}}, align 16
+
+void foo17() {
+ vd2 a;
+ vus2 W = __builtin_convertvector(a, vus2);
+}
+
+// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<2 x !cir.double>, !cir.ptr<!cir.vector<2 x !cir.double>>, ["a"]
+// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<2 x !cir.double>>, !cir.vector<2 x !cir.double>
+// CIR: %[[RES:.*]] = cir.cast(float_to_int, %[[TMP]] : !cir.vector<2 x !cir.double>), !cir.vector<2 x !u16i>
+
+// LLVM: %[[VEC_A:.*]] = alloca <2 x double>, i64 1, align 16
+// LLVM: %[[TMP:.*]] = load <2 x double>, ptr %[[VEC_A]], align 16
+// LLVM: %[[RES:.*]]= fptoui <2 x double> %[[TMP]] to <2 x i16>
+
+// OGCG: %[[VEC_A:.*]] = alloca <2 x double>, align 16
+// OGCG: %[[TMP:.*]] = load <2 x double>, ptr %[[VEC_A]], align 16
+// OGCG: %[[RES:.*]]= fptoui <2 x double> %[[TMP]] to <2 x i16>
``````````
</details>
https://github.com/llvm/llvm-project/pull/142012
More information about the cfe-commits
mailing list