-
Notifications
You must be signed in to change notification settings - Fork 182
[CIR] Emit bitcast for equal-width types #1991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -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; | ||||
| 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 | ||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For these last two cases, I'd suggest implementing the clangir/clang/lib/CodeGen/CGExprScalar.cpp Line 5798 in 96a0551
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 casesFeel free to assert if anything is not implemented yet or if it's out of the scope of this PR.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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(); | ||||
| } | ||||
|
|
||||
| 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> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit |
||
| //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); | ||
| } | ||
There was a problem hiding this comment.
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
scalableVectorsas an example.