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