From: Eli Friedman Date: Thu, 29 May 2008 15:17:49 +0000 (+0000) Subject: More complete/correct implementation of the comparison operators for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b896596a94315485e1d5cfabfbc3f82fd7f96393;p=clang More complete/correct implementation of the comparison operators for constant expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51682 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index a642fd236d..c61d71acad 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -385,20 +385,60 @@ public: return llvm::ConstantExpr::getAnd(LHS, RHS); } - llvm::Constant *VisitBinNE(const BinaryOperator *E) { + llvm::Constant *EmitCmp(const BinaryOperator *E, + llvm::CmpInst::Predicate SignedPred, + llvm::CmpInst::Predicate UnsignedPred, + llvm::CmpInst::Predicate FloatPred) { llvm::Constant *LHS = Visit(E->getLHS()); llvm::Constant *RHS = Visit(E->getRHS()); - - const llvm::Type* ResultType = ConvertType(E->getType()); - if (!ResultType->isInteger()) { + llvm::Constant *Result; + if (LHS->getType()->isInteger() || + isa(LHS->getType())) { + if (E->getLHS()->getType()->isSignedIntegerType()) + Result = llvm::ConstantExpr::getICmp(SignedPred, LHS, RHS); + else + Result = llvm::ConstantExpr::getICmp(UnsignedPred, LHS, RHS); + } else if (LHS->getType()->isFloatingPoint()) { + Result = llvm::ConstantExpr::getFCmp(FloatPred, LHS, RHS); + } else { CGM.WarnUnsupported(E, "constant expression"); - return llvm::Constant::getNullValue(ConvertType(E->getType())); + Result = llvm::ConstantInt::getFalse(); } - llvm::Constant *Result = - llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_NE, LHS, RHS); + + const llvm::Type* ResultType = ConvertType(E->getType()); return llvm::ConstantExpr::getZExtOrBitCast(Result, ResultType); } + llvm::Constant *VisitBinNE(const BinaryOperator *E) { + return EmitCmp(E, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_NE, + llvm::CmpInst::FCMP_ONE); + } + + llvm::Constant *VisitBinEQ(const BinaryOperator *E) { + return EmitCmp(E, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_EQ, + llvm::CmpInst::FCMP_OEQ); + } + + llvm::Constant *VisitBinLT(const BinaryOperator *E) { + return EmitCmp(E, llvm::CmpInst::ICMP_SLT, llvm::CmpInst::ICMP_ULT, + llvm::CmpInst::FCMP_OLT); + } + + llvm::Constant *VisitBinLE(const BinaryOperator *E) { + return EmitCmp(E, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_ULE, + llvm::CmpInst::FCMP_OLE); + } + + llvm::Constant *VisitBinGT(const BinaryOperator *E) { + return EmitCmp(E, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_UGT, + llvm::CmpInst::FCMP_OGT); + } + + llvm::Constant *VisitBinGE(const BinaryOperator *E) { + return EmitCmp(E, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGE, + llvm::CmpInst::FCMP_OGE); + } + llvm::Constant *VisitConditionalOperator(const ConditionalOperator *E) { llvm::Constant *Cond = Visit(E->getCond()); llvm::Constant *CondVal = EmitConversionToBool(Cond, E->getType()); diff --git a/test/CodeGen/constant-comparison.c b/test/CodeGen/constant-comparison.c new file mode 100644 index 0000000000..bc48ac4659 --- /dev/null +++ b/test/CodeGen/constant-comparison.c @@ -0,0 +1,12 @@ +// RUN: clang -emit-llvm %s -o - 2>&1 | not grep warning +// RUN: clang -emit-llvm %s -o - | grep @b | count 1 + +int a, b; +int *c1 = 1 < 2 ? &a : &b; +int *c2 = 3 != 3LL ? &b : &a; +int *c3 = !(3 <= 4.0) ? &b : &a; +int *c4 = &a - (6 * 5 > 30); +int *c5 = &a + (6 * 5 >= 30); +int c6 = 44 < 33; + +