comparison gen/toir.cpp @ 1503:cc5fee7836dc

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.
author Christian Kamm <kamm incasoftware de>
date Tue, 16 Jun 2009 23:00:27 +0200
parents d9d50163e1a4
children 5b66008246bb
comparison
equal deleted inserted replaced
1502:2292878925f4 1503:cc5fee7836dc
1435 Logger::print("EqualExp::toElem: %s @ %s\n", toChars(), type->toChars()); 1435 Logger::print("EqualExp::toElem: %s @ %s\n", toChars(), type->toChars());
1436 LOG_SCOPE; 1436 LOG_SCOPE;
1437 1437
1438 DValue* l = e1->toElem(p); 1438 DValue* l = e1->toElem(p);
1439 DValue* r = e2->toElem(p); 1439 DValue* r = e2->toElem(p);
1440 LLValue* lv = l->getRVal();
1441 LLValue* rv = r->getRVal();
1440 1442
1441 Type* t = e1->type->toBasetype(); 1443 Type* t = e1->type->toBasetype();
1442 Type* e2t = e2->type->toBasetype(); 1444 Type* e2t = e2->type->toBasetype();
1443 //assert(t == e2t); 1445 //assert(t == e2t);
1444 1446
1459 cmpop = llvm::ICmpInst::ICMP_NE; 1461 cmpop = llvm::ICmpInst::ICMP_NE;
1460 break; 1462 break;
1461 default: 1463 default:
1462 assert(0); 1464 assert(0);
1463 } 1465 }
1464 LLValue* lv = l->getRVal();
1465 LLValue* rv = r->getRVal();
1466 if (rv->getType() != lv->getType()) { 1466 if (rv->getType() != lv->getType()) {
1467 rv = DtoBitCast(rv, lv->getType()); 1467 rv = DtoBitCast(rv, lv->getType());
1468 } 1468 }
1469 if (Logger::enabled()) 1469 if (Logger::enabled())
1470 { 1470 {
1471 Logger::cout() << "lv: " << *lv << '\n'; 1471 Logger::cout() << "lv: " << *lv << '\n';
1472 Logger::cout() << "rv: " << *rv << '\n'; 1472 Logger::cout() << "rv: " << *rv << '\n';
1473 } 1473 }
1474 eval = p->ir->CreateICmp(cmpop, lv, rv, "tmp"); 1474 eval = p->ir->CreateICmp(cmpop, lv, rv, "tmp");
1475 } 1475 }
1476 else if (t->iscomplex()) 1476 else if (t->isfloating()) // includes iscomplex
1477 { 1477 {
1478 Logger::println("complex"); 1478 eval = DtoBinNumericEquals(loc, l, r, op);
1479 eval = DtoComplexEquals(loc, op, l, r);
1480 }
1481 else if (t->isfloating())
1482 {
1483 Logger::println("floating");
1484 llvm::FCmpInst::Predicate cmpop;
1485 switch(op)
1486 {
1487 case TOKequal:
1488 cmpop = llvm::FCmpInst::FCMP_OEQ;
1489 break;
1490 case TOKnotequal:
1491 cmpop = llvm::FCmpInst::FCMP_UNE;
1492 break;
1493 default:
1494 assert(0);
1495 }
1496 eval = p->ir->CreateFCmp(cmpop, l->getRVal(), r->getRVal(), "tmp");
1497 } 1479 }
1498 else if (t->ty == Tsarray || t->ty == Tarray) 1480 else if (t->ty == Tsarray || t->ty == Tarray)
1499 { 1481 {
1500 Logger::println("static or dynamic array"); 1482 Logger::println("static or dynamic array");
1501 eval = DtoArrayEquals(loc,op,l,r); 1483 eval = DtoArrayEquals(loc,op,l,r);
2039 DValue* IdentityExp::toElem(IRState* p) 2021 DValue* IdentityExp::toElem(IRState* p)
2040 { 2022 {
2041 Logger::print("IdentityExp::toElem: %s @ %s\n", toChars(), type->toChars()); 2023 Logger::print("IdentityExp::toElem: %s @ %s\n", toChars(), type->toChars());
2042 LOG_SCOPE; 2024 LOG_SCOPE;
2043 2025
2044 DValue* u = e1->toElem(p); 2026 DValue* l = e1->toElem(p);
2045 DValue* v = e2->toElem(p); 2027 DValue* r = e2->toElem(p);
2028 LLValue* lv = l->getRVal();
2029 LLValue* rv = r->getRVal();
2046 2030
2047 Type* t1 = e1->type->toBasetype(); 2031 Type* t1 = e1->type->toBasetype();
2048 2032
2049 // handle dynarray specially 2033 // handle dynarray specially
2050 if (t1->ty == Tarray) 2034 if (t1->ty == Tarray)
2051 return new DImValue(type, DtoDynArrayIs(op,u,v)); 2035 return new DImValue(type, DtoDynArrayIs(op,l,r));
2052 // also structs 2036 // also structs
2053 else if (t1->ty == Tstruct) 2037 else if (t1->ty == Tstruct)
2054 return new DImValue(type, DtoStructEquals(op,u,v)); 2038 return new DImValue(type, DtoStructEquals(op,l,r));
2055 2039
2056 // FIXME this stuff isn't pretty 2040 // FIXME this stuff isn't pretty
2057 LLValue* l = u->getRVal();
2058 LLValue* r = v->getRVal();
2059 LLValue* eval = 0; 2041 LLValue* eval = 0;
2060 2042
2061 if (t1->ty == Tdelegate) { 2043 if (t1->ty == Tdelegate) {
2062 if (v->isNull()) { 2044 if (r->isNull()) {
2063 r = NULL; 2045 rv = NULL;
2064 } 2046 }
2065 else { 2047 else {
2066 assert(l->getType() == r->getType()); 2048 assert(lv->getType() == rv->getType());
2067 } 2049 }
2068 eval = DtoDelegateEquals(op,l,r); 2050 eval = DtoDelegateEquals(op,lv,rv);
2069 } 2051 }
2070 else if (t1->isfloating()) 2052 else if (t1->isfloating()) // includes iscomplex
2071 { 2053 {
2054 eval = DtoBinNumericEquals(loc, l, r, op);
2055 }
2056 else if (t1->ty == Tpointer || t1->ty == Tclass)
2057 {
2058 if (lv->getType() != rv->getType()) {
2059 if (r->isNull())
2060 rv = llvm::ConstantPointerNull::get(isaPointer(lv->getType()));
2061 else
2062 rv = DtoBitCast(rv, lv->getType());
2063 }
2072 eval = (op == TOKidentity) 2064 eval = (op == TOKidentity)
2073 ? p->ir->CreateFCmpOEQ(l,r,"tmp") 2065 ? p->ir->CreateICmpEQ(lv,rv,"tmp")
2074 : p->ir->CreateFCmpONE(l,r,"tmp"); 2066 : p->ir->CreateICmpNE(lv,rv,"tmp");
2075 } 2067 }
2076 else if (t1->ty == Tpointer || t1->ty == Tclass) 2068 else {
2077 { 2069 assert(lv->getType() == rv->getType());
2078 if (l->getType() != r->getType()) {
2079 if (v->isNull())
2080 r = llvm::ConstantPointerNull::get(isaPointer(l->getType()));
2081 else
2082 r = DtoBitCast(r, l->getType());
2083 }
2084 eval = (op == TOKidentity) 2070 eval = (op == TOKidentity)
2085 ? p->ir->CreateICmpEQ(l,r,"tmp") 2071 ? p->ir->CreateICmpEQ(lv,rv,"tmp")
2086 : p->ir->CreateICmpNE(l,r,"tmp"); 2072 : p->ir->CreateICmpNE(lv,rv,"tmp");
2087 }
2088 else {
2089 assert(l->getType() == r->getType());
2090 eval = (op == TOKidentity)
2091 ? p->ir->CreateICmpEQ(l,r,"tmp")
2092 : p->ir->CreateICmpNE(l,r,"tmp");
2093 } 2073 }
2094 return new DImValue(type, eval); 2074 return new DImValue(type, eval);
2095 } 2075 }
2096 2076
2097 ////////////////////////////////////////////////////////////////////////////////////////// 2077 //////////////////////////////////////////////////////////////////////////////////////////