Merge pull request #1562 from kinke/dvalue

Continue with DValue refactoring and fix issue #1327
This commit is contained in:
kinke 2016-06-26 21:24:43 +02:00 committed by GitHub
commit a2fdffaf0d
8 changed files with 180 additions and 158 deletions

View file

@ -18,11 +18,10 @@
//////////////////////////////////////////////////////////////////////////////
DValue *DtoBinAdd(DValue *lhs, DValue *rhs) {
DImValue *DtoBinAdd(DRValue *lhs, DRValue *rhs) {
Type *t = lhs->type;
LLValue *l, *r;
l = DtoRVal(lhs);
r = DtoRVal(rhs);
LLValue *l = DtoRVal(lhs);
LLValue *r = DtoRVal(rhs);
LLValue *res;
if (t->isfloating()) {
@ -36,11 +35,10 @@ DValue *DtoBinAdd(DValue *lhs, DValue *rhs) {
//////////////////////////////////////////////////////////////////////////////
DValue *DtoBinSub(DValue *lhs, DValue *rhs) {
DImValue *DtoBinSub(DRValue *lhs, DRValue *rhs) {
Type *t = lhs->type;
LLValue *l, *r;
l = DtoRVal(lhs);
r = DtoRVal(rhs);
LLValue *l = DtoRVal(lhs);
LLValue *r = DtoRVal(rhs);
LLValue *res;
if (t->isfloating()) {
@ -54,11 +52,10 @@ DValue *DtoBinSub(DValue *lhs, DValue *rhs) {
//////////////////////////////////////////////////////////////////////////////
DValue *DtoBinMul(Type *targettype, DValue *lhs, DValue *rhs) {
DImValue *DtoBinMul(Type *targettype, DRValue *lhs, DRValue *rhs) {
Type *t = lhs->type;
LLValue *l, *r;
l = DtoRVal(lhs);
r = DtoRVal(rhs);
LLValue *l = DtoRVal(lhs);
LLValue *r = DtoRVal(rhs);
LLValue *res;
if (t->isfloating()) {
@ -66,16 +63,16 @@ DValue *DtoBinMul(Type *targettype, DValue *lhs, DValue *rhs) {
} else {
res = gIR->ir->CreateMul(l, r);
}
return new DImValue(targettype, res);
}
//////////////////////////////////////////////////////////////////////////////
DValue *DtoBinDiv(Type *targettype, DValue *lhs, DValue *rhs) {
DImValue *DtoBinDiv(Type *targettype, DRValue *lhs, DRValue *rhs) {
Type *t = lhs->type;
LLValue *l, *r;
l = DtoRVal(lhs);
r = DtoRVal(rhs);
LLValue *l = DtoRVal(lhs);
LLValue *r = DtoRVal(rhs);
LLValue *res;
if (t->isfloating()) {
@ -85,16 +82,17 @@ DValue *DtoBinDiv(Type *targettype, DValue *lhs, DValue *rhs) {
} else {
res = gIR->ir->CreateUDiv(l, r);
}
return new DImValue(targettype, res);
}
//////////////////////////////////////////////////////////////////////////////
DValue *DtoBinRem(Type *targettype, DValue *lhs, DValue *rhs) {
DImValue *DtoBinRem(Type *targettype, DRValue *lhs, DRValue *rhs) {
Type *t = lhs->type;
LLValue *l, *r;
l = DtoRVal(lhs);
r = DtoRVal(rhs);
LLValue *l = DtoRVal(lhs);
LLValue *r = DtoRVal(rhs);
LLValue *res;
if (t->isfloating()) {
res = gIR->ir->CreateFRem(l, r);
@ -103,6 +101,7 @@ DValue *DtoBinRem(Type *targettype, DValue *lhs, DValue *rhs) {
} else {
res = gIR->ir->CreateURem(l, r);
}
return new DImValue(targettype, res);
}

View file

@ -181,7 +181,7 @@ void DtoGetComplexParts(Loc &loc, Type *to, DValue *val, LLValue *&re,
////////////////////////////////////////////////////////////////////////////////
DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
DImValue *DtoComplexAdd(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
// lhs values
@ -212,7 +212,7 @@ DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
////////////////////////////////////////////////////////////////////////////////
DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
DImValue *DtoComplexSub(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
// lhs values
@ -243,7 +243,7 @@ DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
////////////////////////////////////////////////////////////////////////////////
DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
DImValue *DtoComplexMul(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
// lhs values
@ -296,7 +296,7 @@ DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
////////////////////////////////////////////////////////////////////////////////
DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
DImValue *DtoComplexDiv(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
// lhs values
@ -369,7 +369,7 @@ DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
////////////////////////////////////////////////////////////////////////////////
DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
DImValue *DtoComplexRem(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im, *divisor;
// lhs values
@ -390,7 +390,7 @@ DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
////////////////////////////////////////////////////////////////////////////////
DValue *DtoComplexNeg(Loc &loc, Type *type, DValue *val) {
DImValue *DtoComplexNeg(Loc &loc, Type *type, DRValue *val) {
llvm::Value *a, *b, *re, *im;
// values

View file

@ -16,8 +16,8 @@
#include "tokens.h"
#include "longdouble.h"
#include "dvalue.h"
class DValue;
struct Loc;
class Type;
namespace llvm {
@ -43,12 +43,12 @@ void DtoGetComplexParts(Loc &loc, Type *to, DValue *c, DValue *&re,
void DtoGetComplexParts(Loc &loc, Type *to, DValue *c, llvm::Value *&re,
llvm::Value *&im);
DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
DValue *DtoComplexNeg(Loc &loc, Type *type, DValue *val);
DImValue *DtoComplexAdd(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
DImValue *DtoComplexSub(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
DImValue *DtoComplexMul(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
DImValue *DtoComplexDiv(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
DImValue *DtoComplexRem(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
DImValue *DtoComplexNeg(Loc &loc, Type *type, DRValue *val);
llvm::Value *DtoComplexEquals(Loc &loc, TOK op, DValue *lhs, DValue *rhs);

View file

@ -36,18 +36,53 @@ bool isDefinedInFuncEntryBB(LLValue *v) {
////////////////////////////////////////////////////////////////////////////////
bool DValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); }
////////////////////////////////////////////////////////////////////////////////
DImValue::DImValue(Type *t, llvm::Value *v) : DValue(t, v) {
assert(!DtoIsInMemoryOnly(t) &&
"Cannot represent memory-only type as immediate DValue");
LLValue *DtoLVal(DValue *v) {
auto lval = v->isLVal();
assert(lval);
return lval->getLVal()->val;
}
////////////////////////////////////////////////////////////////////////////////
DConstValue::DConstValue(Type *t, llvm::Constant *con) : DValue(t, con) {}
DValue::DValue(Type *t, LLValue *v) : type(t), val(v) {
assert(type);
assert(val);
}
bool DValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); }
////////////////////////////////////////////////////////////////////////////////
DRValue::DRValue(Type *t, LLValue *v) : DValue(t, v) {
assert(!DtoIsInMemoryOnly(t) &&
"Cannot represent memory-only type as DRValue");
}
////////////////////////////////////////////////////////////////////////////////
DConstValue::DConstValue(Type *t, LLConstant *con) : DRValue(t, con) {}
////////////////////////////////////////////////////////////////////////////////
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
: DRValue(t, DtoAggrPair(length, ptr)) {}
LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
LLValue *DSliceValue::getPtr() { return DtoExtractValue(val, 1, ".ptr"); }
////////////////////////////////////////////////////////////////////////////////
DFuncValue::DFuncValue(Type *t, FuncDeclaration *fd, LLValue *v, LLValue *vt)
: DRValue(t, v), func(fd), vthis(vt) {}
DFuncValue::DFuncValue(FuncDeclaration *fd, LLValue *v, LLValue *vt)
: DRValue(fd->type, v), func(fd), vthis(vt) {}
bool DFuncValue::definedInFuncEntryBB() {
return isDefinedInFuncEntryBB(val) &&
(!vthis || isDefinedInFuncEntryBB(vthis));
}
////////////////////////////////////////////////////////////////////////////////
@ -78,18 +113,19 @@ DLValue::DLValue(Type *t, LLValue *v) : DValue(t, v) {
assert(checkVarValueType(v->getType(), false));
}
LLValue *DLValue::getRVal() {
if (DtoIsInMemoryOnly(type->toBasetype())) {
DRValue *DLValue::getRVal() {
if (DtoIsInMemoryOnly(type)) {
llvm_unreachable("getRVal() for memory-only type");
return nullptr;
}
LLValue *rawValue = DtoLoad(val);
if (type->toBasetype()->ty != Tbool)
return rawValue;
LLValue *rval = DtoLoad(val);
if (type->toBasetype()->ty == Tbool) {
assert(rval->getType() == llvm::Type::getInt8Ty(gIR->context()));
rval = gIR->ir->CreateTrunc(rval, llvm::Type::getInt1Ty(gIR->context()));
}
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
return gIR->ir->CreateTrunc(rawValue, llvm::Type::getInt1Ty(gIR->context()));
return new DImValue(type, rval);
}
////////////////////////////////////////////////////////////////////////////////
@ -98,30 +134,8 @@ DSpecialRefValue::DSpecialRefValue(Type *t, LLValue *v) : DLValue(v, t) {
assert(checkVarValueType(v->getType(), true));
}
LLValue *DSpecialRefValue::getLVal() { return DtoLoad(val); }
LLValue *DSpecialRefValue::getRVal() {
return DLValue(type, getLVal()).getRVal();
DRValue *DSpecialRefValue::getRVal() {
return DLValue(type, DtoLoad(val)).getRVal();
}
////////////////////////////////////////////////////////////////////////////////
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
: DValue(t, DtoAggrPair(length, ptr)) {}
LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
LLValue *DSliceValue::getPtr() { return DtoExtractValue(val, 1, ".ptr"); }
////////////////////////////////////////////////////////////////////////////////
DFuncValue::DFuncValue(Type *t, FuncDeclaration *fd, LLValue *v, LLValue *vt)
: DValue(t, v), func(fd), vthis(vt) {}
DFuncValue::DFuncValue(FuncDeclaration *fd, LLValue *v, LLValue *vt)
: DValue(fd->type, v), func(fd), vthis(vt) {}
bool DFuncValue::definedInFuncEntryBB() {
return isDefinedInFuncEntryBB(val) &&
(!vthis || isDefinedInFuncEntryBB(vthis));
}
DLValue *DSpecialRefValue::getLVal() { return new DLValue(type, DtoLoad(val)); }

View file

@ -18,7 +18,6 @@
#define LDC_GEN_DVALUE_H
#include "root.h"
#include <cassert>
class Type;
class Dsymbol;
@ -31,35 +30,38 @@ class Type;
class Constant;
}
class DValue;
class DRValue;
class DImValue;
class DConstValue;
class DNullValue;
class DLValue;
class DSpecialRefValue;
class DFuncValue;
class DSliceValue;
class DFuncValue;
// base class for d-values
/// Represents an immutable pair of LLVM value and associated D type.
class DValue {
public:
Type *const type;
virtual ~DValue() = default;
virtual llvm::Value *getRVal() { return val; }
/// Returns true iff the value can be accessed at the end of the entry basic
/// block of the current function, in the sense that it is either not derived
/// from an llvm::Instruction (but from a global, constant, etc.) or that
/// instruction is part of the entry basic block.
///
/// In other words, whatever value the result of getLVal()/getRVal() might be
/// derived from then certainly dominates uses in all other basic blocks of
/// the function.
/// In other words, whatever the value might be derived from then certainly
/// dominates uses in all other basic blocks of the function.
virtual bool definedInFuncEntryBB();
virtual DRValue *getRVal() { return nullptr; }
virtual DLValue *isLVal() { return nullptr; }
virtual DSpecialRefValue *isSpecialRef() { return nullptr; }
virtual DRValue *isRVal() { return nullptr; }
virtual DImValue *isIm() { return nullptr; }
virtual DConstValue *isConst() { return nullptr; }
virtual DNullValue *isNull() { return nullptr; }
@ -69,22 +71,35 @@ public:
protected:
llvm::Value *const val;
DValue(Type *t, llvm::Value *v) : type(t), val(v) {
assert(type);
assert(val);
}
DValue(Type *t, llvm::Value *v);
friend llvm::Value *DtoRVal(DValue *v);
};
// immediate d-value
class DImValue : public DValue {
/// Represents a D rvalue via a low-level rvalue.
class DRValue : public DValue {
public:
DImValue(Type *t, llvm::Value *v);
DRValue *getRVal() override { return this; }
DRValue *isRVal() override { return this; }
protected:
DRValue(Type *t, llvm::Value *v);
};
/// Represents an immediate D value (simple rvalue with no special properties
/// like being a compile-time constant) via a low-level rvalue.
/// Restricted to primitive types such as pointers (incl. class references),
/// integral and floating-point types.
class DImValue : public DRValue {
public:
DImValue(Type *t, llvm::Value *v) : DRValue(t, v) {}
DImValue *isIm() override { return this; }
};
// constant d-value
class DConstValue : public DValue {
/// Represents a D compile-time constant via a low-level constant.
class DConstValue : public DRValue {
public:
DConstValue(Type *t, llvm::Constant *con);
@ -93,7 +108,7 @@ public:
DConstValue *isConst() override { return this; }
};
// null d-value
/// Represents a D compile-time null constant.
class DNullValue : public DConstValue {
public:
DNullValue(Type *t, llvm::Constant *con) : DConstValue(t, con) {}
@ -101,36 +116,8 @@ public:
DNullValue *isNull() override { return this; }
};
/// Represents a D value in memory via a low-level lvalue.
/// This doesn't imply that the D value is an lvalue too - e.g., we always
/// keep structs and static arrays in memory.
class DLValue : public DValue {
public:
DLValue(Type *t, llvm::Value *v);
virtual llvm::Value *getLVal() { return val; }
llvm::Value *getRVal() override;
DLValue *isLVal() override { return this; }
protected:
DLValue(llvm::Value *v, Type *t) : DValue(t, v) {}
};
/// Represents special internal ref variables.
class DSpecialRefValue : public DLValue {
public:
DSpecialRefValue(Type *t, llvm::Value *v);
llvm::Value *getRefStorage() { return val; }
llvm::Value *getLVal() override;
llvm::Value *getRVal() override;
DSpecialRefValue *isSpecialRef() override { return this; }
};
// slice d-value
class DSliceValue : public DValue {
/// Represents a D slice (dynamic array).
class DSliceValue : public DRValue {
public:
DSliceValue(Type *t, llvm::Value *length, llvm::Value *ptr);
@ -140,8 +127,8 @@ public:
llvm::Value *getPtr();
};
// function d-value
class DFuncValue : public DValue {
/// Represents a D function value with optional this/context pointer.
class DFuncValue : public DRValue {
public:
FuncDeclaration *func;
llvm::Value *vthis;
@ -155,4 +142,38 @@ public:
DFuncValue *isFunc() override { return this; }
};
/// Represents a D value in memory via a low-level lvalue (pointer).
/// This doesn't imply that the D value is an lvalue too - e.g., we always
/// keep structs and static arrays in memory.
class DLValue : public DValue {
public:
DLValue(Type *t, llvm::Value *v);
DRValue *getRVal() override;
virtual DLValue *getLVal() { return this; }
DLValue *isLVal() override { return this; }
protected:
DLValue(llvm::Value *v, Type *t) : DValue(t, v) {}
friend llvm::Value *DtoLVal(DValue *v);
};
/// Represents special internal ref variables.
class DSpecialRefValue : public DLValue {
public:
DSpecialRefValue(Type *t, llvm::Value *v);
DRValue *getRVal() override;
DLValue *getLVal() override;
llvm::Value *getRefStorage() { return val; }
DSpecialRefValue *isSpecialRef() override { return this; }
};
inline llvm::Value *DtoRVal(DValue *v) { return v->getRVal()->val; }
llvm::Value *DtoLVal(DValue *v);
#endif // LDC_GEN_DVALUE_H

View file

@ -1866,13 +1866,3 @@ DValue *makeVarDValue(Type *type, VarDeclaration *vd, llvm::Value *storage) {
return new DLValue(type, val);
}
LLValue *DtoRVal(DValue *v) { return v->getRVal(); }
LLValue *DtoLVal(DValue *v) {
auto lval = v->isLVal();
assert(lval);
return lval->getLVal();
}
LLValue *DtoRVal(Expression *e) { return DtoRVal(toElem(e)); }
LLValue *DtoLVal(Expression *e) { return DtoLVal(toElem(e)); }

View file

@ -129,13 +129,13 @@ LLConstant *DtoConstExpInit(Loc &loc, Type *targetType, Expression *exp);
LLConstant *DtoTypeInfoOf(Type *ty, bool base = true);
// binary operations
DValue *DtoBinAdd(DValue *lhs, DValue *rhs);
DValue *DtoBinSub(DValue *lhs, DValue *rhs);
DImValue *DtoBinAdd(DRValue *lhs, DRValue *rhs);
DImValue *DtoBinSub(DRValue *lhs, DRValue *rhs);
// these binops need an explicit result type to handling
// to give 'ifloat op float' and 'float op ifloat' the correct type
DValue *DtoBinMul(Type *resulttype, DValue *lhs, DValue *rhs);
DValue *DtoBinDiv(Type *resulttype, DValue *lhs, DValue *rhs);
DValue *DtoBinRem(Type *resulttype, DValue *lhs, DValue *rhs);
DImValue *DtoBinMul(Type *resulttype, DRValue *lhs, DRValue *rhs);
DImValue *DtoBinDiv(Type *resulttype, DRValue *lhs, DRValue *rhs);
DImValue *DtoBinRem(Type *resulttype, DRValue *lhs, DRValue *rhs);
LLValue *DtoBinNumericEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
@ -280,10 +280,8 @@ DValue *toElem(Expression *e, bool tryGetLvalue);
DValue *toElemDtor(Expression *e);
LLConstant *toConstElem(Expression *e, IRState *p);
llvm::Value *DtoRVal(DValue *v);
llvm::Value *DtoRVal(Expression *e);
llvm::Value *DtoLVal(DValue *v);
llvm::Value *DtoLVal(Expression *e);
inline llvm::Value *DtoRVal(Expression *e) { return DtoRVal(toElem(e)); }
inline llvm::Value *DtoLVal(Expression *e) { return DtoLVal(toElem(e)); }
/// Creates a DLValue for the given VarDeclaration.
///

View file

@ -165,7 +165,7 @@ static void write_struct_literal(Loc loc, LLValue *mem, StructDeclaration *sd,
DtoAssign(loc, &field, val, TOKconstruct, true);
if (expr && expr->isLvalue()) {
callPostblit(loc, expr, field.getLVal());
callPostblit(loc, expr, DtoLVal(&field));
}
// Also zero out padding bytes counted as being part of the type in DMD
@ -776,7 +776,7 @@ public:
auto &PGO = gIR->func()->pgo;
PGO.setCurrentStmt(e);
DValue *l = toElem(e->e1);
DRValue *l = toElem(e->e1)->getRVal();
Type *t = e->type->toBasetype();
Type *e1type = e->e1->type->toBasetype();
@ -788,9 +788,9 @@ public:
Logger::println("Adding integer to pointer");
result = emitPointerOffset(p, e->loc, l, e->e2, false, e->type);
} else if (t->iscomplex()) {
result = DtoComplexAdd(e->loc, e->type, l, toElem(e->e2));
result = DtoComplexAdd(e->loc, e->type, l, toElem(e->e2)->getRVal());
} else {
result = DtoBinAdd(l, toElem(e->e2));
result = DtoBinAdd(l, toElem(e->e2)->getRVal());
}
}
@ -802,7 +802,7 @@ public:
auto &PGO = gIR->func()->pgo;
PGO.setCurrentStmt(e);
DValue *l = toElem(e->e1);
DRValue *l = toElem(e->e1)->getRVal();
Type *t = e->type->toBasetype();
Type *t1 = e->e1->type->toBasetype();
@ -825,9 +825,9 @@ public:
Logger::println("Subtracting integer from pointer");
result = emitPointerOffset(p, e->loc, l, e->e2, true, e->type);
} else if (t->iscomplex()) {
result = DtoComplexSub(e->loc, e->type, l, toElem(e->e2));
result = DtoComplexSub(e->loc, e->type, l, toElem(e->e2)->getRVal());
} else {
result = DtoBinSub(l, toElem(e->e2));
result = DtoBinSub(l, toElem(e->e2)->getRVal());
}
}
@ -841,8 +841,8 @@ public:
auto &PGO = gIR->func()->pgo;
PGO.setCurrentStmt(e);
DValue *l = toElem(e->e1);
DValue *r = toElem(e->e2);
DRValue *l = toElem(e->e1)->getRVal();
DRValue *r = toElem(e->e2)->getRVal();
errorOnIllegalArrayOp(e, e->e1, e->e2);
@ -863,8 +863,8 @@ public:
auto &PGO = gIR->func()->pgo;
PGO.setCurrentStmt(e);
DValue *l = toElem(e->e1);
DValue *r = toElem(e->e2);
DRValue *l = toElem(e->e1)->getRVal();
DRValue *r = toElem(e->e2)->getRVal();
errorOnIllegalArrayOp(e, e->e1, e->e2);
@ -885,8 +885,8 @@ public:
auto &PGO = gIR->func()->pgo;
PGO.setCurrentStmt(e);
DValue *l = toElem(e->e1);
DValue *r = toElem(e->e2);
DRValue *l = toElem(e->e1)->getRVal();
DRValue *r = toElem(e->e2)->getRVal();
errorOnIllegalArrayOp(e, e->e1, e->e2);
@ -2418,14 +2418,14 @@ public:
e->type->toChars());
LOG_SCOPE;
DValue *l = toElem(e->e1);
DRValue *dval = toElem(e->e1)->getRVal();
if (e->type->iscomplex()) {
result = DtoComplexNeg(e->loc, e->type, l);
result = DtoComplexNeg(e->loc, e->type, dval);
return;
}
LLValue *val = DtoRVal(l);
LLValue *val = DtoRVal(dval);
if (e->type->isintegral()) {
val = p->ir->CreateNeg(val, "negval");