Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()) {
Expand Down
32 changes: 20 additions & 12 deletions clang/test/CIR/CodeGenOpenCL/as_type.cl
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand All @@ -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*);
}
Expand All @@ -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]]