diff options
author | Joey Gouly <joey.gouly@arm.com> | 2013-02-21 11:49:56 +0000 |
---|---|---|
committer | Joey Gouly <joey.gouly@arm.com> | 2013-02-21 11:49:56 +0000 |
commit | 52e933b0c3a1d552ab0e4d629ee15cff99a94447 (patch) | |
tree | ff092c7367162e12da71a5ae2c588e5e66763a8a /lib | |
parent | 4d8fe830d59010d6f748fd1c62090c20538c582b (diff) |
Add support to Sema and CodeGen for floating point vector types in OpenCL.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175734 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 31 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 51 |
2 files changed, 66 insertions, 16 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 7b86c04e8a..69aa7e849c 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1636,12 +1636,15 @@ Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) { } Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { - // Perform vector logical not on comparison with zero vector. if (E->getType()->isExtVectorType()) { Value *Oper = Visit(E->getSubExpr()); Value *Zero = llvm::Constant::getNullValue(Oper->getType()); - Value *Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp"); + Value *Result; + if (Oper->getType()->isFPOrFPVectorTy()) + Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp"); + else + Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp"); return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext"); } @@ -2668,16 +2671,20 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { } Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { - // Perform vector logical and on comparisons with zero vectors. if (E->getType()->isVectorType()) { Value *LHS = Visit(E->getLHS()); Value *RHS = Visit(E->getRHS()); Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); - LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); - RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); + if (LHS->getType()->isFPOrFPVectorTy()) { + LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); + RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); + } else { + LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); + RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); + } Value *And = Builder.CreateAnd(LHS, RHS); - return Builder.CreateSExt(And, Zero->getType(), "sext"); + return Builder.CreateSExt(And, ConvertType(E->getType()), "sext"); } llvm::Type *ResTy = ConvertType(E->getType()); @@ -2735,16 +2742,20 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { } Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { - // Perform vector logical or on comparisons with zero vectors. if (E->getType()->isVectorType()) { Value *LHS = Visit(E->getLHS()); Value *RHS = Visit(E->getRHS()); Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); - LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); - RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); + if (LHS->getType()->isFPOrFPVectorTy()) { + LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); + RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); + } else { + LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); + RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); + } Value *Or = Builder.CreateOr(LHS, RHS); - return Builder.CreateSExt(Or, Zero->getType(), "sext"); + return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext"); } llvm::Type *ResTy = ConvertType(E->getType()); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ec16efdf9d..2858f36511 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -7446,7 +7446,10 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, // Ensure that either both operands are of the same vector type, or // one operand is of a vector type and the other is of its element type. QualType vType = CheckVectorOperands(LHS, RHS, Loc, false); - if (vType.isNull() || vType->isFloatingType()) + if (vType.isNull()) + return InvalidOperands(Loc, LHS, RHS); + if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 && + vType->hasFloatingRepresentation()) return InvalidOperands(Loc, LHS, RHS); return GetSignedVectorType(LHS.get()->getType()); @@ -7522,8 +7525,17 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] RHS.get()->getLocEnd())); } } - + if (!Context.getLangOpts().CPlusPlus) { + // OpenCL v1.1 s6.3.g: The logical operators and (&&), or (||) do + // not operate on the built-in scalar and vector float types. + if (Context.getLangOpts().OpenCL && + Context.getLangOpts().OpenCLVersion < 120) { + if (LHS.get()->getType()->isFloatingType() || + RHS.get()->getType()->isFloatingType()) + return InvalidOperands(Loc, LHS, RHS); + } + LHS = UsualUnaryConversions(LHS.take()); if (LHS.isInvalid()) return QualType(); @@ -8849,7 +8861,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_Not: // bitwise complement Input = UsualUnaryConversions(Input.take()); - if (Input.isInvalid()) return ExprError(); + if (Input.isInvalid()) + return ExprError(); resultType = Input.get()->getType(); if (resultType->isDependentType()) break; @@ -8857,12 +8870,22 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, if (resultType->isComplexType() || resultType->isComplexIntegerType()) // C99 does not support '~' for complex conjugation. Diag(OpLoc, diag::ext_integer_complement_complex) - << resultType << Input.get()->getSourceRange(); + << resultType << Input.get()->getSourceRange(); else if (resultType->hasIntegerRepresentation()) break; - else { + else if (resultType->isExtVectorType()) { + if (Context.getLangOpts().OpenCL) { + // OpenCL v1.1 s6.3.f: The bitwise operator not (~) does not operate + // on vector float types. + QualType T = resultType->getAs<ExtVectorType>()->getElementType(); + if (!T->isIntegerType()) + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input.get()->getSourceRange()); + } + break; + } else { return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) - << resultType << Input.get()->getSourceRange()); + << resultType << Input.get()->getSourceRange()); } break; @@ -8887,8 +8910,24 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, // operand contextually converted to bool. Input = ImpCastExprToType(Input.take(), Context.BoolTy, ScalarTypeToBooleanCastKind(resultType)); + } else if (Context.getLangOpts().OpenCL && + Context.getLangOpts().OpenCLVersion < 120) { + // OpenCL v1.1 6.3.h: The logical operator not (!) does not + // operate on scalar float types. + if (!resultType->isIntegerType()) + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input.get()->getSourceRange()); } } else if (resultType->isExtVectorType()) { + if (Context.getLangOpts().OpenCL && + Context.getLangOpts().OpenCLVersion < 120) { + // OpenCL v1.1 6.3.h: The logical operator not (!) does not + // operate on vector float types. + QualType T = resultType->getAs<ExtVectorType>()->getElementType(); + if (!T->isIntegerType()) + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input.get()->getSourceRange()); + } // Vector logical not returns the signed variant of the operand type. resultType = GetSignedVectorType(resultType); break; |