Index: src/IceTargetLoweringX86BaseImpl.h |
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h |
index a277db23adc70e92847a998e9dd6ac8e9e1a6454..0ac63b8b912240ccd15fc8ca1c188d12e2efb9a4 100644 |
--- a/src/IceTargetLoweringX86BaseImpl.h |
+++ b/src/IceTargetLoweringX86BaseImpl.h |
@@ -1164,13 +1164,14 @@ Operand *TargetX86Base<Machine>::loOperand(Operand *Operand) { |
Operand->getType() == IceType_f64); |
if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) |
return Operand; |
- if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { |
+ if (auto *Var = llvm::dyn_cast<Variable>(Operand)) { |
split64(Var); |
return Var->getLo(); |
} |
- if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { |
- ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>( |
+ if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { |
+ auto *ConstInt = llvm::dyn_cast<ConstantInteger32>( |
Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue()))); |
+ // Check if we need to blind/pool the constant. |
return legalize(ConstInt); |
} |
if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) { |
@@ -1192,25 +1193,23 @@ Operand *TargetX86Base<Machine>::hiOperand(Operand *Operand) { |
Operand->getType() == IceType_f64); |
if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64) |
return Operand; |
- if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { |
+ if (auto *Var = llvm::dyn_cast<Variable>(Operand)) { |
split64(Var); |
return Var->getHi(); |
} |
- if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { |
- ConstantInteger32 *ConstInt = llvm::dyn_cast<ConstantInteger32>( |
+ if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { |
+ auto *ConstInt = llvm::dyn_cast<ConstantInteger32>( |
Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue() >> 32))); |
- // check if we need to blind/pool the constant |
+ // Check if we need to blind/pool the constant. |
return legalize(ConstInt); |
} |
if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) { |
Constant *Offset = Mem->getOffset(); |
if (Offset == nullptr) { |
Offset = Ctx->getConstantInt32(4); |
- } else if (ConstantInteger32 *IntOffset = |
- llvm::dyn_cast<ConstantInteger32>(Offset)) { |
+ } else if (auto *IntOffset = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
Offset = Ctx->getConstantInt32(4 + IntOffset->getValue()); |
- } else if (ConstantRelocatable *SymOffset = |
- llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
+ } else if (auto *SymOffset = llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
assert(!Utils::WouldOverflowAdd(SymOffset->getOffset(), 4)); |
Offset = |
Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(), |
@@ -2453,7 +2452,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) { |
_pand(T, OneMask); |
_movp(Dest, T); |
} else { |
- Operand *Src0 = Inst->getSrc(0); |
+ Operand *Src0 = legalizeUndef(Inst->getSrc(0)); |
if (Src0->getType() == IceType_i64) |
Src0 = loOperand(Src0); |
Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
@@ -3261,9 +3260,9 @@ void TargetX86Base<Machine>::lowerIntrinsicCall( |
return; |
} |
Variable *DestPrev = Instr->getDest(); |
- Operand *PtrToMem = Instr->getArg(0); |
- Operand *Expected = Instr->getArg(1); |
- Operand *Desired = Instr->getArg(2); |
+ Operand *PtrToMem = legalize(Instr->getArg(0)); |
+ Operand *Expected = legalize(Instr->getArg(1)); |
+ Operand *Desired = legalize(Instr->getArg(2)); |
if (tryOptimizedCmpxchgCmpBr(DestPrev, PtrToMem, Expected, Desired)) |
return; |
lowerAtomicCmpxchg(DestPrev, PtrToMem, Expected, Desired); |
@@ -3397,6 +3396,7 @@ void TargetX86Base<Machine>::lowerIntrinsicCall( |
// In 32-bit mode, bswap only works on 32-bit arguments, and the |
// argument must be a register. Use rotate left for 16-bit bswap. |
if (Val->getType() == IceType_i64) { |
+ Val = legalizeUndef(Val); |
Variable *T_Lo = legalizeToVar(loOperand(Val)); |
Variable *T_Hi = legalizeToVar(hiOperand(Val)); |
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
@@ -3411,9 +3411,9 @@ void TargetX86Base<Machine>::lowerIntrinsicCall( |
_mov(Dest, T); |
} else { |
assert(Val->getType() == IceType_i16); |
- Val = legalize(Val); |
Constant *Eight = Ctx->getConstantInt16(8); |
Variable *T = nullptr; |
+ Val = legalize(Val); |
_mov(T, Val); |
_rol(T, Eight); |
_mov(Dest, T); |
@@ -4411,6 +4411,8 @@ void TargetX86Base<Machine>::lowerSelect(const InstSelect *Inst) { |
Cond = InstX86Base<Machine>::getOppositeCondition(Cond); |
} |
if (DestTy == IceType_i64) { |
+ SrcT = legalizeUndef(SrcT); |
+ SrcF = legalizeUndef(SrcF); |
// Set the low portion. |
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
Variable *TLo = nullptr; |
@@ -4448,7 +4450,7 @@ void TargetX86Base<Machine>::lowerStore(const InstStore *Inst) { |
Type Ty = NewAddr->getType(); |
if (Ty == IceType_i64) { |
- Value = legalize(Value); |
+ Value = legalizeUndef(Value); |
Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm); |
Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm); |
_store(ValueHi, |
@@ -4497,7 +4499,7 @@ void TargetX86Base<Machine>::lowerSwitch(const InstSwitch *Inst) { |
Operand *Src0 = Inst->getComparison(); |
SizeT NumCases = Inst->getNumCases(); |
if (Src0->getType() == IceType_i64) { |
- Src0 = legalize(Src0); // get Base/Index into physical registers |
+ Src0 = legalizeUndef(Src0); |
Operand *Src0Lo = loOperand(Src0); |
Operand *Src0Hi = hiOperand(Src0); |
if (NumCases >= 2) { |
@@ -4613,6 +4615,7 @@ void TargetX86Base<Machine>::lowerRMW( |
Type Ty = Src->getType(); |
typename Traits::X86OperandMem *Addr = formMemoryOperand(RMW->getAddr(), Ty); |
if (Ty == IceType_i64) { |
+ Src = legalizeUndef(Src); |
Operand *SrcLo = legalize(loOperand(Src), Legal_Reg | Legal_Imm); |
Operand *SrcHi = legalize(hiOperand(Src), Legal_Reg | Legal_Imm); |
typename Traits::X86OperandMem *AddrLo = |
@@ -4708,8 +4711,7 @@ template <class Machine> void TargetX86Base<Machine>::prelowerPhis() { |
for (SizeT I = 0; I < Phi->getSrcSize(); ++I) { |
Operand *Src = Phi->getSrc(I); |
CfgNode *Label = Phi->getLabel(I); |
- if (llvm::isa<ConstantUndef>(Src)) |
- Src = Ctx->getConstantZero(Dest->getType()); |
+ Src = legalizeUndef(Src); |
PhiLo->addArgument(loOperand(Src), Label); |
PhiHi->addArgument(hiOperand(Src), Label); |
} |
@@ -4791,22 +4793,18 @@ void TargetX86Base<Machine>::lowerPhiAssignments( |
auto Assign = llvm::dyn_cast<InstAssign>(&I); |
Variable *Dest = Assign->getDest(); |
- // If the source operand is ConstantUndef, do not legalize it. |
- // In function test_split_undef_int_vec, the advanced phi |
- // lowering process will find an assignment of undefined |
- // vector. This vector, as the Src here, will crash if it |
- // go through legalize(). legalize() will create new variable |
- // with makeVectorOfZeros(), but this new variable will be |
- // assigned a stack slot. This will fail the assertion in |
- // IceInstX8632.cpp:789, as XmmEmitterRegOp() complain: |
- // Var->hasReg() fails. Note this failure is irrelevant to |
- // randomization or pooling of constants. |
- // So, we do not call legalize() to add pool label for the |
- // src operands of phi assignment instructions. |
- // Instead, we manually add pool label for constant float and |
- // constant double values here. |
- // Note going through legalize() does not affect the testing |
- // results of SPEC2K and xtests. |
+ // If the source operand is ConstantUndef, do not legalize it. In function |
+ // test_split_undef_int_vec, the advanced phi lowering process will find an |
+ // assignment of undefined vector. This vector, as the Src here, will crash |
+ // if it go through legalize(). legalize() will create a new variable with |
+ // makeVectorOfZeros(), but this new variable will be assigned a stack |
+ // slot. This will fail with pxor(Var, Var) because it is an illegal |
+ // instruction form. Note this failure is irrelevant to randomization or |
+ // pooling of constants. So, we do not call legalize() to add pool label |
+ // for the src operands of phi assignment instructions. Instead, we |
+ // manually add pool label for constant float and constant double values |
+ // here. Note going through legalize() does not affect the testing results |
+ // of SPEC2K and xtests. |
Operand *Src = Assign->getSrc(0); |
if (!llvm::isa<ConstantUndef>(Assign->getSrc(0))) { |
Src = legalize(Src); |
@@ -5029,21 +5027,10 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed, |
} |
if (auto *Const = llvm::dyn_cast<Constant>(From)) { |
if (llvm::isa<ConstantUndef>(Const)) { |
- // Lower undefs to zero. Another option is to lower undefs to an |
- // uninitialized register; however, using an uninitialized register |
- // results in less predictable code. |
- // |
- // If in the future the implementation is changed to lower undef |
- // values to uninitialized registers, a FakeDef will be needed: |
- // Context.insert(InstFakeDef::create(Func, Reg)); |
- // This is in order to ensure that the live range of Reg is not |
- // overestimated. If the constant being lowered is a 64 bit value, |
- // then the result should be split and the lo and hi components will |
- // need to go in uninitialized registers. |
+ From = legalizeUndef(Const, RegNum); |
if (isVectorType(Ty)) |
- return makeVectorOfZeros(Ty, RegNum); |
- Const = Ctx->getConstantZero(Ty); |
- From = Const; |
+ return From; |
+ Const = llvm::cast<Constant>(From); |
} |
// There should be no constants of vector type (other than undef). |
assert(!isVectorType(Ty)); |
@@ -5105,6 +5092,29 @@ Variable *TargetX86Base<Machine>::legalizeToVar(Operand *From, int32_t RegNum) { |
return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
} |
+/// Legalize undef values to concrete values. |
+template <class Machine> |
+Operand *TargetX86Base<Machine>::legalizeUndef(Operand *From, int32_t RegNum) { |
+ Type Ty = From->getType(); |
+ if (llvm::isa<ConstantUndef>(From)) { |
+ // Lower undefs to zero. Another option is to lower undefs to an |
+ // uninitialized register; however, using an uninitialized register |
+ // results in less predictable code. |
+ // |
+ // If in the future the implementation is changed to lower undef |
+ // values to uninitialized registers, a FakeDef will be needed: |
+ // Context.insert(InstFakeDef::create(Func, Reg)); |
+ // This is in order to ensure that the live range of Reg is not |
+ // overestimated. If the constant being lowered is a 64 bit value, |
+ // then the result should be split and the lo and hi components will |
+ // need to go in uninitialized registers. |
+ if (isVectorType(Ty)) |
+ return makeVectorOfZeros(Ty, RegNum); |
+ return Ctx->getConstantZero(Ty); |
+ } |
+ return From; |
+} |
+ |
/// For the cmp instruction, if Src1 is an immediate, or known to be a |
/// physical register, we can allow Src0 to be a memory operand. |
/// Otherwise, Src0 must be copied into a physical register. |
@@ -5117,7 +5127,7 @@ Operand *TargetX86Base<Machine>::legalizeSrc0ForCmp(Operand *Src0, |
bool IsSrc1ImmOrReg = false; |
if (llvm::isa<Constant>(Src1)) { |
IsSrc1ImmOrReg = true; |
- } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) { |
+ } else if (auto *Var = llvm::dyn_cast<Variable>(Src1)) { |
if (Var->hasReg()) |
IsSrc1ImmOrReg = true; |
} |
@@ -5141,7 +5151,7 @@ TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd, Type Ty, |
// the constant offset, we will work on the whole memory |
// operand later as one entity later, this save one instruction. |
// By turning blinding and pooling off, we guarantee |
- // legalize(Offset) will return a constant*. |
+ // legalize(Offset) will return a Constant*. |
{ |
BoolFlagSaver B(RandomizationPoolingPaused, true); |
@@ -5357,8 +5367,8 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate( |
MemOperand->getShift(), |
MemOperand->getSegmentRegister()); |
- // Label this memory operand as randomize, so we won't randomize it |
- // again in case we call legalize() mutiple times on this memory |
+ // Label this memory operand as randomized, so we won't randomize it |
+ // again in case we call legalize() multiple times on this memory |
// operand. |
NewMemOperand->setRandomized(true); |
return NewMemOperand; |