diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 058f8a79..cadb2288 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -1122,48 +1122,10 @@ LLValue* DtoArrayEquals(Loc& loc, TOK op, DValue* l, DValue* r) LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r) { LLValue* res = 0; - llvm::ICmpInst::Predicate cmpop; - bool skip = false; + tokToIcmpPred(op, false, &cmpop, &res); - switch(op) - { - case TOKlt: - case TOKul: - cmpop = llvm::ICmpInst::ICMP_SLT; - break; - case TOKle: - case TOKule: - cmpop = llvm::ICmpInst::ICMP_SLE; - break; - case TOKgt: - case TOKug: - cmpop = llvm::ICmpInst::ICMP_SGT; - break; - case TOKge: - case TOKuge: - cmpop = llvm::ICmpInst::ICMP_SGE; - break; - case TOKue: - cmpop = llvm::ICmpInst::ICMP_EQ; - break; - case TOKlg: - cmpop = llvm::ICmpInst::ICMP_NE; - break; - case TOKleg: - skip = true; - res = LLConstantInt::getTrue(gIR->context()); - break; - case TOKunord: - skip = true; - res = LLConstantInt::getFalse(gIR->context()); - break; - - default: - assert(0); - } - - if (!skip) + if (!res) { Type* t = l->getType()->toBasetype()->nextOf()->toBasetype(); if (t->ty == Tchar) diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index a20c6dd5..aad156bd 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1872,8 +1872,6 @@ void printLabelName(std::ostream& target, const char* func_mangle, const char* l func_mangle << "_" << label_name; } -////////////////////////////////////////////////////////////////////////////////////////// -// CTOR and DTOR ////////////////////////////////////////////////////////////////////////////////////////// void AppendFunctionToLLVMGlobalCtorsDtors(llvm::Function* func, const uint32_t priority, const bool isCtor) @@ -1883,3 +1881,42 @@ void AppendFunctionToLLVMGlobalCtorsDtors(llvm::Function* func, const uint32_t p else llvm::appendToGlobalDtors(*gIR->module, func, priority); } + +////////////////////////////////////////////////////////////////////////////////////////// + +void tokToIcmpPred(TOK op, bool isUnsigned, llvm::ICmpInst::Predicate* outPred, llvm::Value** outConst) +{ + switch(op) + { + case TOKlt: + case TOKul: + *outPred = isUnsigned ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT; + break; + case TOKle: + case TOKule: + *outPred = isUnsigned ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE; + break; + case TOKgt: + case TOKug: + *outPred = isUnsigned ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT; + break; + case TOKge: + case TOKuge: + *outPred = isUnsigned ? llvm::ICmpInst::ICMP_UGE : llvm::ICmpInst::ICMP_SGE; + break; + case TOKue: + *outPred = llvm::ICmpInst::ICMP_EQ; + break; + case TOKlg: + *outPred = llvm::ICmpInst::ICMP_NE; + break; + case TOKleg: + *outConst = LLConstantInt::getTrue(gIR->context()); + break; + case TOKunord: + *outConst = LLConstantInt::getFalse(gIR->context()); + break; + default: + llvm_unreachable("Invalid comparison operation"); + } +} diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 4f3a688c..5ab4b810 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -183,6 +183,14 @@ bool isSpecialRefVar(VarDeclaration* vd); /// pointers. bool isLLVMUnsigned(Type* t); +/// Converts a DMD comparison operation token into the corresponding LLVM icmp +/// predicate for the given operand signedness. +/// +/// For some operations, the result can be a constant. In this case outConst is +/// set to it, otherwise outPred is set to the predicate to use. +void tokToIcmpPred(TOK op, bool isUnsigned, llvm::ICmpInst::Predicate* outPred, + llvm::Value** outConst); + //////////////////////////////////////////// // gen/tocall.cpp stuff below //////////////////////////////////////////// diff --git a/gen/toir.cpp b/gen/toir.cpp index 1947627e..ad7eff0e 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1711,46 +1711,10 @@ DValue* CmpExp::toElem(IRState* p) if (t->isintegral() || t->ty == Tpointer || t->ty == Tnull) { - llvm::ICmpInst::Predicate cmpop; - bool skip = false; - bool uns = isLLVMUnsigned(t); - switch(op) - { - case TOKlt: - case TOKul: - cmpop = uns ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT; - break; - case TOKle: - case TOKule: - cmpop = uns ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE; - break; - case TOKgt: - case TOKug: - cmpop = uns ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT; - break; - case TOKge: - case TOKuge: - cmpop = uns ? llvm::ICmpInst::ICMP_UGE : llvm::ICmpInst::ICMP_SGE; - break; - case TOKue: - cmpop = llvm::ICmpInst::ICMP_EQ; - break; - case TOKlg: - cmpop = llvm::ICmpInst::ICMP_NE; - break; - case TOKleg: - skip = true; - eval = LLConstantInt::getTrue(gIR->context()); - break; - case TOKunord: - skip = true; - eval = LLConstantInt::getFalse(gIR->context()); - break; + llvm::ICmpInst::Predicate icmpPred; + tokToIcmpPred(op, isLLVMUnsigned(t), &icmpPred, &eval); - default: - assert(0); - } - if (!skip) + if (!eval) { LLValue* a = l->getRVal(); LLValue* b = r->getRVal(); @@ -1761,7 +1725,7 @@ DValue* CmpExp::toElem(IRState* p) } if (a->getType() != b->getType()) b = DtoBitCast(b, a->getType()); - eval = p->ir->CreateICmp(cmpop, a, b, "tmp"); + eval = p->ir->CreateICmp(icmpPred, a, b, "tmp"); } } else if (t->isfloating())