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
43 changes: 42 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,48 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
mlir::Value VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
llvm_unreachable("NYI");
}
mlir::Value VisitAsTypeExpr(AsTypeExpr *E) { llvm_unreachable("NYI"); }

mlir::Value VisitAsTypeExpr(AsTypeExpr *E) {
mlir::Value src = CGF.emitScalarExpr(E->getSrcExpr());
QualType qualSrcTy = E->getSrcExpr()->getType();
QualType qualDstTy = E->getType();

mlir::Type srcTy = CGF.convertType(qualSrcTy);
mlir::Type dstTy = CGF.convertType(qualDstTy);
auto loc = CGF.getLoc(E->getExprLoc());

unsigned numSrcElems = 0, numDstElems = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need an assert on missing features for a "nonfixedvector", see scalableVectors as an example.

if (auto v = dyn_cast<cir::VectorType>(srcTy))
numSrcElems = v.getSize();
if (auto v = dyn_cast<cir::VectorType>(dstTy))
numDstElems = v.getSize();

// Use bit vector expansion for ext_vector_type boolean vectors.
if (qualDstTy->isExtVectorBoolType()) {
llvm_unreachable("NYI");
}

// Going from vec3 to non-vec3 is a special case and requires a shuffle
// vector to get a vec4, then a bitcast if the target type is different.
if (numSrcElems == 3 && numDstElems != 3) {
llvm_unreachable("NYI");
}

// Going from non-vec3 to vec3 is a special case and requires a bitcast
// to vec4 if the original type is not vec4, then a shuffle vector to
// get a vec3.
if (numSrcElems != 3 && numDstElems == 3) {
llvm_unreachable("NYI");
}

// If types are identical, return the source
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For these last two cases, I'd suggest implementing the createCastsForTypeOfSimeSize function as it is similarly done in OG (see:

static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder,
) . It could look something like:

static mlir::Value createCastsForTypeOfSameSize(CIRGenBuilderTy &builder,
                                           const cir::CIRDataLayout &dl,
                                           mlir::Value src, mlir::Type dstTy,
                                           ) {

  auto srcTy = Src.getType();

  // Case 1.
  if (mlir::isa<cir::PointerType>(srcTy) && mlir::isa<cir::PointerType>(dstTy))
    return Builder.createBitcast(src, dstTy);
// Other cases

Feel free to assert if anything is not implemented yet or if it's out of the scope of this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, right on point!

if (srcTy == dstTy)
return src;

// Otherwise, fallback to CIR bitcast
return cir::CastOp::create(Builder, loc, dstTy, cir::CastKind::bitcast, src);
}

mlir::Value VisitAtomicExpr(AtomicExpr *E) {
return CGF.emitAtomicExpr(E).getScalarVal();
}
Expand Down
43 changes: 43 additions & 0 deletions clang/test/CIR/CodeGen/OpenCL/as_type.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// RUN: %clang_cc1 %s -cl-std=CL2.0 -fclangir -emit-cir -triple spirv64-unknown-unknown -o %t.ll
// RUN: FileCheck %s --input-file=%t.ll --check-prefix=CIR

// RUN: %clang_cc1 %s -cl-std=CL2.0 -fclangir -emit-llvm -triple spirv64-unknown-unknown -o %t.ll
// RUN: FileCheck %s --input-file=%t.ll --check-prefix=LLVM

// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -triple spirv64-unknown-unknown -o %t.ll
// RUN: FileCheck %s --input-file=%t.ll --check-prefix=OG-LLVM

typedef __attribute__(( ext_vector_type(3) )) char char3;
typedef __attribute__(( ext_vector_type(4) )) char char4;
typedef __attribute__(( ext_vector_type(16) )) char char16;
typedef __attribute__(( ext_vector_type(3) )) int int3;

//CIR: cir.func @f4(%{{.*}}: !s32i loc({{.*}})) -> !cir.vector<!s8i x 4>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit //CIR: to // CIR, similar for others

//CIR: %[[x:.*]] = cir.load align(4) %{{.*}} : !cir.ptr<!s32i, addrspace(offload_private)>
//CIR: cir.cast bitcast %[[x]] : !s32i -> !cir.vector<!s8i x 4>
//LLVM: define spir_func <4 x i8> @f4(i32 %[[x:.*]])
//LLVM: %[[astype:.*]] = bitcast i32 %[[x]] to <4 x i8>
//LLVM-NOT: shufflevector
//LLVM: ret <4 x i8> %[[astype]]
//OG-LLVM: define spir_func noundef <4 x i8> @f4(i32 noundef %[[x:.*]])
//OG-LLVM: %[[astype:.*]] = bitcast i32 %[[x]] to <4 x i8>
//OG-LLVM-NOT: shufflevector
//OG-LLVM: ret <4 x i8> %[[astype]]
char4 f4(int x) {
return __builtin_astype(x, char4);
}

//CIR: cir.func @f6(%{{.*}}: !cir.vector<!s8i x 4> loc({{.*}})) -> !s32i
//CIR: %[[x:.*]] = cir.load align(4) %{{.*}} : !cir.ptr<!cir.vector<!s8i x 4>, addrspace(offload_private)>, !cir.vector<!s8i x 4>
//CIR: cir.cast bitcast %[[x]] : !cir.vector<!s8i x 4> -> !s32i
//LLVM: define{{.*}} spir_func i32 @f6(<4 x i8> %[[x:.*]])
//LLVM: %[[astype:.*]] = bitcast <4 x i8> %[[x]] to i32
//LLVM-NOT: shufflevector
//LLVM: ret i32 %[[astype]]
//OG-LLVM: define{{.*}} spir_func noundef i32 @f6(<4 x i8> noundef %[[x:.*]])
//OG-LLVM: %[[astype:.*]] = bitcast <4 x i8> %[[x]] to i32
//OG-LLVM-NOT: shufflevector
//OG-LLVM: ret i32 %[[astype]]
int f6(char4 x) {
return __builtin_astype(x, int);
}
Loading