From a9cda8abf28bc8f684348cc312ffbc3cd8354906 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 28 May 2009 00:35:15 +0000 Subject: Added optimization that narrow load / op / store and the 'op' is a bit twiddling instruction and its second operand is an immediate. If bits that are touched by 'op' can be done with a narrower instruction, reduce the width of the load and store as well. This happens a lot with bitfield manipulation code. e.g. orl $65536, 8(%rax) => orb $1, 10(%rax) Since narrowing is not always a win, e.g. i32 -> i16 is a loss on x86, dag combiner consults with the target before performing the optimization. llvm-svn: 72507 --- llvm/test/CodeGen/X86/narrow_op-1.ll | 23 +++++++++++++++++++++++ llvm/test/CodeGen/X86/narrow_op-2.ll | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 llvm/test/CodeGen/X86/narrow_op-1.ll create mode 100644 llvm/test/CodeGen/X86/narrow_op-2.ll (limited to 'llvm/test/CodeGen') diff --git a/llvm/test/CodeGen/X86/narrow_op-1.ll b/llvm/test/CodeGen/X86/narrow_op-1.ll new file mode 100644 index 00000000000..0ee11b49558 --- /dev/null +++ b/llvm/test/CodeGen/X86/narrow_op-1.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep orb | count 1 +; RUN: llvm-as < %s | llc -march=x86-64 | grep orb | grep 1 +; RUN: llvm-as < %s | llc -march=x86-64 | grep orl | count 1 +; RUN: llvm-as < %s | llc -march=x86-64 | grep orl | grep 16842752 + + %struct.bf = type { i64, i16, i16, i32 } +@bfi = common global %struct.bf zeroinitializer, align 16 + +define void @t1() nounwind optsize ssp { +entry: + %0 = load i32* bitcast (i16* getelementptr (%struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 + %1 = or i32 %0, 65536 + store i32 %1, i32* bitcast (i16* getelementptr (%struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 + ret void +} + +define void @t2() nounwind optsize ssp { +entry: + %0 = load i32* bitcast (i16* getelementptr (%struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 + %1 = or i32 %0, 16842752 + store i32 %1, i32* bitcast (i16* getelementptr (%struct.bf* @bfi, i32 0, i32 1) to i32*), align 8 + ret void +} diff --git a/llvm/test/CodeGen/X86/narrow_op-2.ll b/llvm/test/CodeGen/X86/narrow_op-2.ll new file mode 100644 index 00000000000..b441794f42f --- /dev/null +++ b/llvm/test/CodeGen/X86/narrow_op-2.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep andb | count 2 +; RUN: llvm-as < %s | llc -march=x86-64 | grep andb | grep 254 +; RUN: llvm-as < %s | llc -march=x86-64 | grep andb | grep 253 + + %struct.bf = type { i64, i16, i16, i32 } +@bfi = external global %struct.bf* + +define void @t1() nounwind ssp { +entry: + %0 = load %struct.bf** @bfi, align 8 + %1 = getelementptr %struct.bf* %0, i64 0, i32 1 + %2 = bitcast i16* %1 to i32* + %3 = load i32* %2, align 1 + %4 = and i32 %3, -65537 + store i32 %4, i32* %2, align 1 + %5 = load %struct.bf** @bfi, align 8 + %6 = getelementptr %struct.bf* %5, i64 0, i32 1 + %7 = bitcast i16* %6 to i32* + %8 = load i32* %7, align 1 + %9 = and i32 %8, -131073 + store i32 %9, i32* %7, align 1 + ret void +} -- cgit v1.2.3