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