From 7eb6751ff60673ab6503d7f29cbb7569f5c077be Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 17 Jan 2017 17:23:51 +0000 Subject: [PATCH] [ValueTracking] Extend known bits to understand @llvm.bitreverse. Differential Revision: https://reviews.llvm.org/D28780 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292233 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ValueTracking.cpp | 5 +++ .../InstCombine/bitreverse-known-bits.ll | 34 +++++++++++++++++++ test/Transforms/InstSimplify/bitreverse.ll | 31 +++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 test/Transforms/InstCombine/bitreverse-known-bits.ll create mode 100644 test/Transforms/InstSimplify/bitreverse.ll diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 244aa798a9c..d926b3864de 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -1400,6 +1400,11 @@ static void computeKnownBitsFromOperator(const Operator *I, APInt &KnownZero, if (const IntrinsicInst *II = dyn_cast(I)) { switch (II->getIntrinsicID()) { default: break; + case Intrinsic::bitreverse: + computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q); + KnownZero = KnownZero2.reverseBits(); + KnownOne = KnownOne2.reverseBits(); + break; case Intrinsic::bswap: computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, Depth + 1, Q); KnownZero |= KnownZero2.byteSwap(); diff --git a/test/Transforms/InstCombine/bitreverse-known-bits.ll b/test/Transforms/InstCombine/bitreverse-known-bits.ll new file mode 100644 index 00000000000..b73df77b925 --- /dev/null +++ b/test/Transforms/InstCombine/bitreverse-known-bits.ll @@ -0,0 +1,34 @@ +; RUN: opt < %s -S -instcombine | FileCheck %s + +declare i32 @llvm.bitreverse.i32(i32) + +; CHECK-LABEL: @test1 +; CHECK: ret i1 true +define i1 @test1(i32 %arg) { + %a = or i32 %arg, 4294901760 + %b = call i32 @llvm.bitreverse.i32(i32 %a) + %and = and i32 %b, 65535 + %res = icmp eq i32 %and, 65535 + ret i1 %res +} + +; CHECK-LABEL: @test2 +; CHECK: ret i1 true +define i1 @test2(i32 %arg) { + %a = or i32 %arg, 1 + %b = call i32 @llvm.bitreverse.i32(i32 %a) + %c = and i32 %b, 2147483648 + %d = call i32 @llvm.bitreverse.i32(i32 %c) + %res = icmp eq i32 %d, 1 + ret i1 %res +} + +; CHECK-LABEL: @test3 +; CHECK: ret i1 false +define i1 @test3(i32 %arg) { + %a = or i32 %arg, 65536 + %b = call i32 @llvm.bitreverse.i32(i32 %a) + %and = and i32 %b, 32768 + %res = icmp eq i32 %and, 0 + ret i1 %res +} diff --git a/test/Transforms/InstSimplify/bitreverse.ll b/test/Transforms/InstSimplify/bitreverse.ll new file mode 100644 index 00000000000..d87b68831fe --- /dev/null +++ b/test/Transforms/InstSimplify/bitreverse.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -S -instsimplify | FileCheck %s + +declare i32 @llvm.bitreverse.i32(i32) + +; CHECK-LABEL: @test1( +; CHECK: ret i1 false +define i1 @test1(i32 %arg) { + %a = or i32 %arg, 1 + %b = call i32 @llvm.bitreverse.i32(i32 %a) + %res = icmp eq i32 %b, 0 + ret i1 %res +} + +; CHECK-LABEL: @test2( +; CHECK: ret i1 false +define i1 @test2(i32 %arg) { + %a = or i32 %arg, 1024 + %b = call i32 @llvm.bitreverse.i32(i32 %a) + %res = icmp eq i32 %b, 0 + ret i1 %res +} + +; CHECK-LABEL: @test3( +; CHECK: ret i1 false +define i1 @test3(i32 %arg) { + %a = and i32 %arg, 1 + %b = call i32 @llvm.bitreverse.i32(i32 %a) + %and = and i32 %b, 1 + %res = icmp eq i32 %and, 1 + ret i1 %res +} -- 2.40.0