mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-10 21:06:33 +03:00
Allow vectors to be compared for (not-)equality
I don't know how much sense that makes, as the front-end expects a result expression of a single bool. LLVM returns a vector of i1 values, the pair-wise results. From my experience with SIMD on x86_64, what's mostly needed is a vector bit mask, as that's what the CPU returns and which is later used to mask accesses/writes. Anyway, due to new `Target.isVectorOpSupported()` simply allowing all ops, (not-)equality comparisons of vectors now land here, and I reduce the pair-wise results via integer bitcast and an additional integer comparison.
This commit is contained in:
parent
988444c899
commit
db8797e1ce
4 changed files with 40 additions and 12 deletions
|
@ -324,18 +324,17 @@ LLValue *DtoBinNumericEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op) {
|
||||||
|
|
||||||
LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op) {
|
LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op) {
|
||||||
LLValue *res = nullptr;
|
LLValue *res = nullptr;
|
||||||
if (op == TOKequal) {
|
if (op == TOKequal || op == TOKnotequal) {
|
||||||
res = gIR->ir->CreateFCmpOEQ(DtoRVal(lhs), DtoRVal(rhs));
|
LLValue *l = DtoRVal(lhs);
|
||||||
} else if (op == TOKnotequal) {
|
LLValue *r = DtoRVal(rhs);
|
||||||
res = gIR->ir->CreateFCmpUNE(DtoRVal(lhs), DtoRVal(rhs));
|
res = (op == TOKequal ? gIR->ir->CreateFCmpOEQ(l, r)
|
||||||
} else {
|
: gIR->ir->CreateFCmpUNE(l, r));
|
||||||
llvm::ICmpInst::Predicate cmpop;
|
if (lhs->type->toBasetype()->ty == Tvector) {
|
||||||
if (op == TOKidentity) {
|
res = mergeVectorEquals(res, op);
|
||||||
cmpop = llvm::ICmpInst::ICMP_EQ;
|
|
||||||
} else {
|
|
||||||
cmpop = llvm::ICmpInst::ICMP_NE;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const auto cmpop =
|
||||||
|
op == TOKidentity ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
|
||||||
LLValue *sz = DtoConstSize_t(getTypeStoreSize(DtoType(lhs->type)));
|
LLValue *sz = DtoConstSize_t(getTypeStoreSize(DtoType(lhs->type)));
|
||||||
LLValue *val = DtoMemCmp(makeLValue(loc, lhs), makeLValue(loc, rhs), sz);
|
LLValue *val = DtoMemCmp(makeLValue(loc, lhs), makeLValue(loc, rhs), sz);
|
||||||
res = gIR->ir->CreateICmp(cmpop, val,
|
res = gIR->ir->CreateICmp(cmpop, val,
|
||||||
|
@ -344,3 +343,28 @@ LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op) {
|
||||||
assert(res);
|
assert(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LLValue *mergeVectorEquals(LLValue *resultsVector, TOK op) {
|
||||||
|
// `resultsVector` is a vector of i1 values, the pair-wise results.
|
||||||
|
// Bitcast to an integer and checks the bits via additional integer
|
||||||
|
// comparison.
|
||||||
|
const auto sizeInBits = getTypeBitSize(resultsVector->getType());
|
||||||
|
LLType *integerType = LLType::getIntNTy(gIR->context(), sizeInBits);
|
||||||
|
LLValue *v = DtoBitCast(resultsVector, integerType);
|
||||||
|
|
||||||
|
if (op == TOKequal) {
|
||||||
|
// all pairs must be equal for the vectors to be equal
|
||||||
|
LLConstant *allEqual =
|
||||||
|
LLConstantInt::get(integerType, (1 << sizeInBits) - 1);
|
||||||
|
return gIR->ir->CreateICmpEQ(v, allEqual);
|
||||||
|
} else if (op == TOKnotequal) {
|
||||||
|
// any not-equal pair suffices for the vectors to be not-equal
|
||||||
|
LLConstant *noneNotEqual = LLConstantInt::get(integerType, 0);
|
||||||
|
return gIR->ir->CreateICmpNE(v, noneNotEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm_unreachable("Unsupported operator.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
|
@ -57,5 +57,6 @@ DValue *binUshr(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
|
|
||||||
llvm::Value *DtoBinNumericEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
llvm::Value *DtoBinNumericEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
||||||
llvm::Value *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
llvm::Value *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
||||||
|
llvm::Value *mergeVectorEquals(llvm::Value *resultsVector, TOK op);
|
||||||
|
|
||||||
dinteger_t undoStrideMul(Loc &loc, Type *t, dinteger_t offset);
|
dinteger_t undoStrideMul(Loc &loc, Type *t, dinteger_t offset);
|
||||||
|
|
|
@ -1343,6 +1343,9 @@ public:
|
||||||
Logger::cout() << "rv: " << *rv << '\n';
|
Logger::cout() << "rv: " << *rv << '\n';
|
||||||
}
|
}
|
||||||
eval = p->ir->CreateICmp(cmpop, lv, rv);
|
eval = p->ir->CreateICmp(cmpop, lv, rv);
|
||||||
|
if (t->ty == Tvector) {
|
||||||
|
eval = mergeVectorEquals(eval, e->op);
|
||||||
|
}
|
||||||
} else if (t->isfloating()) // includes iscomplex
|
} else if (t->isfloating()) // includes iscomplex
|
||||||
{
|
{
|
||||||
eval = DtoBinNumericEquals(e->loc, l, r, e->op);
|
eval = DtoBinNumericEquals(e->loc, l, r, e->op);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0889fc7ce6f2148e1278e6f04e28ca50399d431b
|
Subproject commit cdf6195c9ca07b8e02e284f4581723c322f9c69d
|
Loading…
Add table
Add a link
Reference in a new issue