forked from OSchip/llvm-project
Expand i8 selects into control flow instead of 16-bit conditional
moves. This avoids the need to promote the operands (or implicitly extend them, a partial register update condition), and can reduce i8 register pressure. This substantially speeds up code such as write_hex in lib/Support/raw_ostream.cpp. subclass-coalesce.ll is too trivial and no longer tests what it was originally intended to test. llvm-svn: 80184
This commit is contained in:
parent
eabf770457
commit
f1abb5511b
|
@ -276,9 +276,9 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
|||
setOperationAction(ISD::BSWAP , MVT::i16 , Expand);
|
||||
|
||||
// These should be promoted to a larger select which is supported.
|
||||
setOperationAction(ISD::SELECT , MVT::i1 , Promote);
|
||||
setOperationAction(ISD::SELECT , MVT::i8 , Promote);
|
||||
setOperationAction(ISD::SELECT , MVT::i1 , Promote);
|
||||
// X86 wants to expand cmov itself.
|
||||
setOperationAction(ISD::SELECT , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::SELECT , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::SELECT , MVT::i32 , Custom);
|
||||
setOperationAction(ISD::SELECT , MVT::f32 , Custom);
|
||||
|
@ -7707,6 +7707,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
|||
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
|
||||
switch (MI->getOpcode()) {
|
||||
default: assert(false && "Unexpected instr type to insert");
|
||||
case X86::CMOV_GR8:
|
||||
case X86::CMOV_V1I64:
|
||||
case X86::CMOV_FR32:
|
||||
case X86::CMOV_FR64:
|
||||
|
|
|
@ -1035,6 +1035,18 @@ let isTwoAddress = 1 in {
|
|||
// Conditional moves
|
||||
let Uses = [EFLAGS] in {
|
||||
let isCommutable = 1 in {
|
||||
|
||||
// X86 doesn't have 8-bit conditional moves. Use a customDAGSchedInserter to
|
||||
// emit control flow. An alternative to this is to mark i8 SELECT as Promote,
|
||||
// however that requires promoting the operands, and can induce additional
|
||||
// i8 register pressure.
|
||||
let usesCustomDAGSchedInserter = 1 in
|
||||
def CMOV_GR8 : I<0, Pseudo,
|
||||
(outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cond),
|
||||
"#CMOV_GR8 PSEUDO!",
|
||||
[(set GR8:$dst, (X86cmov GR8:$src1, GR8:$src2,
|
||||
imm:$cond, EFLAGS))]>;
|
||||
|
||||
def CMOVB16rr : I<0x42, MRMSrcReg, // if <u, GR16 = GR16
|
||||
(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
|
||||
"cmovb\t{$src2, $dst|$dst, $src2}",
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
; RUN: llvm-as < %s | llc -march=x86 > %t
|
||||
; RUN: not grep movz %t
|
||||
; RUN: not grep cmov %t
|
||||
; RUN: grep movb %t | count 2
|
||||
|
||||
; Don't try to use a 16-bit conditional move to do an 8-bit select,
|
||||
; because it isn't worth it. Just use a branch instead.
|
||||
|
||||
define i8 @foo(i1 inreg %c, i8 inreg %a, i8 inreg %b) {
|
||||
%d = select i1 %c, i8 %a, i8 %b
|
||||
ret i8 %d
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of cross class joins performed}
|
||||
|
||||
@mem.6 = external global i64 ; <i64*> [#uses=1]
|
||||
|
||||
define i64 @attachFunc() nounwind {
|
||||
entry:
|
||||
%tmp64.i = add i64 0, 72 ; <i64> [#uses=1]
|
||||
%tmp68.i = load i64* @mem.6, align 8 ; <i64> [#uses=1]
|
||||
%tmp70.i = icmp sgt i64 %tmp64.i, %tmp68.i ; <i1> [#uses=1]
|
||||
br i1 %tmp70.i, label %bb73.i, label %bb116
|
||||
|
||||
bb73.i: ; preds = %entry
|
||||
br label %bb116
|
||||
|
||||
bb116: ; preds = %bb73.i, %entry
|
||||
ret i64 %tmp68.i
|
||||
}
|
Loading…
Reference in New Issue