Commit bc004630 by Jan Voung

Split ConstantInteger into ConstantInteger32 and ConstantInteger64.

In many cases, we expect a constant to be 32-bits or less. This simplifies range checking for x86 memory operand displacements (can only be 32-bit), or immediates in instructions (also 32-bit), since we only store 32-bits (so it trivially fits in 32-bits). Checks for whether a constant fits in 8-bits can be done on the 32-bit value instead of the 64-bit value. When TargetLowering sees a 64-bit immediate as an operand on a 64-bit instruction, it should have split the 64-bit immediate into a 32-bit loOperand(), and a 32-bit hiOperand(). So what's left for the Emit pass should be 32-bit constants. Other places which work with constants: - intrinsic operands (the ABI only allows i32 params for atomic mem order, or atomic is lock free byte-size, or the longjmp param). - addressing mode optimization (gep expansion should be working with i32 constants). - insertelement, and extractelement constant indices (bitcode reader restricts the type of the index to be i32 also). I guess now you may end up with multiple copies of what may be the "same" constant (i64 0 vs i32 0). BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/569033002
parent 97501839
......@@ -102,8 +102,12 @@ public:
return Ctx->getConstantSym(convertToIceType(GV->getType()), 0,
GV->getName());
} else if (const ConstantInt *CI = dyn_cast<ConstantInt>(Const)) {
return Ctx->getConstantInt(convertToIceType(CI->getType()),
CI->getSExtValue());
Ice::Type Ty = convertToIceType(CI->getType());
if (Ty == Ice::IceType_i64) {
return Ctx->getConstantInt64(Ty, CI->getSExtValue());
} else {
return Ctx->getConstantInt32(Ty, CI->getSExtValue());
}
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Const)) {
Ice::Type Type = convertToIceType(CFP->getType());
if (Type == Ice::IceType_f32)
......
......@@ -21,6 +21,7 @@
#include <cassert>
#include <cstdio> // snprintf
#include <functional> // std::less
#include <limits>
#include <list>
#include <map>
#include <set>
......@@ -128,6 +129,11 @@ private:
Timer &operator=(const Timer &) LLVM_DELETED_FUNCTION;
};
template <typename T> bool WouldOverflowAdd(T X, T Y) {
return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) ||
(X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y)));
}
} // end of namespace Ice
#endif // SUBZERO_SRC_ICEDEFS_H
......@@ -109,7 +109,8 @@ public:
ConstantPool() {}
TypePool<float, ConstantFloat, true> Floats;
TypePool<double, ConstantDouble, true> Doubles;
TypePool<uint64_t, ConstantInteger> Integers;
TypePool<uint32_t, ConstantInteger32> Integers32;
TypePool<uint64_t, ConstantInteger64> Integers64;
TypePool<RelocatableTuple, ConstantRelocatable> Relocatables;
UndefPool Undefs;
};
......@@ -289,10 +290,15 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
GlobalContext::~GlobalContext() {}
Constant *GlobalContext::getConstantInt(Type Ty, uint64_t ConstantInt64) {
Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) {
assert(Ty == IceType_i64);
return ConstPool->Integers64.getOrAdd(this, Ty, ConstantInt64);
}
Constant *GlobalContext::getConstantInt32(Type Ty, uint32_t ConstantInt32) {
if (Ty == IceType_i1)
ConstantInt64 &= UINT64_C(1);
return ConstPool->Integers.getOrAdd(this, Ty, ConstantInt64);
ConstantInt32 &= UINT32_C(1);
return ConstPool->Integers32.getOrAdd(this, Ty, ConstantInt32);
}
Constant *GlobalContext::getConstantFloat(float ConstantFloat) {
......@@ -320,8 +326,9 @@ Constant *GlobalContext::getConstantZero(Type Ty) {
case IceType_i8:
case IceType_i16:
case IceType_i32:
return getConstantInt32(Ty, 0);
case IceType_i64:
return getConstantInt(Ty, 0);
return getConstantInt64(Ty, 0);
case IceType_f32:
return getConstantFloat(0);
case IceType_f64:
......@@ -351,8 +358,9 @@ ConstantList GlobalContext::getConstantPool(Type Ty) const {
case IceType_i8:
case IceType_i16:
case IceType_i32:
return ConstPool->Integers32.getConstantPool();
case IceType_i64:
return ConstPool->Integers.getConstantPool();
return ConstPool->Integers64.getConstantPool();
case IceType_f32:
return ConstPool->Floats.getConstantPool();
case IceType_f64:
......
......@@ -75,7 +75,8 @@ public:
// Manage Constants.
// getConstant*() functions are not const because they might add
// something to the constant pool.
Constant *getConstantInt(Type Ty, uint64_t ConstantInt64);
Constant *getConstantInt32(Type Ty, uint32_t ConstantInt32);
Constant *getConstantInt64(Type Ty, uint64_t ConstantInt64);
Constant *getConstantFloat(float Value);
Constant *getConstantDouble(double Value);
// Returns a symbolic constant.
......
......@@ -1383,9 +1383,12 @@ void OperandX8632Mem::emit(const Cfg *Func) const {
bool OffsetIsNegative = false;
if (Offset == NULL) {
OffsetIsZero = true;
} else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) {
} else if (ConstantInteger32 *CI =
llvm::dyn_cast<ConstantInteger32>(Offset)) {
OffsetIsZero = (CI->getValue() == 0);
OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0);
OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
} else {
assert(llvm::isa<ConstantRelocatable>(Offset));
}
if (Dumped) {
if (!OffsetIsZero) { // Suppress if Offset is known to be 0
......@@ -1430,9 +1433,12 @@ void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
bool OffsetIsNegative = false;
if (Offset == NULL) {
OffsetIsZero = true;
} else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) {
} else if (ConstantInteger32 *CI =
llvm::dyn_cast<ConstantInteger32>(Offset)) {
OffsetIsZero = (CI->getValue() == 0);
OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0);
OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
} else {
assert(llvm::isa<ConstantRelocatable>(Offset));
}
if (Dumped) {
if (!OffsetIsZero) { // Suppress if Offset is known to be 0
......
......@@ -27,7 +27,8 @@ class Operand {
public:
enum OperandKind {
kConst_Base,
kConstInteger,
kConstInteger32,
kConstInteger64,
kConstFloat,
kConstDouble,
kConstRelocatable,
......@@ -152,15 +153,21 @@ private:
const T Value;
};
typedef ConstantPrimitive<uint64_t, Operand::kConstInteger> ConstantInteger;
typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32;
typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64;
typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat;
typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble;
template <> inline void ConstantInteger::dump(const Cfg *, Ostream &Str) const {
template <> inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const {
if (getType() == IceType_i1)
Str << (getValue() ? "true" : "false");
else
Str << static_cast<int64_t>(getValue());
Str << static_cast<int32_t>(getValue());
}
template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const {
assert(getType() == IceType_i64);
Str << static_cast<int64_t>(getValue());
}
// RelocatableTuple bundles the parameters that are used to
......
......@@ -600,7 +600,7 @@ void TargetX8632::finishArgumentLowering(Variable *Arg, Variable *FramePtr,
assert(Ty != IceType_i64);
OperandX8632Mem *Mem = OperandX8632Mem::create(
Func, Ty, FramePtr,
Ctx->getConstantInt(IceType_i32, Arg->getStackOffset()));
Ctx->getConstantInt32(IceType_i32, Arg->getStackOffset()));
if (isVectorType(Arg->getType())) {
_movp(Arg, Mem);
} else {
......@@ -799,7 +799,7 @@ void TargetX8632::addProlog(CfgNode *Node) {
// Generate "sub esp, SpillAreaSizeBytes"
if (SpillAreaSizeBytes)
_sub(getPhysicalRegister(Reg_esp),
Ctx->getConstantInt(IceType_i32, SpillAreaSizeBytes));
Ctx->getConstantInt32(IceType_i32, SpillAreaSizeBytes));
resetStackAdjustment();
......@@ -915,7 +915,7 @@ void TargetX8632::addEpilog(CfgNode *Node) {
} else {
// add esp, SpillAreaSizeBytes
if (SpillAreaSizeBytes)
_add(esp, Ctx->getConstantInt(IceType_i32, SpillAreaSizeBytes));
_add(esp, Ctx->getConstantInt32(IceType_i32, SpillAreaSizeBytes));
}
// Add pop instructions for preserved registers.
......@@ -1033,9 +1033,9 @@ Operand *TargetX8632::loOperand(Operand *Operand) {
split64(Var);
return Var->getLo();
}
if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) {
uint64_t Mask = (1ull << 32) - 1;
return Ctx->getConstantInt(IceType_i32, Const->getValue() & Mask);
if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
return Ctx->getConstantInt32(IceType_i32,
static_cast<uint32_t>(Const->getValue()));
}
if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(),
......@@ -1054,16 +1054,17 @@ Operand *TargetX8632::hiOperand(Operand *Operand) {
split64(Var);
return Var->getHi();
}
if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) {
return Ctx->getConstantInt(IceType_i32, Const->getValue() >> 32);
if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
return Ctx->getConstantInt32(
IceType_i32, static_cast<uint32_t>(Const->getValue() >> 32));
}
if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
Constant *Offset = Mem->getOffset();
if (Offset == NULL)
Offset = Ctx->getConstantInt(IceType_i32, 4);
else if (ConstantInteger *IntOffset =
llvm::dyn_cast<ConstantInteger>(Offset)) {
Offset = Ctx->getConstantInt(IceType_i32, 4 + IntOffset->getValue());
Offset = Ctx->getConstantInt32(IceType_i32, 4);
else if (ConstantInteger32 *IntOffset =
llvm::dyn_cast<ConstantInteger32>(Offset)) {
Offset = Ctx->getConstantInt32(IceType_i32, 4 + IntOffset->getValue());
} else if (ConstantRelocatable *SymOffset =
llvm::dyn_cast<ConstantRelocatable>(Offset)) {
Offset = Ctx->getConstantSym(IceType_i32, 4 + SymOffset->getOffset(),
......@@ -1131,20 +1132,20 @@ void TargetX8632::lowerAlloca(const InstAlloca *Inst) {
uint32_t Alignment = std::max(AlignmentParam, X86_STACK_ALIGNMENT_BYTES);
if (Alignment > X86_STACK_ALIGNMENT_BYTES) {
_and(esp, Ctx->getConstantInt(IceType_i32, -Alignment));
_and(esp, Ctx->getConstantInt32(IceType_i32, -Alignment));
}
if (ConstantInteger *ConstantTotalSize =
llvm::dyn_cast<ConstantInteger>(TotalSize)) {
if (ConstantInteger32 *ConstantTotalSize =
llvm::dyn_cast<ConstantInteger32>(TotalSize)) {
uint32_t Value = ConstantTotalSize->getValue();
Value = applyAlignment(Value, Alignment);
_sub(esp, Ctx->getConstantInt(IceType_i32, Value));
_sub(esp, Ctx->getConstantInt32(IceType_i32, Value));
} else {
// Non-constant sizes need to be adjusted to the next highest
// multiple of the required alignment at runtime.
Variable *T = makeReg(IceType_i32);
_mov(T, TotalSize);
_add(T, Ctx->getConstantInt(IceType_i32, Alignment - 1));
_and(T, Ctx->getConstantInt(IceType_i32, -Alignment));
_add(T, Ctx->getConstantInt32(IceType_i32, Alignment - 1));
_and(T, Ctx->getConstantInt32(IceType_i32, -Alignment));
_sub(esp, T);
}
_mov(Dest, esp);
......@@ -1254,7 +1255,7 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
// a.lo = t2
// a.hi = t3
Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL;
Constant *BitTest = Ctx->getConstantInt(IceType_i32, 0x20);
Constant *BitTest = Ctx->getConstantInt32(IceType_i32, 0x20);
Constant *Zero = Ctx->getConstantZero(IceType_i32);
InstX8632Label *Label = InstX8632Label::create(Func, this);
_mov(T_1, Src1Lo, Reg_ecx);
......@@ -1290,7 +1291,7 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
// a.lo = t2
// a.hi = t3
Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL;
Constant *BitTest = Ctx->getConstantInt(IceType_i32, 0x20);
Constant *BitTest = Ctx->getConstantInt32(IceType_i32, 0x20);
Constant *Zero = Ctx->getConstantZero(IceType_i32);
InstX8632Label *Label = InstX8632Label::create(Func, this);
_mov(T_1, Src1Lo, Reg_ecx);
......@@ -1326,8 +1327,8 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
// a.lo = t2
// a.hi = t3
Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL;
Constant *BitTest = Ctx->getConstantInt(IceType_i32, 0x20);
Constant *SignExtend = Ctx->getConstantInt(IceType_i32, 0x1f);
Constant *BitTest = Ctx->getConstantInt32(IceType_i32, 0x20);
Constant *SignExtend = Ctx->getConstantInt32(IceType_i32, 0x1f);
InstX8632Label *Label = InstX8632Label::create(Func, this);
_mov(T_1, Src1Lo, Reg_ecx);
_mov(T_2, Src0Lo);
......@@ -1448,7 +1449,7 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
// Mask that directs pshufd to create a vector with entries
// Src[1, 0, 3, 0]
const unsigned Constant1030 = 0x31;
Constant *Mask1030 = Ctx->getConstantInt(IceType_i8, Constant1030);
Constant *Mask1030 = Ctx->getConstantInt32(IceType_i8, Constant1030);
// Mask that directs shufps to create a vector with entries
// Dest[0, 2], Src[0, 2]
const unsigned Mask0202 = 0x88;
......@@ -1464,8 +1465,8 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
_pshufd(T3, Src1, Mask1030);
_pmuludq(T1, Src1);
_pmuludq(T2, T3);
_shufps(T1, T2, Ctx->getConstantInt(IceType_i8, Mask0202));
_pshufd(T4, T1, Ctx->getConstantInt(IceType_i8, Mask0213));
_shufps(T1, T2, Ctx->getConstantInt32(IceType_i8, Mask0202));
_pshufd(T4, T1, Ctx->getConstantInt32(IceType_i8, Mask0213));
_movp(Dest, T4);
} else {
assert(Dest->getType() == IceType_v16i8);
......@@ -1758,7 +1759,8 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);
}
Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp);
Constant *Loc = Ctx->getConstantInt(IceType_i32, ParameterAreaSizeBytes);
Constant *Loc =
Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes);
StackArgLocations.push_back(OperandX8632Mem::create(Func, Ty, esp, Loc));
ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType());
}
......@@ -1855,7 +1857,7 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
// of resetting the stack offset during emission.
if (ParameterAreaSizeBytes) {
Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp);
_add(esp, Ctx->getConstantInt(IceType_i32, ParameterAreaSizeBytes));
_add(esp, Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes));
}
// Insert a register-kill pseudo instruction.
......@@ -1940,7 +1942,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// width = width(elty) - 1; dest = (src << width) >> width
SizeT ShiftAmount =
X86_CHAR_BIT * typeWidthInBytes(typeElementType(DestTy)) - 1;
Constant *ShiftConstant = Ctx->getConstantInt(IceType_i8, ShiftAmount);
Constant *ShiftConstant =
Ctx->getConstantInt32(IceType_i8, ShiftAmount);
Variable *T = makeReg(DestTy);
_movp(T, Src0RM);
_psll(T, ShiftConstant);
......@@ -1949,7 +1952,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
}
} else if (Dest->getType() == IceType_i64) {
// t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2
Constant *Shift = Ctx->getConstantInt(IceType_i32, 31);
Constant *Shift = Ctx->getConstantInt32(IceType_i32, 31);
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *T_Lo = makeReg(DestLo->getType());
......@@ -1975,7 +1978,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// sar t1, dst_bitwidth - 1
// dst = t1
size_t DestBits = X86_CHAR_BIT * typeWidthInBytes(Dest->getType());
Constant *ShiftAmount = Ctx->getConstantInt(IceType_i32, DestBits - 1);
Constant *ShiftAmount = Ctx->getConstantInt32(IceType_i32, DestBits - 1);
Variable *T = makeReg(Dest->getType());
if (typeWidthInBytes(Dest->getType()) <=
typeWidthInBytes(Src0RM->getType())) {
......@@ -2018,14 +2021,14 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
_movzx(Tmp, Src0RM);
}
if (Src0RM->getType() == IceType_i1) {
Constant *One = Ctx->getConstantInt(IceType_i32, 1);
Constant *One = Ctx->getConstantInt32(IceType_i32, 1);
_and(Tmp, One);
}
_mov(DestLo, Tmp);
_mov(DestHi, Zero);
} else if (Src0RM->getType() == IceType_i1) {
// t = Src0RM; t &= 1; Dest = t
Constant *One = Ctx->getConstantInt(IceType_i32, 1);
Constant *One = Ctx->getConstantInt32(IceType_i32, 1);
Variable *T = makeReg(IceType_i32);
_movzx(T, Src0RM);
_and(T, One);
......@@ -2057,7 +2060,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
Variable *T = NULL;
_mov(T, Src0RM);
if (Dest->getType() == IceType_i1)
_and(T, Ctx->getConstantInt(IceType_i1, 1));
_and(T, Ctx->getConstantInt32(IceType_i1, 1));
_mov(Dest, T);
}
break;
......@@ -2102,7 +2105,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
_cvtt(T_1, Src0RM);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types
if (Dest->getType() == IceType_i1)
_and(T_2, Ctx->getConstantInt(IceType_i1, 1));
_and(T_2, Ctx->getConstantInt32(IceType_i1, 1));
_mov(Dest, T_2);
T_2->setPreferredRegister(T_1, true);
}
......@@ -2139,7 +2142,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
_cvtt(T_1, Src0RM);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types
if (Dest->getType() == IceType_i1)
_and(T_2, Ctx->getConstantInt(IceType_i1, 1));
_and(T_2, Ctx->getConstantInt32(IceType_i1, 1));
_mov(Dest, T_2);
T_2->setPreferredRegister(T_1, true);
}
......@@ -2350,8 +2353,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
void TargetX8632::lowerExtractElement(const InstExtractElement *Inst) {
Operand *SourceVectNotLegalized = Inst->getSrc(0);
ConstantInteger *ElementIndex =
llvm::dyn_cast<ConstantInteger>(Inst->getSrc(1));
ConstantInteger32 *ElementIndex =
llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(1));
// Only constant indices are allowed in PNaCl IR.
assert(ElementIndex);
......@@ -2366,7 +2369,7 @@ void TargetX8632::lowerExtractElement(const InstExtractElement *Inst) {
Ty == IceType_v8i16 || Ty == IceType_v8i1 || InstructionSet >= SSE4_1;
if (CanUsePextr && Ty != IceType_v4f32) {
// Use pextrb, pextrw, or pextrd.
Constant *Mask = Ctx->getConstantInt(IceType_i8, Index);
Constant *Mask = Ctx->getConstantInt32(IceType_i8, Index);
Variable *SourceVectR = legalizeToVar(SourceVectNotLegalized);
_pextr(ExtractedElementR, SourceVectR, Mask);
} else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) {
......@@ -2375,7 +2378,7 @@ void TargetX8632::lowerExtractElement(const InstExtractElement *Inst) {
if (Index) {
// The shuffle only needs to occur if the element to be extracted
// is not at the lowest index.
Constant *Mask = Ctx->getConstantInt(IceType_i8, Index);
Constant *Mask = Ctx->getConstantInt32(IceType_i8, Index);
T = makeReg(Ty);
_pshufd(T, legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem), Mask);
} else {
......@@ -2514,7 +2517,7 @@ void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
_ucomiss(T, Src1RM);
}
Constant *Default =
Ctx->getConstantInt(IceType_i32, TableFcmp[Index].Default);
Ctx->getConstantInt32(IceType_i32, TableFcmp[Index].Default);
_mov(Dest, Default);
if (HasC1) {
InstX8632Label *Label = InstX8632Label::create(Func, this);
......@@ -2524,7 +2527,7 @@ void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
}
Context.insert(InstFakeUse::create(Func, Dest));
Constant *NonDefault =
Ctx->getConstantInt(IceType_i32, !TableFcmp[Index].Default);
Ctx->getConstantInt32(IceType_i32, !TableFcmp[Index].Default);
_mov(Dest, NonDefault);
Context.insert(Label);
}
......@@ -2665,7 +2668,7 @@ void TargetX8632::lowerIcmp(const InstIcmp *Inst) {
// a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1:
Constant *Zero = Ctx->getConstantZero(IceType_i32);
Constant *One = Ctx->getConstantInt(IceType_i32, 1);
Constant *One = Ctx->getConstantInt32(IceType_i32, 1);
if (Src0->getType() == IceType_i64) {
InstIcmp::ICond Condition = Inst->getCondition();
size_t Index = static_cast<size_t>(Condition);
......@@ -2716,8 +2719,8 @@ void TargetX8632::lowerIcmp(const InstIcmp *Inst) {
void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) {
Operand *SourceVectNotLegalized = Inst->getSrc(0);
Operand *ElementToInsertNotLegalized = Inst->getSrc(1);
ConstantInteger *ElementIndex =
llvm::dyn_cast<ConstantInteger>(Inst->getSrc(2));
ConstantInteger32 *ElementIndex =
llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(2));
// Only constant indices are allowed in PNaCl IR.
assert(ElementIndex);
unsigned Index = ElementIndex->getValue();
......@@ -2747,9 +2750,9 @@ void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) {
Variable *T = makeReg(Ty);
_movp(T, SourceVectRM);
if (Ty == IceType_v4f32)
_insertps(T, ElementRM, Ctx->getConstantInt(IceType_i8, Index << 4));
_insertps(T, ElementRM, Ctx->getConstantInt32(IceType_i8, Index << 4));
else
_pinsr(T, ElementRM, Ctx->getConstantInt(IceType_i8, Index));
_pinsr(T, ElementRM, Ctx->getConstantInt32(IceType_i8, Index));
_movp(Inst->getDest(), T);
} else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) {
// Use shufps or movss.
......@@ -2800,8 +2803,10 @@ void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) {
const unsigned char Mask1[3] = {0, 192, 128};
const unsigned char Mask2[3] = {227, 196, 52};
Constant *Mask1Constant = Ctx->getConstantInt(IceType_i8, Mask1[Index - 1]);
Constant *Mask2Constant = Ctx->getConstantInt(IceType_i8, Mask2[Index - 1]);
Constant *Mask1Constant =
Ctx->getConstantInt32(IceType_i8, Mask1[Index - 1]);
Constant *Mask2Constant =
Ctx->getConstantInt32(IceType_i8, Mask2[Index - 1]);
if (Index == 1) {
_shufps(ElementR, SourceVectRM, Mask1Constant);
......@@ -2841,12 +2846,12 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
switch (Instr->getIntrinsicInfo().ID) {
case Intrinsics::AtomicCmpxchg: {
if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger>(Instr->getArg(3))->getValue())) {
llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) {
Func->setError("Unexpected memory ordering (success) for AtomicCmpxchg");
return;
}
if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger>(Instr->getArg(4))->getValue())) {
llvm::cast<ConstantInteger32>(Instr->getArg(4))->getValue())) {
Func->setError("Unexpected memory ordering (failure) for AtomicCmpxchg");
return;
}
......@@ -2861,7 +2866,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
}
case Intrinsics::AtomicFence:
if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger>(Instr->getArg(0))->getValue())) {
llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicFence");
return;
}
......@@ -2879,7 +2884,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
// byte size, this opens up DCE opportunities.
Operand *ByteSize = Instr->getArg(0);
Variable *Dest = Instr->getDest();
if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(ByteSize)) {
if (ConstantInteger32 *CI = llvm::dyn_cast<ConstantInteger32>(ByteSize)) {
Constant *Result;
switch (CI->getValue()) {
default:
......@@ -2893,7 +2898,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
case 2:
case 4:
case 8:
Result = Ctx->getConstantInt(IceType_i32, 1);
Result = Ctx->getConstantInt32(IceType_i32, 1);
break;
}
_mov(Dest, Result);
......@@ -2907,7 +2912,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
// We require the memory address to be naturally aligned.
// Given that is the case, then normal loads are atomic.
if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger>(Instr->getArg(1))->getValue())) {
llvm::cast<ConstantInteger32>(Instr->getArg(1))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicLoad");
return;
}
......@@ -2940,18 +2945,18 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
}
case Intrinsics::AtomicRMW:
if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger>(Instr->getArg(3))->getValue())) {
llvm::cast<ConstantInteger32>(Instr->getArg(3))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicRMW");
return;
}
lowerAtomicRMW(Instr->getDest(),
static_cast<uint32_t>(llvm::cast<ConstantInteger>(
Instr->getArg(0))->getValue()),
static_cast<uint32_t>(llvm::cast<ConstantInteger32>(
Instr->getArg(0))->getValue()),
Instr->getArg(1), Instr->getArg(2));
return;
case Intrinsics::AtomicStore: {
if (!Intrinsics::VerifyMemoryOrder(
llvm::cast<ConstantInteger>(Instr->getArg(2))->getValue())) {
llvm::cast<ConstantInteger32>(Instr->getArg(2))->getValue())) {
Func->setError("Unexpected memory ordering for AtomicStore");
return;
}
......@@ -2999,7 +3004,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} else {
assert(Val->getType() == IceType_i16);
Val = legalize(Val);
Constant *Eight = Ctx->getConstantInt(IceType_i16, 8);
Constant *Eight = Ctx->getConstantInt32(IceType_i16, 8);
Variable *T = NULL;
_mov(T, Val);
_rol(T, Eight);
......@@ -3482,12 +3487,12 @@ void TargetX8632::lowerCountZeros(bool Cttz, Type Ty, Variable *Dest,
_bsr(T, FirstValRM);
}
Variable *T_Dest = makeReg(IceType_i32);
Constant *ThirtyTwo = Ctx->getConstantInt(IceType_i32, 32);
Constant *ThirtyOne = Ctx->getConstantInt(IceType_i32, 31);
Constant *ThirtyTwo = Ctx->getConstantInt32(IceType_i32, 32);
Constant *ThirtyOne = Ctx->getConstantInt32(IceType_i32, 31);
if (Cttz) {
_mov(T_Dest, ThirtyTwo);
} else {
Constant *SixtyThree = Ctx->getConstantInt(IceType_i32, 63);
Constant *SixtyThree = Ctx->getConstantInt32(IceType_i32, 63);
_mov(T_Dest, SixtyThree);
}
_cmov(T_Dest, T, InstX8632::Br_ne);
......@@ -3616,8 +3621,8 @@ bool matchShiftedIndex(Variable *&Index, uint16_t &Shift, const Inst *&Reason) {
if (const InstArithmetic *ArithInst =
llvm::dyn_cast<InstArithmetic>(IndexInst)) {
if (Variable *Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
if (ConstantInteger *Const =
llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1))) {
if (ConstantInteger32 *Const =
llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1))) {
if (ArithInst->getOp() == InstArithmetic::Mul &&
!Var->getIsMultidef() && Const->getType() == IceType_i32) {
uint64_t Mult = Const->getValue();
......@@ -3668,19 +3673,22 @@ bool matchOffsetBase(Variable *&Base, int32_t &Offset, const Inst *&Reason) {
return false;
bool IsAdd = ArithInst->getOp() == InstArithmetic::Add;
Variable *Var = NULL;
ConstantInteger *Const = NULL;
ConstantInteger32 *Const = NULL;
if (Variable *VariableOperand =
llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
Var = VariableOperand;
Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1));
Const = llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1));
} else if (IsAdd) {
Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(0));
Const = llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(0));
Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1));
}
if (Var == NULL || Const == NULL || Var->getIsMultidef())
return false;
int32_t MoreOffset = IsAdd ? Const->getValue() : -Const->getValue();
if (WouldOverflowAdd(Offset, MoreOffset))
return false;
Base = Var;
Offset += IsAdd ? Const->getValue() : -Const->getValue();
Offset += MoreOffset;
Reason = BaseInst;
return true;
}
......@@ -3812,7 +3820,7 @@ void TargetX8632::doAddressOptLoad() {
computeAddressOpt(Func, Inst, Base, Index, Shift, Offset);
if (Base && Addr != Base) {
Inst->setDeleted();
Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset);
Constant *OffsetOp = Ctx->getConstantInt32(IceType_i32, Offset);
Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index,
Shift, SegmentReg);
Context.insert(InstLoad::create(Func, Dest, Addr));
......@@ -3879,7 +3887,7 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) {
Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem);
Variable *xmm0 = makeReg(IceType_v4i32, Reg_xmm0);
_movp(xmm0, ConditionRM);
_psll(xmm0, Ctx->getConstantInt(IceType_i8, 31));
_psll(xmm0, Ctx->getConstantInt32(IceType_i8, 31));
_movp(T, SrcFRM);
_blendvps(T, SrcTRM, xmm0);
_movp(Dest, T);
......@@ -3994,7 +4002,7 @@ void TargetX8632::doAddressOptStore() {
computeAddressOpt(Func, Inst, Base, Index, Shift, Offset);
if (Base && Addr != Base) {
Inst->setDeleted();
Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset);
Constant *OffsetOp = Ctx->getConstantInt32(IceType_i32, Offset);
Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index,
Shift, SegmentReg);
Context.insert(InstStore::create(Func, Data, Addr));
......@@ -4014,7 +4022,7 @@ void TargetX8632::lowerSwitch(const InstSwitch *Inst) {
Src0 = legalize(Src0, Legal_Reg | Legal_Mem, true);
for (SizeT I = 0; I < NumCases; ++I) {
// TODO(stichnot): Correct lowering for IceType_i64.
Constant *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I));
Constant *Value = Ctx->getConstantInt32(IceType_i32, Inst->getValue(I));
_cmp(Src0, Value);
_br(InstX8632Br::Br_e, Inst->getLabel(I));
}
......@@ -4032,7 +4040,7 @@ void TargetX8632::scalarizeArithmetic(InstArithmetic::OpKind Kind,
Operand *T = Ctx->getConstantUndef(Ty);
for (SizeT I = 0; I < NumElements; ++I) {
Constant *Index = Ctx->getConstantInt(IceType_i32, I);
Constant *Index = Ctx->getConstantInt32(IceType_i32, I);
// Extract the next two inputs.
Variable *Op0 = Func->makeVariable(ElementTy, Context.getNode());
......@@ -4121,13 +4129,13 @@ Variable *TargetX8632::makeVectorOfHighOrderBits(Type Ty, int32_t RegNum) {
if (Ty == IceType_v4f32 || Ty == IceType_v4i32 || Ty == IceType_v8i16) {
Variable *Reg = makeVectorOfOnes(Ty, RegNum);
SizeT Shift = typeWidthInBytes(typeElementType(Ty)) * X86_CHAR_BIT - 1;
_psll(Reg, Ctx->getConstantInt(IceType_i8, Shift));
_psll(Reg, Ctx->getConstantInt32(IceType_i8, Shift));
return Reg;
} else {
// SSE has no left shift operation for vectors of 8 bit integers.
const uint32_t HIGH_ORDER_BITS_MASK = 0x80808080;
Constant *ConstantMask =
Ctx->getConstantInt(IceType_i32, HIGH_ORDER_BITS_MASK);
Ctx->getConstantInt32(IceType_i32, HIGH_ORDER_BITS_MASK);
Variable *Reg = makeReg(Ty, RegNum);
_movd(Reg, legalize(ConstantMask, Legal_Reg | Legal_Mem));
_pshufd(Reg, Reg, Ctx->getConstantZero(IceType_i8));
......@@ -4148,7 +4156,7 @@ OperandX8632Mem *TargetX8632::getMemoryOperandForStackSlot(Type Ty,
const Type PointerType = IceType_i32;
Variable *Loc = makeReg(PointerType);
_lea(Loc, Slot);
Constant *ConstantOffset = Ctx->getConstantInt(IceType_i32, Offset);
Constant *ConstantOffset = Ctx->getConstantInt32(IceType_i32, Offset);
return OperandX8632Mem::create(Func, Ty, Loc, ConstantOffset);
}
......@@ -4278,7 +4286,7 @@ OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) {
Constant *Offset = llvm::dyn_cast<Constant>(Operand);
assert(Base || Offset);
if (Offset) {
assert(llvm::isa<ConstantInteger>(Offset) ||
assert(llvm::isa<ConstantInteger32>(Offset) ||
llvm::isa<ConstantRelocatable>(Offset));
}
Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
......@@ -4402,9 +4410,13 @@ void TargetX8632::postLower() {
}
}
template <> void ConstantInteger::emit(GlobalContext *Ctx) const {
template <> void ConstantInteger32::emit(GlobalContext *Ctx) const {
Ostream &Str = Ctx->getStrEmit();
Str << (int64_t) getValue();
Str << (int32_t)getValue();
}
template <> void ConstantInteger64::emit(GlobalContext *) const {
llvm_unreachable("Not expecting to emit 64-bit integers");
}
template <> void ConstantFloat::emit(GlobalContext *Ctx) const {
......
......@@ -509,7 +509,8 @@ private:
virtual ~TargetGlobalInitX8632() {}
};
template <> void ConstantInteger::emit(GlobalContext *Ctx) const;
template <> void ConstantInteger32::emit(GlobalContext *Ctx) const;
template <> void ConstantInteger64::emit(GlobalContext *Ctx) const;
template <> void ConstantFloat::emit(GlobalContext *Ctx) const;
template <> void ConstantDouble::emit(GlobalContext *Ctx) const;
......
......@@ -1777,8 +1777,11 @@ void ConstantsParser::ProcessRecord() {
if (IntegerType *IType = dyn_cast<IntegerType>(
Context->convertToLLVMType(NextConstantType))) {
APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0]));
Ice::Constant *C =
getContext()->getConstantInt(NextConstantType, Value.getSExtValue());
Ice::Constant *C = (NextConstantType == Ice::IceType_i64)
? getContext()->getConstantInt64(
NextConstantType, Value.getSExtValue())
: getContext()->getConstantInt32(
NextConstantType, Value.getSExtValue());
FuncParser->setNextConstantID(C);
return;
}
......
......@@ -61,4 +61,66 @@ entry:
; CHECK: movss xmm0, dword ptr [eax + 8]
}
define float @address_mode_opt_chaining_overflow(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = add i32 2147483640, %arg.int
%addr2.int = add i32 %addr1.int, 2147483643
%addr2.ptr = inttoptr i32 %addr2.int to float*
%addr2.load = load float* %addr2.ptr, align 4
ret float %addr2.load
; CHECK-LABEL: address_mode_opt_chaining_overflow:
; CHECK: 2147483640
; CHECK: movss xmm0, dword ptr [{{.*}} + 2147483643]
}
define float @address_mode_opt_chaining_overflow_sub(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = sub i32 %arg.int, 2147483640
%addr2.int = sub i32 %addr1.int, 2147483643
%addr2.ptr = inttoptr i32 %addr2.int to float*
%addr2.load = load float* %addr2.ptr, align 4
ret float %addr2.load
; CHECK-LABEL: address_mode_opt_chaining_overflow_sub:
; CHECK: 2147483640
; CHECK: movss xmm0, dword ptr [{{.*}} - 2147483643]
}
define float @address_mode_opt_chaining_no_overflow(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = sub i32 %arg.int, 2147483640
%addr2.int = add i32 %addr1.int, 2147483643
%addr2.ptr = inttoptr i32 %addr2.int to float*
%addr2.load = load float* %addr2.ptr, align 4
ret float %addr2.load
; CHECK-LABEL: address_mode_opt_chaining_no_overflow:
; CHECK: movss xmm0, dword ptr [{{.*}} + 3]
}
define float @address_mode_opt_add_pos_min_int(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = add i32 %arg.int, 2147483648
%addr1.ptr = inttoptr i32 %addr1.int to float*
%addr1.load = load float* %addr1.ptr, align 4
ret float %addr1.load
; CHECK-LABEL: address_mode_opt_add_pos_min_int:
; CHECK: movss xmm0, dword ptr [{{.*}} - 2147483648]
}
define float @address_mode_opt_sub_min_int(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = sub i32 %arg.int, 2147483648
%addr1.ptr = inttoptr i32 %addr1.int to float*
%addr1.load = load float* %addr1.ptr, align 4
ret float %addr1.load
; CHECK-LABEL: address_mode_opt_sub_min_int:
; CHECK: movss xmm0, dword ptr [{{.*}} - 2147483648]
}
; ERRORS-NOT: ICE translation error
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment