xref: /llvm-project/llvm/unittests/IR/DemandedBitsTest.cpp (revision b25b1db8199d86cb3645e92200cda8d5d30922d0)
1c1f6ce0cSSimon Pilgrim //===- DemandedBitsTest.cpp - DemandedBits tests --------------------------===//
2c1f6ce0cSSimon Pilgrim //
3c1f6ce0cSSimon Pilgrim // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c1f6ce0cSSimon Pilgrim // See https://llvm.org/LICENSE.txt for license information.
5c1f6ce0cSSimon Pilgrim // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c1f6ce0cSSimon Pilgrim //
7c1f6ce0cSSimon Pilgrim //===----------------------------------------------------------------------===//
8c1f6ce0cSSimon Pilgrim 
9c1f6ce0cSSimon Pilgrim #include "llvm/Analysis/DemandedBits.h"
10c1f6ce0cSSimon Pilgrim #include "../Support/KnownBitsTest.h"
11c1f6ce0cSSimon Pilgrim #include "llvm/Support/KnownBits.h"
12c1f6ce0cSSimon Pilgrim #include "gtest/gtest.h"
13c1f6ce0cSSimon Pilgrim 
14c1f6ce0cSSimon Pilgrim using namespace llvm;
15c1f6ce0cSSimon Pilgrim 
16c1f6ce0cSSimon Pilgrim namespace {
17c1f6ce0cSSimon Pilgrim 
18c1f6ce0cSSimon Pilgrim template <typename Fn1, typename Fn2>
TestBinOpExhaustive(Fn1 PropagateFn,Fn2 EvalFn)19c1f6ce0cSSimon Pilgrim static void TestBinOpExhaustive(Fn1 PropagateFn, Fn2 EvalFn) {
20c1f6ce0cSSimon Pilgrim   unsigned Bits = 4;
21c1f6ce0cSSimon Pilgrim   unsigned Max = 1 << Bits;
22c1f6ce0cSSimon Pilgrim   ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
23c1f6ce0cSSimon Pilgrim     ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
24c1f6ce0cSSimon Pilgrim       for (unsigned AOut_ = 0; AOut_ < Max; AOut_++) {
25c1f6ce0cSSimon Pilgrim         APInt AOut(Bits, AOut_);
26c1f6ce0cSSimon Pilgrim         APInt AB1 = PropagateFn(0, AOut, Known1, Known2);
27c1f6ce0cSSimon Pilgrim         APInt AB2 = PropagateFn(1, AOut, Known1, Known2);
28c1f6ce0cSSimon Pilgrim         {
29c1f6ce0cSSimon Pilgrim           // If the propagator claims that certain known bits
30c1f6ce0cSSimon Pilgrim           // didn't matter, check it doesn't change its mind
31c1f6ce0cSSimon Pilgrim           // when they become unknown.
32c1f6ce0cSSimon Pilgrim           KnownBits Known1Redacted;
33c1f6ce0cSSimon Pilgrim           KnownBits Known2Redacted;
34c1f6ce0cSSimon Pilgrim           Known1Redacted.Zero = Known1.Zero & AB1;
35c1f6ce0cSSimon Pilgrim           Known1Redacted.One = Known1.One & AB1;
36c1f6ce0cSSimon Pilgrim           Known2Redacted.Zero = Known2.Zero & AB2;
37c1f6ce0cSSimon Pilgrim           Known2Redacted.One = Known2.One & AB2;
38c1f6ce0cSSimon Pilgrim 
39c1f6ce0cSSimon Pilgrim           APInt AB1R = PropagateFn(0, AOut, Known1Redacted, Known2Redacted);
40c1f6ce0cSSimon Pilgrim           APInt AB2R = PropagateFn(1, AOut, Known1Redacted, Known2Redacted);
41*b25b1db8Sc8ef           if (!Known1Redacted.hasConflict() && !Known2Redacted.hasConflict()) {
42c1f6ce0cSSimon Pilgrim             EXPECT_EQ(AB1, AB1R);
43c1f6ce0cSSimon Pilgrim             EXPECT_EQ(AB2, AB2R);
44c1f6ce0cSSimon Pilgrim           }
45*b25b1db8Sc8ef         }
46c1f6ce0cSSimon Pilgrim         ForeachNumInKnownBits(Known1, [&](APInt Value1) {
47c1f6ce0cSSimon Pilgrim           ForeachNumInKnownBits(Known2, [&](APInt Value2) {
48c1f6ce0cSSimon Pilgrim             APInt ReferenceResult = EvalFn((Value1 & AB1), (Value2 & AB2));
49c1f6ce0cSSimon Pilgrim             APInt Result = EvalFn(Value1, Value2);
50c1f6ce0cSSimon Pilgrim             EXPECT_EQ(Result & AOut, ReferenceResult & AOut);
51c1f6ce0cSSimon Pilgrim           });
52c1f6ce0cSSimon Pilgrim         });
53c1f6ce0cSSimon Pilgrim       }
54c1f6ce0cSSimon Pilgrim     });
55c1f6ce0cSSimon Pilgrim   });
56c1f6ce0cSSimon Pilgrim }
57c1f6ce0cSSimon Pilgrim 
TEST(DemandedBitsTest,Add)58c1f6ce0cSSimon Pilgrim TEST(DemandedBitsTest, Add) {
59c1f6ce0cSSimon Pilgrim   TestBinOpExhaustive(DemandedBits::determineLiveOperandBitsAdd,
60c1f6ce0cSSimon Pilgrim                       [](APInt N1, APInt N2) -> APInt { return N1 + N2; });
61c1f6ce0cSSimon Pilgrim }
62c1f6ce0cSSimon Pilgrim 
TEST(DemandedBitsTest,Sub)63c1f6ce0cSSimon Pilgrim TEST(DemandedBitsTest, Sub) {
64c1f6ce0cSSimon Pilgrim   TestBinOpExhaustive(DemandedBits::determineLiveOperandBitsSub,
65c1f6ce0cSSimon Pilgrim                       [](APInt N1, APInt N2) -> APInt { return N1 - N2; });
66c1f6ce0cSSimon Pilgrim }
67c1f6ce0cSSimon Pilgrim 
68c1f6ce0cSSimon Pilgrim } // anonymous namespace
69