Chromium Code Reviews| Index: src/IceTargetLoweringX86BaseImpl.h |
| diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h |
| index 8f372196779cc6b3c068655afb1ccd4ff3948165..b4c7a10760b292b3a90133f4b0dd3193ae74b490 100644 |
| --- a/src/IceTargetLoweringX86BaseImpl.h |
| +++ b/src/IceTargetLoweringX86BaseImpl.h |
| @@ -29,6 +29,7 @@ |
| #include "IceUtils.h" |
| #include "llvm/Support/MathExtras.h" |
| +#include <cmath> // signbit() |
| #include <stack> |
| namespace Ice { |
| @@ -1916,7 +1917,7 @@ void TargetX86Base<Machine>::lowerAssign(const InstAssign *Inst) { |
| // If Dest already has a physical register, then only basic legalization |
| // is needed, as the source operand can be a register, immediate, or |
| // memory. |
| - Src0Legal = legalize(Src0); |
| + Src0Legal = legalize(Src0, Legal_Reg, Dest->getRegNum()); |
| } else { |
| // If Dest could be a stack operand, then RI must be a physical register |
| // or a scalar integer immediate. |
| @@ -5307,6 +5308,34 @@ template <class Machine> void TargetX86Base<Machine>::prelowerPhis() { |
| this, Context.getNode(), Func); |
| } |
| +template <class Machine> |
| +Variable *TargetX86Base<Machine>::makeZeroedRegister(Type Ty, int32_t RegNum) { |
| + Variable *Reg = makeReg(Ty, RegNum); |
| + switch (Ty) { |
| + case IceType_i1: |
| + case IceType_i8: |
| + case IceType_i16: |
| + case IceType_i32: |
| + case IceType_i64: |
| + // Conservatively do "mov reg, 0" to avoid modifying FLAGS. |
| + _mov(Reg, Ctx->getConstantZero(Ty)); |
| + break; |
| + case IceType_f32: |
| + case IceType_f64: |
| + Context.insert(InstFakeDef::create(Func, Reg)); |
| + // TODO(stichnot): Use xorps/xorpd instead of pxor. |
| + _pxor(Reg, Reg); |
|
John
2015/11/13 21:51:20
What's the difference of pxor and xorp*?
Jim Stichnoth
2015/11/13 22:20:24
We were trying to figure that out. The Intel guys
|
| + break; |
| + default: |
| + // All vector types use the same pxor instruction. |
| + assert(isVectorType(Ty)); |
| + Context.insert(InstFakeDef::create(Func, Reg)); |
| + _pxor(Reg, Reg); |
| + break; |
| + } |
| + return Reg; |
| +} |
| + |
| // There is no support for loading or emitting vector constants, so the vector |
| // values returned from makeVectorOfZeros, makeVectorOfOnes, etc. are |
| // initialized with register operations. |
| @@ -5316,12 +5345,7 @@ template <class Machine> void TargetX86Base<Machine>::prelowerPhis() { |
| template <class Machine> |
| Variable *TargetX86Base<Machine>::makeVectorOfZeros(Type Ty, int32_t RegNum) { |
| - Variable *Reg = makeReg(Ty, RegNum); |
| - // Insert a FakeDef, since otherwise the live range of Reg might be |
| - // overestimated. |
| - Context.insert(InstFakeDef::create(Func, Reg)); |
| - _pxor(Reg, Reg); |
| - return Reg; |
| + return makeZeroedRegister(Ty, RegNum); |
| } |
| template <class Machine> |
| @@ -5563,6 +5587,15 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed, |
| // Convert a scalar floating point constant into an explicit memory |
| // operand. |
| if (isScalarFloatingType(Ty)) { |
| + if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(Const)) { |
| + float Value = ConstFloat->getValue(); |
| + if (Value == 0 && !signbit(Value)) |
|
John
2015/11/13 21:51:19
Optional: This is a good candidate for a little he
Jim Stichnoth
2015/11/13 22:20:24
Nice, done.
|
| + return makeZeroedRegister(Ty, RegNum); |
| + } else if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(Const)) { |
| + double Value = ConstDouble->getValue(); |
| + if (Value == 0 && !signbit(Value)) |
| + return makeZeroedRegister(Ty, RegNum); |
| + } |
| Variable *Base = nullptr; |
| std::string Buffer; |
| llvm::raw_string_ostream StrBuf(Buffer); |