[clang] 459de73 - [CIR] Upstream converting vector types (#142012)

via cfe-commits cfe-commits at lists.llvm.org
Fri May 30 14:14:14 PDT 2025


Author: Amr Hesham
Date: 2025-05-30T23:14:11+02:00
New Revision: 459de736a0753e12d8a7a557e5b9d7da93ef7a57

URL: https://github.com/llvm/llvm-project/commit/459de736a0753e12d8a7a557e5b9d7da93ef7a57
DIFF: https://github.com/llvm/llvm-project/commit/459de736a0753e12d8a7a557e5b9d7da93ef7a57.diff

LOG: [CIR] Upstream converting vector types (#142012)

This change adds support for ConvertVectorExpr to convert between vector
types with the same size

Issue https://github.com/llvm/llvm-project/issues/136487

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
    clang/lib/CIR/Dialect/IR/CIRDialect.cpp
    clang/test/CIR/CodeGen/vector-ext.cpp
    clang/test/CIR/CodeGen/vector.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index bdb12bf86d1bf..8448c164a5e58 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -185,6 +185,14 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
     return {};
   }
 
+  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);
@@ -277,7 +285,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 94f61b513741b..76860191de7bb 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 e8fed724923de..8a0479fc1d088 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 int vi6 __attribute__((ext_vector_type(6)));
 typedef unsigned int uvi4 __attribute__((ext_vector_type(4)));
@@ -1073,3 +1074,20 @@ void foo16() {
 // OGCG: %[[SHUF_IDX_3:.*]] = extractelement <6 x i32> %[[MASK]], i64 3
 // OGCG: %[[SHUF_ELE_3:.*]] = extractelement <6 x i32> %[[TMP_A]], i32 %[[SHUF_IDX_3]]
 // OGCG: %[[SHUF_INS_3:.*]] = insertelement <6 x i32> %[[SHUF_INS_2]], i32 %[[SHUF_ELE_3]], i64 3
+
+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 6a0b58d98aa7f..4c50f68a56162 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 int vi6 __attribute__((vector_size(24)));
 typedef unsigned int uvi4 __attribute__((vector_size(16)));
@@ -1052,3 +1053,20 @@ void foo16() {
 // OGCG: %[[SHUF_IDX_3:.*]] = extractelement <6 x i32> %[[MASK]], i64 3
 // OGCG: %[[SHUF_ELE_3:.*]] = extractelement <6 x i32> %[[TMP_A]], i32 %[[SHUF_IDX_3]]
 // OGCG: %[[SHUF_INS_3:.*]] = insertelement <6 x i32> %[[SHUF_INS_2]], i32 %[[SHUF_ELE_3]], i64 3
+
+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>
\ No newline at end of file


        


More information about the cfe-commits mailing list