# HG changeset patch # User Christian Kamm # Date 1245186027 -7200 # Node ID cc5fee7836dcd7e27d7e6179287b3812f2cf3481 # Parent 2292878925f41f25faede86948f677ba2e0a3719 Made is and !is use the same numeric comparison as == and !=, fixes #328 Factored out common code from EqualExp and IdentityExp into DtoBinNumericEquals in binexp.cpp. diff -r 2292878925f4 -r cc5fee7836dc gen/binops.cpp --- a/gen/binops.cpp Tue Jun 16 19:31:10 2009 +0200 +++ b/gen/binops.cpp Tue Jun 16 23:00:27 2009 +0200 @@ -5,6 +5,8 @@ #include "gen/irstate.h" #include "gen/tollvm.h" #include "gen/dvalue.h" +#include "gen/logger.h" +#include "gen/complex.h" ////////////////////////////////////////////////////////////////////////////// @@ -65,3 +67,34 @@ res = gIR->ir->CreateURem(l, r, "tmp"); return new DImValue( targettype, res ); } + +////////////////////////////////////////////////////////////////////////////// + +LLValue* DtoBinNumericEquals(Loc loc, DValue* lhs, DValue* rhs, TOK op) +{ + assert(op == TOKequal || op == TOKnotequal || + op == TOKidentity || op == TOKnotidentity); + Type* t = lhs->getType()->toBasetype(); + assert(t->isfloating()); + Logger::println("numeric equality"); + + LLValue* lv = lhs->getRVal(); + LLValue* rv = rhs->getRVal(); + LLValue* res = 0; + + if (t->iscomplex()) + { + Logger::println("complex"); + res = DtoComplexEquals(loc, op, lhs, rhs); + } + else if (t->isfloating()) + { + Logger::println("floating"); + res = (op == TOKidentity || op == TOKequal) + ? gIR->ir->CreateFCmpOEQ(lv,rv,"tmp") + : gIR->ir->CreateFCmpUNE(lv,rv,"tmp"); + } + + assert(res); + return res; +} diff -r 2292878925f4 -r cc5fee7836dc gen/complex.cpp --- a/gen/complex.cpp Tue Jun 16 19:31:10 2009 +0200 +++ b/gen/complex.cpp Tue Jun 16 23:00:27 2009 +0200 @@ -390,7 +390,7 @@ // select predicate llvm::FCmpInst::Predicate cmpop; - if (op == TOKequal) + if (op == TOKequal || op == TOKidentity) cmpop = llvm::FCmpInst::FCMP_OEQ; else cmpop = llvm::FCmpInst::FCMP_UNE; diff -r 2292878925f4 -r cc5fee7836dc gen/llvmhelpers.h --- a/gen/llvmhelpers.h Tue Jun 16 19:31:10 2009 +0200 +++ b/gen/llvmhelpers.h Tue Jun 16 23:00:27 2009 +0200 @@ -119,6 +119,7 @@ DValue* DtoBinMul(Type* resulttype, DValue* lhs, DValue* rhs); DValue* DtoBinDiv(Type* resulttype, DValue* lhs, DValue* rhs); DValue* DtoBinRem(Type* resulttype, DValue* lhs, DValue* rhs); +LLValue* DtoBinNumericEquals(Loc loc, DValue* lhs, DValue* rhs, TOK op); // target stuff void findDefaultTarget(); diff -r 2292878925f4 -r cc5fee7836dc gen/toir.cpp --- a/gen/toir.cpp Tue Jun 16 19:31:10 2009 +0200 +++ b/gen/toir.cpp Tue Jun 16 23:00:27 2009 +0200 @@ -1437,6 +1437,8 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); + LLValue* lv = l->getRVal(); + LLValue* rv = r->getRVal(); Type* t = e1->type->toBasetype(); Type* e2t = e2->type->toBasetype(); @@ -1461,8 +1463,6 @@ default: assert(0); } - LLValue* lv = l->getRVal(); - LLValue* rv = r->getRVal(); if (rv->getType() != lv->getType()) { rv = DtoBitCast(rv, lv->getType()); } @@ -1473,27 +1473,9 @@ } eval = p->ir->CreateICmp(cmpop, lv, rv, "tmp"); } - else if (t->iscomplex()) - { - Logger::println("complex"); - eval = DtoComplexEquals(loc, op, l, r); - } - else if (t->isfloating()) + else if (t->isfloating()) // includes iscomplex { - Logger::println("floating"); - llvm::FCmpInst::Predicate cmpop; - switch(op) - { - case TOKequal: - cmpop = llvm::FCmpInst::FCMP_OEQ; - break; - case TOKnotequal: - cmpop = llvm::FCmpInst::FCMP_UNE; - break; - default: - assert(0); - } - eval = p->ir->CreateFCmp(cmpop, l->getRVal(), r->getRVal(), "tmp"); + eval = DtoBinNumericEquals(loc, l, r, op); } else if (t->ty == Tsarray || t->ty == Tarray) { @@ -2041,55 +2023,53 @@ Logger::print("IdentityExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; - DValue* u = e1->toElem(p); - DValue* v = e2->toElem(p); + DValue* l = e1->toElem(p); + DValue* r = e2->toElem(p); + LLValue* lv = l->getRVal(); + LLValue* rv = r->getRVal(); Type* t1 = e1->type->toBasetype(); // handle dynarray specially if (t1->ty == Tarray) - return new DImValue(type, DtoDynArrayIs(op,u,v)); + return new DImValue(type, DtoDynArrayIs(op,l,r)); // also structs else if (t1->ty == Tstruct) - return new DImValue(type, DtoStructEquals(op,u,v)); + return new DImValue(type, DtoStructEquals(op,l,r)); // FIXME this stuff isn't pretty - LLValue* l = u->getRVal(); - LLValue* r = v->getRVal(); LLValue* eval = 0; if (t1->ty == Tdelegate) { - if (v->isNull()) { - r = NULL; + if (r->isNull()) { + rv = NULL; } else { - assert(l->getType() == r->getType()); + assert(lv->getType() == rv->getType()); } - eval = DtoDelegateEquals(op,l,r); + eval = DtoDelegateEquals(op,lv,rv); } - else if (t1->isfloating()) + else if (t1->isfloating()) // includes iscomplex { - eval = (op == TOKidentity) - ? p->ir->CreateFCmpOEQ(l,r,"tmp") - : p->ir->CreateFCmpONE(l,r,"tmp"); + eval = DtoBinNumericEquals(loc, l, r, op); } else if (t1->ty == Tpointer || t1->ty == Tclass) { - if (l->getType() != r->getType()) { - if (v->isNull()) - r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); + if (lv->getType() != rv->getType()) { + if (r->isNull()) + rv = llvm::ConstantPointerNull::get(isaPointer(lv->getType())); else - r = DtoBitCast(r, l->getType()); + rv = DtoBitCast(rv, lv->getType()); } eval = (op == TOKidentity) - ? p->ir->CreateICmpEQ(l,r,"tmp") - : p->ir->CreateICmpNE(l,r,"tmp"); + ? p->ir->CreateICmpEQ(lv,rv,"tmp") + : p->ir->CreateICmpNE(lv,rv,"tmp"); } else { - assert(l->getType() == r->getType()); + assert(lv->getType() == rv->getType()); eval = (op == TOKidentity) - ? p->ir->CreateICmpEQ(l,r,"tmp") - : p->ir->CreateICmpNE(l,r,"tmp"); + ? p->ir->CreateICmpEQ(lv,rv,"tmp") + : p->ir->CreateICmpNE(lv,rv,"tmp"); } return new DImValue(type, eval); }