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/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";