From b2b7c4b1a73b4be0d061880152d5d305da39630c Mon Sep 17 00:00:00 2001 From: Brian Gesiak Date: Thu, 13 Apr 2017 16:44:25 +0000 Subject: [PATCH] [Analysis] Support bitreverse in -demanded-bits pass Summary: * Add a bitreverse case in the demanded bits analysis pass. * Add tests for the bitreverse (and bswap) intrinsic in the demanded bits pass. * Add a test case to the BDCE tests: that manipulations to high-order bits are eliminated once the bits are reversed and then right-shifted. Reviewers: mkuper, jmolloy, hfinkel, trentxintong Reviewed By: jmolloy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31857 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300215 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/DemandedBits.cpp | 3 +++ test/Analysis/DemandedBits/intrinsics.ll | 25 +++++++++++++++++++++ test/Transforms/BDCE/basic.ll | 38 ++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 test/Analysis/DemandedBits/intrinsics.ll diff --git a/lib/Analysis/DemandedBits.cpp b/lib/Analysis/DemandedBits.cpp index 688c1db534c..151c0b0e6c9 100644 --- a/lib/Analysis/DemandedBits.cpp +++ b/lib/Analysis/DemandedBits.cpp @@ -110,6 +110,9 @@ void DemandedBits::determineLiveOperandBits( // the output. AB = AOut.byteSwap(); break; + case Intrinsic::bitreverse: + AB = AOut.reverseBits(); + break; case Intrinsic::ctlz: if (OperandNo == 0) { // We need some output bits, so we need all bits of the diff --git a/test/Analysis/DemandedBits/intrinsics.ll b/test/Analysis/DemandedBits/intrinsics.ll new file mode 100644 index 00000000000..5a6d17284a7 --- /dev/null +++ b/test/Analysis/DemandedBits/intrinsics.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -demanded-bits -analyze < %s | FileCheck %s +; RUN: opt -S -disable-output -passes="print" < %s 2>&1 | FileCheck %s + +; CHECK-DAG: DemandedBits: 0xFF000000 for %1 = or i32 %x, 1 +; CHECK-DAG: DemandedBits: 0xFF for %2 = call i32 @llvm.bitreverse.i32(i32 %1) +; CHECK-DAG: DemandedBits: 0xFF for %3 = trunc i32 %2 to i8 +define i8 @test_bswap(i32 %x) { + %1 = or i32 %x, 1 + %2 = call i32 @llvm.bswap.i32(i32 %1) + %3 = trunc i32 %2 to i8 + ret i8 %3 +} +declare i32 @llvm.bswap.i32(i32) + +; CHECK-DAG: DemandedBits: 0xFF000000 for %1 = or i32 %x, 1 +; CHECK-DAG: DemandedBits: 0xFF for %2 = call i32 @llvm.bswap.i32(i32 %1) +; CHECK-DAG: DemandedBits: 0xFF for %3 = trunc i32 %2 to i8 +define i8 @test_bitreverse(i32 %x) { + %1 = or i32 %x, 1 + %2 = call i32 @llvm.bitreverse.i32(i32 %1) + %3 = trunc i32 %2 to i8 + ret i8 %3 +} +declare i32 @llvm.bitreverse.i32(i32) + diff --git a/test/Transforms/BDCE/basic.ll b/test/Transforms/BDCE/basic.ll index 6e748c69a16..6132c5d797f 100644 --- a/test/Transforms/BDCE/basic.ll +++ b/test/Transforms/BDCE/basic.ll @@ -136,6 +136,44 @@ entry: declare i32 @llvm.bswap.i32(i32) #0 ; Function Attrs: nounwind readnone +define signext i32 @tim(i32 signext %x) #0 { +entry: + %call = tail call signext i32 @foo(i32 signext 5) #0 + %and = and i32 %call, 536870912 + %or = or i32 %and, %x + %call1 = tail call signext i32 @foo(i32 signext 3) #0 + %and2 = and i32 %call1, 1073741824 + %or3 = or i32 %or, %and2 + %call4 = tail call signext i32 @foo(i32 signext 2) #0 + %and5 = and i32 %call4, 16 + %or6 = or i32 %or3, %and5 + %call7 = tail call signext i32 @foo(i32 signext 1) #0 + %and8 = and i32 %call7, 32 + %or9 = or i32 %or6, %and8 + %call10 = tail call signext i32 @foo(i32 signext 0) #0 + %and11 = and i32 %call10, 64 + %or12 = or i32 %or9, %and11 + %call13 = tail call signext i32 @foo(i32 signext 4) #0 + %and14 = and i32 %call13, 128 + %or15 = or i32 %or12, %and14 + %bs = tail call i32 @llvm.bitreverse.i32(i32 %or15) #0 + %shr = ashr i32 %bs, 4 + ret i32 %shr + +; CHECK-LABEL: @tim +; CHECK-NOT: tail call signext i32 @foo(i32 signext 5) +; CHECK-NOT: tail call signext i32 @foo(i32 signext 3) +; CHECK: tail call signext i32 @foo(i32 signext 2) +; CHECK: tail call signext i32 @foo(i32 signext 1) +; CHECK: tail call signext i32 @foo(i32 signext 0) +; CHECK: tail call signext i32 @foo(i32 signext 4) +; CHECK: ret i32 +} + +; Function Attrs: nounwind readnone +declare i32 @llvm.bitreverse.i32(i32) #0 + +; Function Attrs: nounwind readnone define signext i32 @tar2(i32 signext %x) #0 { entry: %call = tail call signext i32 @foo(i32 signext 5) #0 -- 2.11.0