From 5f916d3df42330d647cefa8c36a0ab2ec6cc0f62 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Mar 2016 18:11:31 +0000 Subject: [PATCH] [X86] Use "and $0" and "orl $-1" to store 0 and -1 when optimizing for minsize 64-bit, 32-bit and 16-bit move-immediate instructions are 7, 6, and 5 bytes, respectively, whereas and/or with 8-bit immediate is only three bytes. Since these instructions imply an additional memory read (which the CPU could elide, but we don't think it does), restrict these patterns to minsize functions. Differential Revision: http://reviews.llvm.org/D18374 llvm-svn: 264440 --- llvm/lib/Target/X86/X86InstrCompiler.td | 12 ++++ llvm/test/CodeGen/X86/store-zero-and-minus-one.ll | 88 +++++++++++++++++++++++ llvm/test/CodeGen/X86/tail-opts.ll | 2 +- 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/X86/store-zero-and-minus-one.ll diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index c2a00aa..faf0f81 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -1001,6 +1001,18 @@ def ACQUIRE_MOV64rm : I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$src), // DAG Pattern Matching Rules //===----------------------------------------------------------------------===// +// Use AND/OR to store 0/-1 in memory when optimizing for minsize. This saves +// binary size compared to a regular MOV, but it introduces an unnecessary +// load, so is not suitable for regular or optsize functions. +let Predicates = [OptForMinSize] in { +def : Pat<(store (i16 0), addr:$dst), (AND16mi8 addr:$dst, 0)>; +def : Pat<(store (i32 0), addr:$dst), (AND32mi8 addr:$dst, 0)>; +def : Pat<(store (i64 0), addr:$dst), (AND64mi8 addr:$dst, 0)>; +def : Pat<(store (i16 -1), addr:$dst), (OR16mi8 addr:$dst, -1)>; +def : Pat<(store (i32 -1), addr:$dst), (OR32mi8 addr:$dst, -1)>; +def : Pat<(store (i64 -1), addr:$dst), (OR64mi8 addr:$dst, -1)>; +} + // ConstantPool GlobalAddress, ExternalSymbol, and JumpTable def : Pat<(i32 (X86Wrapper tconstpool :$dst)), (MOV32ri tconstpool :$dst)>; def : Pat<(i32 (X86Wrapper tjumptable :$dst)), (MOV32ri tjumptable :$dst)>; diff --git a/llvm/test/CodeGen/X86/store-zero-and-minus-one.ll b/llvm/test/CodeGen/X86/store-zero-and-minus-one.ll new file mode 100644 index 0000000..14790018 --- /dev/null +++ b/llvm/test/CodeGen/X86/store-zero-and-minus-one.ll @@ -0,0 +1,88 @@ +; RUN: llc -mtriple=i686-unknown-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK32 --check-prefix=CHECK +; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK + +define void @zero_optsize(i32* %p) optsize { +entry: + store i32 0, i32* %p + ret void + +; CHECK-LABEL: zero_optsize: +; CHECK: movl $0 +; CHECK: ret +} + +define void @minus_one_optsize(i32* %p) optsize { +entry: + store i32 -1, i32* %p + ret void + +; CHECK-LABEL: minus_one_optsize: +; CHECK: movl $-1 +; CHECK: ret +} + + +define void @zero_64(i64* %p) minsize { +entry: + store i64 0, i64* %p + ret void + +; CHECK-LABEL: zero_64: +; CHECK32: andl $0 +; CHECK32: andl $0 +; CHECK64: andq $0 +; CHECK: ret +} + +define void @zero_32(i32* %p) minsize { +entry: + store i32 0, i32* %p + ret void + +; CHECK-LABEL: zero_32: +; CHECK: andl $0 +; CHECK: ret +} + +define void @zero_16(i16* %p) minsize { +entry: + store i16 0, i16* %p + ret void + +; CHECK-LABEL: zero_16: +; CHECK: andw $0 +; CHECK: ret +} + + +define void @minus_one_64(i64* %p) minsize { +entry: + store i64 -1, i64* %p + ret void + +; CHECK-LABEL: minus_one_64: +; CHECK32: orl $-1 +; CHECK32: orl $-1 +; CHECK64: orq $-1 +; CHECK: ret +} + +define void @minus_one_32(i32* %p) minsize { +entry: + store i32 -1, i32* %p + ret void + +; CHECK-LABEL: minus_one_32: +; CHECK: orl $-1 +; CHECK: ret +} + +define void @minus_one_16(i16* %p) minsize { +entry: + store i16 -1, i16* %p + ret void + +; CHECK-LABEL: minus_one_16: +; CHECK: orw $-1 +; CHECK: ret +} diff --git a/llvm/test/CodeGen/X86/tail-opts.ll b/llvm/test/CodeGen/X86/tail-opts.ll index bf778e5..12c90c1 100644 --- a/llvm/test/CodeGen/X86/tail-opts.ll +++ b/llvm/test/CodeGen/X86/tail-opts.ll @@ -376,7 +376,7 @@ return: ; CHECK-LABEL: two_minsize: ; CHECK-NOT: XYZ ; CHECK: ret -; CHECK: movl $0, XYZ(%rip) +; CHECK: andl $0, XYZ(%rip) ; CHECK: movl $1, XYZ(%rip) ; CHECK-NOT: XYZ -- 2.7.4