Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit f245d9a

Browse files
committed
[FastISel][X86] Emit more efficient instructions for integer constant materialization.
This mostly affects the i64 value type, which always resulted in an 15byte mobavsq instruction to materialize any constant. The custom code checks the value of the immediate and tries to use a different and smaller mov instruction when possible. This fixes <rdar://problem/17420988>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215593 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent dc408e8 commit f245d9a

File tree

3 files changed

+177
-212
lines changed

3 files changed

+177
-212
lines changed

lib/Target/X86/X86FastISel.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3105,7 +3105,34 @@ X86FastISel::TargetSelectInstruction(const Instruction *I) {
31053105
unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
31063106
if (VT > MVT::i64)
31073107
return 0;
3108-
return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
3108+
3109+
uint64_t Imm = CI->getZExtValue();
3110+
unsigned Opc = 0;
3111+
switch (VT.SimpleTy) {
3112+
default: llvm_unreachable("Unexpected value type");
3113+
case MVT::i1: VT = MVT::i8; // fall-through
3114+
case MVT::i8: Opc = X86::MOV8ri; break;
3115+
case MVT::i16: Opc = X86::MOV16ri; break;
3116+
case MVT::i32: Opc = X86::MOV32ri; break;
3117+
case MVT::i64: {
3118+
if (isUInt<32>(Imm))
3119+
Opc = X86::MOV32ri;
3120+
else if (isInt<32>(Imm))
3121+
Opc = X86::MOV64ri32;
3122+
else
3123+
Opc = X86::MOV64ri;
3124+
break;
3125+
}
3126+
}
3127+
if (VT == MVT::i64 && Opc == X86::MOV32ri) {
3128+
unsigned SrcReg = FastEmitInst_i(Opc, &X86::GR32RegClass, Imm);
3129+
unsigned ResultReg = createResultReg(&X86::GR64RegClass);
3130+
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3131+
TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3132+
.addImm(0).addReg(SrcReg).addImm(X86::sub_32bit);
3133+
return ResultReg;
3134+
}
3135+
return FastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm);
31093136
}
31103137

31113138
unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {

test/CodeGen/X86/object-size.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s -check-prefix=X64
1+
; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s
22

33
; ModuleID = 'ts.c'
44
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -12,8 +12,8 @@ entry:
1212
%tmp = load i8** @p ; <i8*> [#uses=1]
1313
%0 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp, i1 0) ; <i64> [#uses=1]
1414
%cmp = icmp ne i64 %0, -1 ; <i1> [#uses=1]
15-
; X64: movabsq $-1, [[RAX:%r..]]
16-
; X64: cmpq $-1, [[RAX]]
15+
; CHECK: movq $-1, [[RAX:%r..]]
16+
; CHECK: cmpq $-1, [[RAX]]
1717
br i1 %cmp, label %cond.true, label %cond.false
1818

1919
cond.true: ; preds = %entry

0 commit comments

Comments
 (0)