Skip to content

Commit

Permalink
[CIR][CIRGen] Add support for __fp16 type
Browse files Browse the repository at this point in the history
  • Loading branch information
Lancern committed Oct 9, 2024
1 parent 2a11e98 commit a4c99c3
Show file tree
Hide file tree
Showing 3 changed files with 866 additions and 10 deletions.
64 changes: 56 additions & 8 deletions clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,16 +502,25 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// TODO(cir): CGFPOptionsRAII
assert(!MissingFeatures::CGFPOptionsRAII());

if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType)
llvm_unreachable("__fp16 type NYI");
if (type->isHalfType() &&
!CGF.getContext().getLangOpts().NativeHalfType) {
// Another special case: half FP increment should be done via float
if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
llvm_unreachable("cast via llvm.convert.from.fp16 is NYI");
} else {
value = Builder.createCast(CGF.getLoc(E->getExprLoc()),
mlir::cir::CastKind::floating, input,
CGF.CGM.FloatTy);
}
}

if (mlir::isa<mlir::cir::SingleType, mlir::cir::DoubleType>(
value.getType())) {
// Create the inc/dec operation.
// NOTE(CIR): clang calls CreateAdd but folds this to a unary op
auto kind =
(isInc ? mlir::cir::UnaryOpKind::Inc : mlir::cir::UnaryOpKind::Dec);
value = buildUnaryOp(E, kind, input);
value = buildUnaryOp(E, kind, value);
} else {
// Remaining types are Half, Bfloat16, LongDouble, __ibm128 or
// __float128. Convert from float.
Expand All @@ -537,8 +546,16 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
value = Builder.createBinop(value, mlir::cir::BinOpKind::Add, amt);
}

if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType)
llvm_unreachable("NYI");
if (type->isHalfType() &&
!CGF.getContext().getLangOpts().NativeHalfType) {
if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
llvm_unreachable("cast via llvm.convert.to.fp16 is NYI");
} else {
value = Builder.createCast(CGF.getLoc(E->getExprLoc()),
mlir::cir::CastKind::floating, value,
input.getType());
}
}

} else if (type->isFixedPointType()) {
llvm_unreachable("no fixed point inc/dec yet");
Expand Down Expand Up @@ -1043,7 +1060,23 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// Cast from half through float if half isn't a native type.
if (SrcType->isHalfType() &&
!CGF.getContext().getLangOpts().NativeHalfType) {
llvm_unreachable("not implemented");
// Cast to FP using the intrinsic if the half type itself isn't supported.
if (mlir::isa<mlir::cir::CIRFPTypeInterface>(DstTy)) {
if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
llvm_unreachable("cast via llvm.convert.from.fp16 is NYI");
} else {
// Cast to other types through float, using either the intrinsic or
// FPExt, depending on whether the half type itself is supported (as
// opposed to operations on half, available with NativeHalfType).
if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
llvm_unreachable("cast via llvm.convert.from.fp16 is NYI");
} else {
Src = Builder.createCast(
CGF.getLoc(Loc), mlir::cir::CastKind::floating, Src, CGF.FloatTy);
}
SrcType = CGF.getContext().FloatTy;
SrcTy = CGF.FloatTy;
}
}

// TODO(cir): LLVM codegen ignore conversions like int -> uint,
Expand Down Expand Up @@ -1098,13 +1131,28 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// Cast to half through float if half isn't a native type.
if (DstType->isHalfType() &&
!CGF.getContext().getLangOpts().NativeHalfType) {
llvm_unreachable("NYI");
// Make sure we cast in a single step if from another FP type.
if (mlir::isa<mlir::cir::CIRFPTypeInterface>(SrcTy)) {
// Use the intrinsic if the half type itself isn't supported
// (as opposed to operations on half, available with NativeHalfType).
if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
llvm_unreachable("cast via llvm.convert.to.fp16 is NYI");
// If the half type is supported, just use an fptrunc.
return Builder.createCast(CGF.getLoc(Loc),
mlir::cir::CastKind::floating, Src, DstTy);
}
DstTy = CGF.FloatTy;
}

Res = buildScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);

if (DstTy != ResTy) {
llvm_unreachable("NYI");
if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
llvm_unreachable("cast via llvm.convert.to.fp16 is NYI");
} else {
Res = Builder.createCast(CGF.getLoc(Loc), mlir::cir::CastKind::floating,
Res, ResTy);
}
}

if (Opts.EmitImplicitIntegerTruncationChecks)
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,11 @@ mlir::Type CIRGenTypes::ConvertType(QualType T) {
ResultType = CGM.FP16Ty;
break;
case BuiltinType::Half:
// Should be the same as above?
assert(0 && "not implemented");
if (Context.getLangOpts().NativeHalfType ||
!Context.getTargetInfo().useFP16ConversionIntrinsics())
ResultType = CGM.FP16Ty;
else
llvm_unreachable("NYI");
break;
case BuiltinType::BFloat16:
ResultType = CGM.BFloat16Ty;
Expand Down
Loading

0 comments on commit a4c99c3

Please sign in to comment.