| //===- DemandedBitsTest.cpp - DemandedBits tests --------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Analysis/DemandedBits.h" |
| #include "../Support/KnownBitsTest.h" |
| #include "llvm/Support/KnownBits.h" |
| #include "gtest/gtest.h" |
| |
| using namespace llvm; |
| |
| namespace { |
| |
| template <typename Fn1, typename Fn2> |
| static void TestBinOpExhaustive(Fn1 PropagateFn, Fn2 EvalFn) { |
| unsigned Bits = 4; |
| unsigned Max = 1 << Bits; |
| ForeachKnownBits(Bits, [&](const KnownBits &Known1) { |
| ForeachKnownBits(Bits, [&](const KnownBits &Known2) { |
| for (unsigned AOut_ = 0; AOut_ < Max; AOut_++) { |
| APInt AOut(Bits, AOut_); |
| APInt AB1 = PropagateFn(0, AOut, Known1, Known2); |
| APInt AB2 = PropagateFn(1, AOut, Known1, Known2); |
| { |
| // If the propagator claims that certain known bits |
| // didn't matter, check it doesn't change its mind |
| // when they become unknown. |
| KnownBits Known1Redacted; |
| KnownBits Known2Redacted; |
| Known1Redacted.Zero = Known1.Zero & AB1; |
| Known1Redacted.One = Known1.One & AB1; |
| Known2Redacted.Zero = Known2.Zero & AB2; |
| Known2Redacted.One = Known2.One & AB2; |
| |
| APInt AB1R = PropagateFn(0, AOut, Known1Redacted, Known2Redacted); |
| APInt AB2R = PropagateFn(1, AOut, Known1Redacted, Known2Redacted); |
| EXPECT_EQ(AB1, AB1R); |
| EXPECT_EQ(AB2, AB2R); |
| } |
| ForeachNumInKnownBits(Known1, [&](APInt Value1) { |
| ForeachNumInKnownBits(Known2, [&](APInt Value2) { |
| APInt ReferenceResult = EvalFn((Value1 & AB1), (Value2 & AB2)); |
| APInt Result = EvalFn(Value1, Value2); |
| EXPECT_EQ(Result & AOut, ReferenceResult & AOut); |
| }); |
| }); |
| } |
| }); |
| }); |
| } |
| |
| TEST(DemandedBitsTest, Add) { |
| TestBinOpExhaustive(DemandedBits::determineLiveOperandBitsAdd, |
| [](APInt N1, APInt N2) -> APInt { return N1 + N2; }); |
| } |
| |
| TEST(DemandedBitsTest, Sub) { |
| TestBinOpExhaustive(DemandedBits::determineLiveOperandBitsSub, |
| [](APInt N1, APInt N2) -> APInt { return N1 - N2; }); |
| } |
| |
| } // anonymous namespace |