@@ -502,16 +502,25 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
502
502
// TODO(cir): CGFPOptionsRAII
503
503
assert (!MissingFeatures::CGFPOptionsRAII ());
504
504
505
- if (type->isHalfType () && !CGF.getContext ().getLangOpts ().NativeHalfType )
506
- llvm_unreachable (" __fp16 type NYI" );
505
+ if (type->isHalfType () &&
506
+ !CGF.getContext ().getLangOpts ().NativeHalfType ) {
507
+ // Another special case: half FP increment should be done via float
508
+ if (CGF.getContext ().getTargetInfo ().useFP16ConversionIntrinsics ()) {
509
+ llvm_unreachable (" cast via llvm.convert.from.fp16 is NYI" );
510
+ } else {
511
+ value = Builder.createCast (CGF.getLoc (E->getExprLoc ()),
512
+ mlir::cir::CastKind::floating, input,
513
+ CGF.CGM .FloatTy );
514
+ }
515
+ }
507
516
508
517
if (mlir::isa<mlir::cir::SingleType, mlir::cir::DoubleType>(
509
518
value.getType ())) {
510
519
// Create the inc/dec operation.
511
520
// NOTE(CIR): clang calls CreateAdd but folds this to a unary op
512
521
auto kind =
513
522
(isInc ? mlir::cir::UnaryOpKind::Inc : mlir::cir::UnaryOpKind::Dec);
514
- value = buildUnaryOp (E, kind, input );
523
+ value = buildUnaryOp (E, kind, value );
515
524
} else {
516
525
// Remaining types are Half, Bfloat16, LongDouble, __ibm128 or
517
526
// __float128. Convert from float.
@@ -537,8 +546,16 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
537
546
value = Builder.createBinop (value, mlir::cir::BinOpKind::Add, amt);
538
547
}
539
548
540
- if (type->isHalfType () && !CGF.getContext ().getLangOpts ().NativeHalfType )
541
- llvm_unreachable (" NYI" );
549
+ if (type->isHalfType () &&
550
+ !CGF.getContext ().getLangOpts ().NativeHalfType ) {
551
+ if (CGF.getContext ().getTargetInfo ().useFP16ConversionIntrinsics ()) {
552
+ llvm_unreachable (" cast via llvm.convert.to.fp16 is NYI" );
553
+ } else {
554
+ value = Builder.createCast (CGF.getLoc (E->getExprLoc ()),
555
+ mlir::cir::CastKind::floating, value,
556
+ input.getType ());
557
+ }
558
+ }
542
559
543
560
} else if (type->isFixedPointType ()) {
544
561
llvm_unreachable (" no fixed point inc/dec yet" );
@@ -1043,7 +1060,23 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
1043
1060
// Cast from half through float if half isn't a native type.
1044
1061
if (SrcType->isHalfType () &&
1045
1062
!CGF.getContext ().getLangOpts ().NativeHalfType ) {
1046
- llvm_unreachable (" not implemented" );
1063
+ // Cast to FP using the intrinsic if the half type itself isn't supported.
1064
+ if (mlir::isa<mlir::cir::CIRFPTypeInterface>(DstTy)) {
1065
+ if (CGF.getContext ().getTargetInfo ().useFP16ConversionIntrinsics ())
1066
+ llvm_unreachable (" cast via llvm.convert.from.fp16 is NYI" );
1067
+ } else {
1068
+ // Cast to other types through float, using either the intrinsic or
1069
+ // FPExt, depending on whether the half type itself is supported (as
1070
+ // opposed to operations on half, available with NativeHalfType).
1071
+ if (CGF.getContext ().getTargetInfo ().useFP16ConversionIntrinsics ()) {
1072
+ llvm_unreachable (" cast via llvm.convert.from.fp16 is NYI" );
1073
+ } else {
1074
+ Src = Builder.createCast (
1075
+ CGF.getLoc (Loc), mlir::cir::CastKind::floating, Src, CGF.FloatTy );
1076
+ }
1077
+ SrcType = CGF.getContext ().FloatTy ;
1078
+ SrcTy = CGF.FloatTy ;
1079
+ }
1047
1080
}
1048
1081
1049
1082
// TODO(cir): LLVM codegen ignore conversions like int -> uint,
@@ -1098,13 +1131,28 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
1098
1131
// Cast to half through float if half isn't a native type.
1099
1132
if (DstType->isHalfType () &&
1100
1133
!CGF.getContext ().getLangOpts ().NativeHalfType ) {
1101
- llvm_unreachable (" NYI" );
1134
+ // Make sure we cast in a single step if from another FP type.
1135
+ if (mlir::isa<mlir::cir::CIRFPTypeInterface>(SrcTy)) {
1136
+ // Use the intrinsic if the half type itself isn't supported
1137
+ // (as opposed to operations on half, available with NativeHalfType).
1138
+ if (CGF.getContext ().getTargetInfo ().useFP16ConversionIntrinsics ())
1139
+ llvm_unreachable (" cast via llvm.convert.to.fp16 is NYI" );
1140
+ // If the half type is supported, just use an fptrunc.
1141
+ return Builder.createCast (CGF.getLoc (Loc),
1142
+ mlir::cir::CastKind::floating, Src, DstTy);
1143
+ }
1144
+ DstTy = CGF.FloatTy ;
1102
1145
}
1103
1146
1104
1147
Res = buildScalarCast (Src, SrcType, DstType, SrcTy, DstTy, Opts);
1105
1148
1106
1149
if (DstTy != ResTy) {
1107
- llvm_unreachable (" NYI" );
1150
+ if (CGF.getContext ().getTargetInfo ().useFP16ConversionIntrinsics ()) {
1151
+ llvm_unreachable (" cast via llvm.convert.to.fp16 is NYI" );
1152
+ } else {
1153
+ Res = Builder.createCast (CGF.getLoc (Loc), mlir::cir::CastKind::floating,
1154
+ Res, ResTy);
1155
+ }
1108
1156
}
1109
1157
1110
1158
if (Opts.EmitImplicitIntegerTruncationChecks )
0 commit comments