[clang] [cir] Implement __builtin_astype for vec4 to vec3 (PR #199374)
via cfe-commits
cfe-commits at lists.llvm.org
Sat May 23 13:27:15 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Amr Hesham (AmrDeveloper)
<details>
<summary>Changes</summary>
Implement __builtin_astype for vec4 to vec3
Issue #<!-- -->192311
---
Full diff: https://github.com/llvm/llvm-project/pull/199374.diff
2 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+15-5)
- (modified) clang/test/CIR/CodeGenOpenCL/as_type.cl (+20-12)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 5609bd848f230..911ff14e5ef84 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1430,6 +1430,13 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
return {};
}
+ mlir::Value convertVec3AndVec4(CIRGenBuilderTy &builder, mlir::Location loc,
+ mlir::Value src, unsigned numElementsDst) {
+ static constexpr int64_t mask[] = {0, 1, 2, -1};
+ return builder.createVecShuffle(
+ loc, src, llvm::ArrayRef<int64_t>(mask, numElementsDst));
+ }
+
// Create cast instructions for converting MLIR value \p Src to MLIR type \p
// DstTy. \p Src has the same size as \p DstTy. Both are single value types
// but could be scalar or vectors of different lengths, and either can be
@@ -1516,10 +1523,12 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// to vec4 if the original type is not vec4, then a shuffle vector to
// get a vec3.
if (numElementsSrc != 3 && numElementsDst == 3) {
- cgf.cgm.errorNYI(e->getSourceRange(),
- "ScalarExprEmitter: VisitAsTypeExpr numElemsSrc != 3, "
- "numElemsDst = 3");
- return {};
+ mlir::Location loc = cgf.getLoc(e->getExprLoc());
+ auto dstElemTy = cast<cir::VectorType>(dstTy).getElementType();
+ auto dstVec4Ty = cir::VectorType::get(dstElemTy, 4);
+ src = createCastsForTypeOfSameSize(src, dstVec4Ty);
+ src = convertVec3AndVec4(builder, loc, src, 3);
+ return src;
}
return createCastsForTypeOfSameSize(src, dstTy);
@@ -1987,7 +1996,8 @@ mlir::Value ScalarExprEmitter::emitRem(const BinOpInfo &ops) {
mlir::Value ScalarExprEmitter::emitAdd(const BinOpInfo &ops) {
if (mlir::isa<cir::PointerType>(ops.lhs.getType()) ||
mlir::isa<cir::PointerType>(ops.rhs.getType()))
- return emitPointerArithmetic(cgf, ops, /*isSubtraction=*/false);
+ return emitPointerArithmetic(cgf, ops, /*isSubtraction=*/
+ false);
const mlir::Location loc = cgf.getLoc(ops.loc);
if (ops.compType->isSignedIntegerOrEnumerationType()) {
diff --git a/clang/test/CIR/CodeGenOpenCL/as_type.cl b/clang/test/CIR/CodeGenOpenCL/as_type.cl
index 05afd65665e7c..fc5c3bd5a04b6 100644
--- a/clang/test/CIR/CodeGenOpenCL/as_type.cl
+++ b/clang/test/CIR/CodeGenOpenCL/as_type.cl
@@ -5,8 +5,9 @@
// RUN: FileCheck %s --input-file=%t.ll --check-prefix=LLVM
// RUN: %clang_cc1 %s -emit-llvm -triple spir-unknown-unknown -o %t.ll
-// RUN: FileCheck %s --input-file=%t.ll --check-prefix=OGCG
+// RUN: FileCheck %s --input-file=%t.ll --check-prefix=LLVM
+typedef __attribute__(( ext_vector_type(3) )) char char3;
typedef __attribute__(( ext_vector_type(4) )) char char4;
char4 f4(int x) {
@@ -27,10 +28,6 @@ char4 f4(int x) {
// LLVM: %[[RET:.*]] = bitcast i32 %{{.*}} to <4 x i8>
// LLVM: ret <4 x i8> %[[RET]]
-// OGCG: define {{.*}} <4 x i8> @f4
-// OGCG: %[[RET:.*]] = bitcast i32 %{{.*}} to <4 x i8>
-// OGCG: ret <4 x i8> %[[RET]]
-
int f6(char4 x) {
return __builtin_astype(x, int);
}
@@ -49,10 +46,6 @@ int f6(char4 x) {
// LLVM: %[[RET:.*]] = bitcast <4 x i8> %{{.*}} to i32
// LLVM: ret i32 %[[RET]]
-// OGCG: define {{.*}} i32 @f6
-// OGCG: %[[RET:.*]] = bitcast <4 x i8> %{{.*}} to i32
-// OGCG: ret i32 %[[RET]]
-
int* int_to_ptr(int x) {
return __builtin_astype(x, int*);
}
@@ -71,6 +64,21 @@ int* int_to_ptr(int x) {
// LLVM: %[[INT_TO_PTR:.*]] = inttoptr i32 %{{.*}} to ptr
// LLVM: ret ptr %[[INT_TO_PTR]]
-// OGCG: define {{.*}} ptr @int_to_ptr
-// OGCG: %[[INT_TO_PTR:.*]] = inttoptr i32 %{{.*}} to ptr
-// OGCG: ret ptr %[[INT_TO_PTR]]
+char3 vec4_to_vec_3(char4 x) {
+ return __builtin_astype(x, char3);
+}
+
+// CIR: cir.func {{.*}} @vec4_to_vec_3
+// CIR: %[[X_ADDR:.*]] = cir.alloca !cir.vector<4 x !s8i>, !cir.ptr<!cir.vector<4 x !s8i>>, ["x", init]
+// CIR: %[[RET_ADDR:.*]] = cir.alloca !cir.vector<3 x !s8i>, !cir.ptr<!cir.vector<3 x !s8i>>, ["__retval"]
+// CIR: cir.store %{{.*}}, %[[X_ADDR]] : !cir.vector<4 x !s8i>, !cir.ptr<!cir.vector<4 x !s8i>>
+// CIR: %[[TMP_X:.*]] = cir.load {{.*}} %[[X_ADDR]] : !cir.ptr<!cir.vector<4 x !s8i>>, !cir.vector<4 x !s8i>
+// CIR: %[[POISON:.*]] = cir.const #cir.poison : !cir.vector<4 x !s8i>
+// CIR: %[[RESULT:.*]] = cir.vec.shuffle(%[[TMP_X]], %[[POISON]] : !cir.vector<4 x !s8i>) [#cir.int<0> : !s32i, #cir.int<1> : !s32i, #cir.int<2> : !s32i] : !cir.vector<3 x !s8i>
+// CIR: cir.store %[[RESULT]], %[[RET_ADDR]] : !cir.vector<3 x !s8i>, !cir.ptr<!cir.vector<3 x !s8i>>
+// CIR: %[[TMP_RET:.*]] = cir.load %[[RET_ADDR]] : !cir.ptr<!cir.vector<3 x !s8i>>, !cir.vector<3 x !s8i>
+// CIR: cir.return %[[TMP_RET]] : !cir.vector<3 x !s8i>
+
+// LLVM: define {{.*}} <3 x i8> @vec4_to_vec_3
+// LLVM: %[[RESULT:.*]] = shufflevector <4 x i8> %{{.*}}, <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 2>
+// LLVM: ret <3 x i8> %[[RESULT]]
``````````
</details>
https://github.com/llvm/llvm-project/pull/199374
More information about the cfe-commits
mailing list