Subzero: x86-64: Allow immediates in 64-bit instructions. The original code legalized *all* i64 constants into a register move, creating unnecessary instructions and slightly higher register pressure in most cases. Generally, immediates can be used in 64-bit instructions as long as the immediate can be represented as a sign-extended 32-bit value. BUG= none R=jpp@chromium.org Review URL: https://codereview.chromium.org/2063053002 .
diff --git a/src/IceAssemblerX86BaseImpl.h b/src/IceAssemblerX86BaseImpl.h index 554f533..85d9302 100644 --- a/src/IceAssemblerX86BaseImpl.h +++ b/src/IceAssemblerX86BaseImpl.h
@@ -295,7 +295,6 @@ template <typename TraitsType> void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst, const Immediate &imm) { - assert(Ty != IceType_i64 && "i64 not supported yet."); AssemblerBuffer::EnsureCapacity ensured(&Buffer); if (Ty == IceType_i16) emitOperandSizeOverride(); @@ -2641,7 +2640,7 @@ void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg, const Immediate &imm) { AssemblerBuffer::EnsureCapacity ensured(&Buffer); - assert(Ty == IceType_i16 || Ty == IceType_i32); + assert(Ty == IceType_i16 || Ty == IceType_i32 || Ty == IceType_i64); if (Ty == IceType_i16) emitOperandSizeOverride(); emitRexRB(Ty, reg, reg);
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h index bc5811e..cfc36d4 100644 --- a/src/IceInstX86BaseImpl.h +++ b/src/IceInstX86BaseImpl.h
@@ -738,6 +738,10 @@ Mem->toAsmAddress(Asm, Target, IsLea)); } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); + } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger64>(Src)) { + assert(Traits::Is64Bit); + assert(Utils::IsInt(32, Imm->getValue())); + (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { const auto FixupKind = (Reloc->getName().hasStdString() && Reloc->getName().toString() == GlobalOffsetTable) @@ -765,6 +769,10 @@ (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue())); + } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger64>(Src)) { + assert(Traits::Is64Bit); + assert(Utils::IsInt(32, Imm->getValue())); + (Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue())); } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { const auto FixupKind = (Reloc->getName().hasStdString() && Reloc->getName().toString() == GlobalOffsetTable) @@ -816,6 +824,10 @@ (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); + } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger64>(Src)) { + assert(Traits::Is64Bit); + assert(Utils::IsInt(32, Imm->getValue())); + (Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue())); } else { llvm_unreachable("Unexpected operand type"); } @@ -2042,7 +2054,8 @@ Type SrcTy = Src->getType(); Type DestTy = this->getDest()->getType(); if (Traits::Is64Bit && DestTy == IceType_i64 && - llvm::isa<ConstantInteger64>(Src)) { + llvm::isa<ConstantInteger64>(Src) && + !Utils::IsInt(32, llvm::cast<ConstantInteger64>(Src)->getValue())) { Str << "\t" "movabs" "\t";
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h index 6b25823..fcfe6ed 100644 --- a/src/IceTargetLoweringX86BaseImpl.h +++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -2228,21 +2228,24 @@ break; case InstArithmetic::Shl: _mov(T, Src0); - if (!llvm::isa<ConstantInteger32>(Src1)) + if (!llvm::isa<ConstantInteger32>(Src1) && + !llvm::isa<ConstantInteger64>(Src1)) Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl); _shl(T, Src1); _mov(Dest, T); break; case InstArithmetic::Lshr: _mov(T, Src0); - if (!llvm::isa<ConstantInteger32>(Src1)) + if (!llvm::isa<ConstantInteger32>(Src1) && + !llvm::isa<ConstantInteger64>(Src1)) Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl); _shr(T, Src1); _mov(Dest, T); break; case InstArithmetic::Ashr: _mov(T, Src0); - if (!llvm::isa<ConstantInteger32>(Src1)) + if (!llvm::isa<ConstantInteger32>(Src1) && + !llvm::isa<ConstantInteger64>(Src1)) Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl); _sar(T, Src1); _mov(Dest, T); @@ -7339,11 +7342,13 @@ // If the operand is a 64 bit constant integer we need to legalize it to a // register in x86-64. if (Traits::Is64Bit) { - if (llvm::isa<ConstantInteger64>(Const)) { - if (RegNum.hasValue()) { - assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); + if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Const)) { + if (!Utils::IsInt(32, C64->getValue())) { + if (RegNum.hasValue()) { + assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); + } + return copyToReg(Const, RegNum); } - return copyToReg(Const, RegNum); } }