diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 90 |
1 files changed, 64 insertions, 26 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index ef3e27ecec99..603d9a6e7e84 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -348,6 +348,9 @@ public: EmitImplicitIntegerSignChangeChecks( SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {} }; + Value *EmitScalarCast(Value *Src, QualType SrcType, QualType DstType, + llvm::Type *SrcTy, llvm::Type *DstTy, + ScalarConversionOpts Opts); Value * EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc, @@ -1191,6 +1194,58 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, {Src, Dst}); } +Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType, + QualType DstType, llvm::Type *SrcTy, + llvm::Type *DstTy, + ScalarConversionOpts Opts) { + // The Element types determine the type of cast to perform. + llvm::Type *SrcElementTy; + llvm::Type *DstElementTy; + QualType SrcElementType; + QualType DstElementType; + if (SrcType->isMatrixType() && DstType->isMatrixType()) { + // Allow bitcast between matrixes of the same size. + if (SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits()) + return Builder.CreateBitCast(Src, DstTy, "conv"); + + SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType(); + DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType(); + SrcElementType = SrcType->castAs<MatrixType>()->getElementType(); + DstElementType = DstType->castAs<MatrixType>()->getElementType(); + } else { + assert(!SrcType->isMatrixType() && !DstType->isMatrixType() && + "cannot cast between matrix and non-matrix types"); + SrcElementTy = SrcTy; + DstElementTy = DstTy; + SrcElementType = SrcType; + DstElementType = DstType; + } + + if (isa<llvm::IntegerType>(SrcElementTy)) { + bool InputSigned = SrcElementType->isSignedIntegerOrEnumerationType(); + if (SrcElementType->isBooleanType() && Opts.TreatBooleanAsSigned) { + InputSigned = true; + } + + if (isa<llvm::IntegerType>(DstElementTy)) + return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"); + if (InputSigned) + return Builder.CreateSIToFP(Src, DstTy, "conv"); + return Builder.CreateUIToFP(Src, DstTy, "conv"); + } + + if (isa<llvm::IntegerType>(DstElementTy)) { + assert(SrcElementTy->isFloatingPointTy() && "Unknown real conversion"); + if (DstElementType->isSignedIntegerOrEnumerationType()) + return Builder.CreateFPToSI(Src, DstTy, "conv"); + return Builder.CreateFPToUI(Src, DstTy, "conv"); + } + + if (DstElementTy->getTypeID() < SrcElementTy->getTypeID()) + return Builder.CreateFPTrunc(Src, DstTy, "conv"); + return Builder.CreateFPExt(Src, DstTy, "conv"); +} + /// Emit a conversion from the specified type to the specified destination type, /// both of which are LLVM scalar types. Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, @@ -1318,6 +1373,9 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, return Builder.CreateVectorSplat(NumElements, Src, "splat"); } + if (SrcType->isMatrixType() && DstType->isMatrixType()) + return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts); + if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) { // Allow bitcast from vector to integer/fp of the same size. unsigned SrcSize = SrcTy->getPrimitiveSizeInBits(); @@ -1384,31 +1442,7 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, DstTy = CGF.FloatTy; } - if (isa<llvm::IntegerType>(SrcTy)) { - bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); - if (SrcType->isBooleanType() && Opts.TreatBooleanAsSigned) { - InputSigned = true; - } - if (isa<llvm::IntegerType>(DstTy)) - Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"); - else if (InputSigned) - Res = Builder.CreateSIToFP(Src, DstTy, "conv"); - else - Res = Builder.CreateUIToFP(Src, DstTy, "conv"); - } else if (isa<llvm::IntegerType>(DstTy)) { - assert(SrcTy->isFloatingPointTy() && "Unknown real conversion"); - if (DstType->isSignedIntegerOrEnumerationType()) - Res = Builder.CreateFPToSI(Src, DstTy, "conv"); - else - Res = Builder.CreateFPToUI(Src, DstTy, "conv"); - } else { - assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() && - "Unknown real conversion"); - if (DstTy->getTypeID() < SrcTy->getTypeID()) - Res = Builder.CreateFPTrunc(Src, DstTy, "conv"); - else - Res = Builder.CreateFPExt(Src, DstTy, "conv"); - } + Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts); if (DstTy != ResTy) { if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { @@ -1729,7 +1763,7 @@ Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) { llvm::MatrixBuilder<CGBuilderTy> MB(Builder); return MB.CreateExtractElement( Matrix, RowIdx, ColumnIdx, - E->getBase()->getType()->getAs<ConstantMatrixType>()->getNumRows()); + E->getBase()->getType()->castAs<ConstantMatrixType>()->getNumRows()); } static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, @@ -2230,6 +2264,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { CGF.EmitIgnoredExpr(E); return nullptr; } + case CK_MatrixCast: { + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); + } case CK_VectorSplat: { llvm::Type *DstTy = ConvertType(DestTy); Value *Elt = Visit(const_cast<Expr*>(E)); |