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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to