llvm-project
2847 строк · 110.6 Кб
1//===- ConstantRangeTest.cpp - ConstantRange tests ------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/IR/ConstantRange.h"10#include "llvm/ADT/BitVector.h"11#include "llvm/ADT/Sequence.h"12#include "llvm/ADT/SmallBitVector.h"13#include "llvm/IR/Instructions.h"14#include "llvm/IR/Operator.h"15#include "llvm/Support/KnownBits.h"16#include "gtest/gtest.h"17
18using namespace llvm;19
20namespace {21
22class ConstantRangeTest : public ::testing::Test {23protected:24static ConstantRange Full;25static ConstantRange Empty;26static ConstantRange One;27static ConstantRange Some;28static ConstantRange Wrap;29};30
31template<typename Fn>32static void EnumerateAPInts(unsigned Bits, Fn TestFn) {33APInt N(Bits, 0);34do {35TestFn(N);36} while (++N != 0);37}
38
39template<typename Fn>40static void EnumerateConstantRanges(unsigned Bits, Fn TestFn) {41unsigned Max = 1 << Bits;42for (unsigned Lo = 0; Lo < Max; Lo++) {43for (unsigned Hi = 0; Hi < Max; Hi++) {44// Enforce ConstantRange invariant.45if (Lo == Hi && Lo != 0 && Lo != Max - 1)46continue;47
48ConstantRange CR(APInt(Bits, Lo), APInt(Bits, Hi));49TestFn(CR);50}51}52}
53
54template <typename Fn>55static void EnumerateInterestingConstantRanges(Fn TestFn) {56// Check 1 bit ranges, because they may have special cases.57EnumerateConstantRanges(/* Bits */ 1, TestFn);58// Check 4 bit ranges to have decent coverage without being too slow.59EnumerateConstantRanges(/* Bits */ 4, TestFn);60}
61
62template <typename Fn>63static void EnumerateTwoInterestingConstantRanges(Fn TestFn) {64for (unsigned Bits : {1, 4}) {65EnumerateConstantRanges(Bits, [&](const ConstantRange &CR1) {66EnumerateConstantRanges(67Bits, [&](const ConstantRange &CR2) { TestFn(CR1, CR2); });68});69}70}
71
72template <typename Fn>73static void ForeachNumInConstantRange(const ConstantRange &CR, Fn TestFn) {74if (!CR.isEmptySet()) {75APInt N = CR.getLower();76do TestFn(N);77while (++N != CR.getUpper());78}79}
80
81using PreferFn = llvm::function_ref<bool(const ConstantRange &,82const ConstantRange &)>;83
84bool PreferSmallest(const ConstantRange &CR1, const ConstantRange &CR2) {85return CR1.isSizeStrictlySmallerThan(CR2);86}
87
88bool PreferSmallestUnsigned(const ConstantRange &CR1,89const ConstantRange &CR2) {90if (CR1.isWrappedSet() != CR2.isWrappedSet())91return CR1.isWrappedSet() < CR2.isWrappedSet();92return PreferSmallest(CR1, CR2);93}
94
95bool PreferSmallestSigned(const ConstantRange &CR1, const ConstantRange &CR2) {96if (CR1.isSignWrappedSet() != CR2.isSignWrappedSet())97return CR1.isSignWrappedSet() < CR2.isSignWrappedSet();98return PreferSmallest(CR1, CR2);99}
100
101bool PreferSmallestNonFullUnsigned(const ConstantRange &CR1,102const ConstantRange &CR2) {103if (CR1.isFullSet() != CR2.isFullSet())104return CR1.isFullSet() < CR2.isFullSet();105return PreferSmallestUnsigned(CR1, CR2);106}
107
108bool PreferSmallestNonFullSigned(const ConstantRange &CR1,109const ConstantRange &CR2) {110if (CR1.isFullSet() != CR2.isFullSet())111return CR1.isFullSet() < CR2.isFullSet();112return PreferSmallestSigned(CR1, CR2);113}
114
115testing::AssertionResult rangeContains(const ConstantRange &CR, const APInt &N,116ArrayRef<ConstantRange> Inputs) {117if (CR.contains(N))118return testing::AssertionSuccess();119
120testing::AssertionResult Result = testing::AssertionFailure();121Result << CR << " does not contain " << N << " for inputs: ";122for (const ConstantRange &Input : Inputs)123Result << Input << ", ";124return Result;125}
126
127// Check whether constant range CR is an optimal approximation of the set
128// Elems under the given PreferenceFn. The preference function should return
129// true if the first range argument is strictly preferred to the second one.
130static void TestRange(const ConstantRange &CR, const SmallBitVector &Elems,131PreferFn PreferenceFn, ArrayRef<ConstantRange> Inputs,132bool CheckOptimality = true) {133unsigned BitWidth = CR.getBitWidth();134
135// Check conservative correctness.136for (unsigned Elem : Elems.set_bits()) {137EXPECT_TRUE(rangeContains(CR, APInt(BitWidth, Elem), Inputs));138}139
140if (!CheckOptimality)141return;142
143// Make sure we have at least one element for the code below.144if (Elems.none()) {145EXPECT_TRUE(CR.isEmptySet());146return;147}148
149auto NotPreferred = [&](const ConstantRange &PossibleCR) {150if (!PreferenceFn(PossibleCR, CR))151return testing::AssertionSuccess();152
153testing::AssertionResult Result = testing::AssertionFailure();154Result << "Inputs = ";155for (const ConstantRange &Input : Inputs)156Result << Input << ", ";157Result << "CR = " << CR << ", BetterCR = " << PossibleCR;158return Result;159};160
161// Look at all pairs of adjacent elements and the slack-free ranges162// [Elem, PrevElem] they imply. Check that none of the ranges are strictly163// preferred over the computed range (they may have equal preference).164int FirstElem = Elems.find_first();165int PrevElem = FirstElem, Elem;166do {167Elem = Elems.find_next(PrevElem);168if (Elem < 0)169Elem = FirstElem; // Wrap around to first element.170
171ConstantRange PossibleCR =172ConstantRange::getNonEmpty(APInt(BitWidth, Elem),173APInt(BitWidth, PrevElem) + 1);174// We get a full range any time PrevElem and Elem are adjacent. Avoid175// repeated checks by skipping here, and explicitly checking below instead.176if (!PossibleCR.isFullSet()) {177EXPECT_TRUE(NotPreferred(PossibleCR));178}179
180PrevElem = Elem;181} while (Elem != FirstElem);182
183EXPECT_TRUE(NotPreferred(ConstantRange::getFull(BitWidth)));184}
185
186using UnaryRangeFn = llvm::function_ref<ConstantRange(const ConstantRange &)>;187using UnaryIntFn = llvm::function_ref<std::optional<APInt>(const APInt &)>;188
189static void TestUnaryOpExhaustive(UnaryRangeFn RangeFn, UnaryIntFn IntFn,190PreferFn PreferenceFn = PreferSmallest) {191EnumerateInterestingConstantRanges([&](const ConstantRange &CR) {192SmallBitVector Elems(1 << CR.getBitWidth());193ForeachNumInConstantRange(CR, [&](const APInt &N) {194if (std::optional<APInt> ResultN = IntFn(N))195Elems.set(ResultN->getZExtValue());196});197TestRange(RangeFn(CR), Elems, PreferenceFn, {CR});198});199}
200
201using BinaryRangeFn = llvm::function_ref<ConstantRange(const ConstantRange &,202const ConstantRange &)>;203using BinaryIntFn =204llvm::function_ref<std::optional<APInt>(const APInt &, const APInt &)>;205using BinaryCheckFn = llvm::function_ref<bool(const ConstantRange &,206const ConstantRange &)>;207
208static bool CheckAll(const ConstantRange &, const ConstantRange &) {209return true;210}
211
212static bool CheckCorrectnessOnly(const ConstantRange &, const ConstantRange &) {213return false;214}
215
216static bool CheckSingleElementsOnly(const ConstantRange &CR1,217const ConstantRange &CR2) {218return CR1.isSingleElement() && CR2.isSingleElement();219}
220
221static bool CheckNonWrappedOnly(const ConstantRange &CR1,222const ConstantRange &CR2) {223return !CR1.isWrappedSet() && !CR2.isWrappedSet();224}
225
226static bool CheckNonSignWrappedOnly(const ConstantRange &CR1,227const ConstantRange &CR2) {228return !CR1.isSignWrappedSet() && !CR2.isSignWrappedSet();229}
230
231static bool CheckNonWrappedOrSignWrappedOnly(const ConstantRange &CR1,232const ConstantRange &CR2) {233return !CR1.isWrappedSet() && !CR1.isSignWrappedSet() &&234!CR2.isWrappedSet() && !CR2.isSignWrappedSet();235}
236
237// CheckFn determines whether optimality is checked for a given range pair.
238// Correctness is always checked.
239static void TestBinaryOpExhaustive(BinaryRangeFn RangeFn, BinaryIntFn IntFn,240PreferFn PreferenceFn = PreferSmallest,241BinaryCheckFn CheckFn = CheckAll) {242EnumerateTwoInterestingConstantRanges(243[&](const ConstantRange &CR1, const ConstantRange &CR2) {244SmallBitVector Elems(1 << CR1.getBitWidth());245ForeachNumInConstantRange(CR1, [&](const APInt &N1) {246ForeachNumInConstantRange(CR2, [&](const APInt &N2) {247if (std::optional<APInt> ResultN = IntFn(N1, N2))248Elems.set(ResultN->getZExtValue());249});250});251TestRange(RangeFn(CR1, CR2), Elems, PreferenceFn, {CR1, CR2},252CheckFn(CR1, CR2));253});254}
255
256ConstantRange ConstantRangeTest::Full(16, true);257ConstantRange ConstantRangeTest::Empty(16, false);258ConstantRange ConstantRangeTest::One(APInt(16, 0xa));259ConstantRange ConstantRangeTest::Some(APInt(16, 0xa), APInt(16, 0xaaa));260ConstantRange ConstantRangeTest::Wrap(APInt(16, 0xaaa), APInt(16, 0xa));261
262TEST_F(ConstantRangeTest, Basics) {263EXPECT_TRUE(Full.isFullSet());264EXPECT_FALSE(Full.isEmptySet());265EXPECT_TRUE(Full.inverse().isEmptySet());266EXPECT_FALSE(Full.isWrappedSet());267EXPECT_TRUE(Full.contains(APInt(16, 0x0)));268EXPECT_TRUE(Full.contains(APInt(16, 0x9)));269EXPECT_TRUE(Full.contains(APInt(16, 0xa)));270EXPECT_TRUE(Full.contains(APInt(16, 0xaa9)));271EXPECT_TRUE(Full.contains(APInt(16, 0xaaa)));272
273EXPECT_FALSE(Empty.isFullSet());274EXPECT_TRUE(Empty.isEmptySet());275EXPECT_TRUE(Empty.inverse().isFullSet());276EXPECT_FALSE(Empty.isWrappedSet());277EXPECT_FALSE(Empty.contains(APInt(16, 0x0)));278EXPECT_FALSE(Empty.contains(APInt(16, 0x9)));279EXPECT_FALSE(Empty.contains(APInt(16, 0xa)));280EXPECT_FALSE(Empty.contains(APInt(16, 0xaa9)));281EXPECT_FALSE(Empty.contains(APInt(16, 0xaaa)));282
283EXPECT_FALSE(One.isFullSet());284EXPECT_FALSE(One.isEmptySet());285EXPECT_FALSE(One.isWrappedSet());286EXPECT_FALSE(One.contains(APInt(16, 0x0)));287EXPECT_FALSE(One.contains(APInt(16, 0x9)));288EXPECT_TRUE(One.contains(APInt(16, 0xa)));289EXPECT_FALSE(One.contains(APInt(16, 0xaa9)));290EXPECT_FALSE(One.contains(APInt(16, 0xaaa)));291EXPECT_FALSE(One.inverse().contains(APInt(16, 0xa)));292
293EXPECT_FALSE(Some.isFullSet());294EXPECT_FALSE(Some.isEmptySet());295EXPECT_FALSE(Some.isWrappedSet());296EXPECT_FALSE(Some.contains(APInt(16, 0x0)));297EXPECT_FALSE(Some.contains(APInt(16, 0x9)));298EXPECT_TRUE(Some.contains(APInt(16, 0xa)));299EXPECT_TRUE(Some.contains(APInt(16, 0xaa9)));300EXPECT_FALSE(Some.contains(APInt(16, 0xaaa)));301
302EXPECT_FALSE(Wrap.isFullSet());303EXPECT_FALSE(Wrap.isEmptySet());304EXPECT_TRUE(Wrap.isWrappedSet());305EXPECT_TRUE(Wrap.contains(APInt(16, 0x0)));306EXPECT_TRUE(Wrap.contains(APInt(16, 0x9)));307EXPECT_FALSE(Wrap.contains(APInt(16, 0xa)));308EXPECT_FALSE(Wrap.contains(APInt(16, 0xaa9)));309EXPECT_TRUE(Wrap.contains(APInt(16, 0xaaa)));310}
311
312TEST_F(ConstantRangeTest, Equality) {313EXPECT_EQ(Full, Full);314EXPECT_EQ(Empty, Empty);315EXPECT_EQ(One, One);316EXPECT_EQ(Some, Some);317EXPECT_EQ(Wrap, Wrap);318EXPECT_NE(Full, Empty);319EXPECT_NE(Full, One);320EXPECT_NE(Full, Some);321EXPECT_NE(Full, Wrap);322EXPECT_NE(Empty, One);323EXPECT_NE(Empty, Some);324EXPECT_NE(Empty, Wrap);325EXPECT_NE(One, Some);326EXPECT_NE(One, Wrap);327EXPECT_NE(Some, Wrap);328}
329
330TEST_F(ConstantRangeTest, SingleElement) {331EXPECT_EQ(Full.getSingleElement(), static_cast<APInt *>(nullptr));332EXPECT_EQ(Empty.getSingleElement(), static_cast<APInt *>(nullptr));333EXPECT_EQ(Full.getSingleMissingElement(), static_cast<APInt *>(nullptr));334EXPECT_EQ(Empty.getSingleMissingElement(), static_cast<APInt *>(nullptr));335
336EXPECT_EQ(*One.getSingleElement(), APInt(16, 0xa));337EXPECT_EQ(Some.getSingleElement(), static_cast<APInt *>(nullptr));338EXPECT_EQ(Wrap.getSingleElement(), static_cast<APInt *>(nullptr));339
340EXPECT_EQ(One.getSingleMissingElement(), static_cast<APInt *>(nullptr));341EXPECT_EQ(Some.getSingleMissingElement(), static_cast<APInt *>(nullptr));342
343ConstantRange OneInverse = One.inverse();344EXPECT_EQ(*OneInverse.getSingleMissingElement(), *One.getSingleElement());345
346EXPECT_FALSE(Full.isSingleElement());347EXPECT_FALSE(Empty.isSingleElement());348EXPECT_TRUE(One.isSingleElement());349EXPECT_FALSE(Some.isSingleElement());350EXPECT_FALSE(Wrap.isSingleElement());351}
352
353TEST_F(ConstantRangeTest, GetMinsAndMaxes) {354EXPECT_EQ(Full.getUnsignedMax(), APInt(16, UINT16_MAX));355EXPECT_EQ(One.getUnsignedMax(), APInt(16, 0xa));356EXPECT_EQ(Some.getUnsignedMax(), APInt(16, 0xaa9));357EXPECT_EQ(Wrap.getUnsignedMax(), APInt(16, UINT16_MAX));358
359EXPECT_EQ(Full.getUnsignedMin(), APInt(16, 0));360EXPECT_EQ(One.getUnsignedMin(), APInt(16, 0xa));361EXPECT_EQ(Some.getUnsignedMin(), APInt(16, 0xa));362EXPECT_EQ(Wrap.getUnsignedMin(), APInt(16, 0));363
364EXPECT_EQ(Full.getSignedMax(), APInt(16, INT16_MAX));365EXPECT_EQ(One.getSignedMax(), APInt(16, 0xa));366EXPECT_EQ(Some.getSignedMax(), APInt(16, 0xaa9));367EXPECT_EQ(Wrap.getSignedMax(), APInt(16, INT16_MAX));368
369EXPECT_EQ(Full.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));370EXPECT_EQ(One.getSignedMin(), APInt(16, 0xa));371EXPECT_EQ(Some.getSignedMin(), APInt(16, 0xa));372EXPECT_EQ(Wrap.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));373
374// Found by Klee375EXPECT_EQ(ConstantRange(APInt(4, 7), APInt(4, 0)).getSignedMax(),376APInt(4, 7));377}
378
379TEST_F(ConstantRangeTest, SignWrapped) {380EXPECT_FALSE(Full.isSignWrappedSet());381EXPECT_FALSE(Empty.isSignWrappedSet());382EXPECT_FALSE(One.isSignWrappedSet());383EXPECT_FALSE(Some.isSignWrappedSet());384EXPECT_TRUE(Wrap.isSignWrappedSet());385
386EXPECT_FALSE(ConstantRange(APInt(8, 127), APInt(8, 128)).isSignWrappedSet());387EXPECT_TRUE(ConstantRange(APInt(8, 127), APInt(8, 129)).isSignWrappedSet());388EXPECT_FALSE(ConstantRange(APInt(8, 128), APInt(8, 129)).isSignWrappedSet());389EXPECT_TRUE(ConstantRange(APInt(8, 10), APInt(8, 9)).isSignWrappedSet());390EXPECT_TRUE(ConstantRange(APInt(8, 10), APInt(8, 250)).isSignWrappedSet());391EXPECT_FALSE(ConstantRange(APInt(8, 250), APInt(8, 10)).isSignWrappedSet());392EXPECT_FALSE(ConstantRange(APInt(8, 250), APInt(8, 251)).isSignWrappedSet());393}
394
395TEST_F(ConstantRangeTest, UpperWrapped) {396// The behavior here is the same as for isWrappedSet() / isSignWrappedSet().397EXPECT_FALSE(Full.isUpperWrapped());398EXPECT_FALSE(Empty.isUpperWrapped());399EXPECT_FALSE(One.isUpperWrapped());400EXPECT_FALSE(Some.isUpperWrapped());401EXPECT_TRUE(Wrap.isUpperWrapped());402EXPECT_FALSE(Full.isUpperSignWrapped());403EXPECT_FALSE(Empty.isUpperSignWrapped());404EXPECT_FALSE(One.isUpperSignWrapped());405EXPECT_FALSE(Some.isUpperSignWrapped());406EXPECT_TRUE(Wrap.isUpperSignWrapped());407
408// The behavior differs if Upper is the Min/SignedMin value.409ConstantRange CR1(APInt(8, 42), APInt::getMinValue(8));410EXPECT_FALSE(CR1.isWrappedSet());411EXPECT_TRUE(CR1.isUpperWrapped());412
413ConstantRange CR2(APInt(8, 42), APInt::getSignedMinValue(8));414EXPECT_FALSE(CR2.isSignWrappedSet());415EXPECT_TRUE(CR2.isUpperSignWrapped());416}
417
418TEST_F(ConstantRangeTest, Trunc) {419ConstantRange TFull = Full.truncate(10);420ConstantRange TEmpty = Empty.truncate(10);421ConstantRange TOne = One.truncate(10);422ConstantRange TSome = Some.truncate(10);423ConstantRange TWrap = Wrap.truncate(10);424EXPECT_TRUE(TFull.isFullSet());425EXPECT_TRUE(TEmpty.isEmptySet());426EXPECT_EQ(TOne, ConstantRange(One.getLower().trunc(10),427One.getUpper().trunc(10)));428EXPECT_TRUE(TSome.isFullSet());429EXPECT_TRUE(TWrap.isFullSet());430
431// trunc([2, 5), 3->2) = [2, 1)432ConstantRange TwoFive(APInt(3, 2), APInt(3, 5));433EXPECT_EQ(TwoFive.truncate(2), ConstantRange(APInt(2, 2), APInt(2, 1)));434
435// trunc([2, 6), 3->2) = full436ConstantRange TwoSix(APInt(3, 2), APInt(3, 6));437EXPECT_TRUE(TwoSix.truncate(2).isFullSet());438
439// trunc([5, 7), 3->2) = [1, 3)440ConstantRange FiveSeven(APInt(3, 5), APInt(3, 7));441EXPECT_EQ(FiveSeven.truncate(2), ConstantRange(APInt(2, 1), APInt(2, 3)));442
443// trunc([7, 1), 3->2) = [3, 1)444ConstantRange SevenOne(APInt(3, 7), APInt(3, 1));445EXPECT_EQ(SevenOne.truncate(2), ConstantRange(APInt(2, 3), APInt(2, 1)));446}
447
448TEST_F(ConstantRangeTest, ZExt) {449ConstantRange ZFull = Full.zeroExtend(20);450ConstantRange ZEmpty = Empty.zeroExtend(20);451ConstantRange ZOne = One.zeroExtend(20);452ConstantRange ZSome = Some.zeroExtend(20);453ConstantRange ZWrap = Wrap.zeroExtend(20);454EXPECT_EQ(ZFull, ConstantRange(APInt(20, 0), APInt(20, 0x10000)));455EXPECT_TRUE(ZEmpty.isEmptySet());456EXPECT_EQ(ZOne, ConstantRange(One.getLower().zext(20),457One.getUpper().zext(20)));458EXPECT_EQ(ZSome, ConstantRange(Some.getLower().zext(20),459Some.getUpper().zext(20)));460EXPECT_EQ(ZWrap, ConstantRange(APInt(20, 0), APInt(20, 0x10000)));461
462// zext([5, 0), 3->7) = [5, 8)463ConstantRange FiveZero(APInt(3, 5), APInt(3, 0));464EXPECT_EQ(FiveZero.zeroExtend(7), ConstantRange(APInt(7, 5), APInt(7, 8)));465}
466
467TEST_F(ConstantRangeTest, SExt) {468ConstantRange SFull = Full.signExtend(20);469ConstantRange SEmpty = Empty.signExtend(20);470ConstantRange SOne = One.signExtend(20);471ConstantRange SSome = Some.signExtend(20);472ConstantRange SWrap = Wrap.signExtend(20);473EXPECT_EQ(SFull, ConstantRange(APInt(20, (uint64_t)INT16_MIN, true),474APInt(20, INT16_MAX + 1, true)));475EXPECT_TRUE(SEmpty.isEmptySet());476EXPECT_EQ(SOne, ConstantRange(One.getLower().sext(20),477One.getUpper().sext(20)));478EXPECT_EQ(SSome, ConstantRange(Some.getLower().sext(20),479Some.getUpper().sext(20)));480EXPECT_EQ(SWrap, ConstantRange(APInt(20, (uint64_t)INT16_MIN, true),481APInt(20, INT16_MAX + 1, true)));482
483EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, 140)).signExtend(16),484ConstantRange(APInt(16, -128), APInt(16, 128)));485
486EXPECT_EQ(ConstantRange(APInt(16, 0x0200), APInt(16, 0x8000)).signExtend(19),487ConstantRange(APInt(19, 0x0200), APInt(19, 0x8000)));488}
489
490TEST_F(ConstantRangeTest, IntersectWith) {491EXPECT_EQ(Empty.intersectWith(Full), Empty);492EXPECT_EQ(Empty.intersectWith(Empty), Empty);493EXPECT_EQ(Empty.intersectWith(One), Empty);494EXPECT_EQ(Empty.intersectWith(Some), Empty);495EXPECT_EQ(Empty.intersectWith(Wrap), Empty);496EXPECT_EQ(Full.intersectWith(Full), Full);497EXPECT_EQ(Some.intersectWith(Some), Some);498EXPECT_EQ(Some.intersectWith(One), One);499EXPECT_EQ(Full.intersectWith(One), One);500EXPECT_EQ(Full.intersectWith(Some), Some);501EXPECT_EQ(Some.intersectWith(Wrap), Empty);502EXPECT_EQ(One.intersectWith(Wrap), Empty);503EXPECT_EQ(One.intersectWith(Wrap), Wrap.intersectWith(One));504
505// Klee generated testcase from PR4545.506// The intersection of i16 [4, 2) and [6, 5) is disjoint, looking like507// 01..4.6789ABCDEF where the dots represent values not in the intersection.508ConstantRange LHS(APInt(16, 4), APInt(16, 2));509ConstantRange RHS(APInt(16, 6), APInt(16, 5));510EXPECT_TRUE(LHS.intersectWith(RHS) == LHS);511
512// previous bug: intersection of [min, 3) and [2, max) should be 2513LHS = ConstantRange(APInt(32, -2147483646), APInt(32, 3));514RHS = ConstantRange(APInt(32, 2), APInt(32, 2147483646));515EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2)));516
517// [2, 0) /\ [4, 3) = [2, 0)518LHS = ConstantRange(APInt(32, 2), APInt(32, 0));519RHS = ConstantRange(APInt(32, 4), APInt(32, 3));520EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2), APInt(32, 0)));521
522// [2, 0) /\ [4, 2) = [4, 0)523LHS = ConstantRange(APInt(32, 2), APInt(32, 0));524RHS = ConstantRange(APInt(32, 4), APInt(32, 2));525EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 0)));526
527// [4, 2) /\ [5, 1) = [5, 1)528LHS = ConstantRange(APInt(32, 4), APInt(32, 2));529RHS = ConstantRange(APInt(32, 5), APInt(32, 1));530EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 5), APInt(32, 1)));531
532// [2, 0) /\ [7, 4) = [7, 4)533LHS = ConstantRange(APInt(32, 2), APInt(32, 0));534RHS = ConstantRange(APInt(32, 7), APInt(32, 4));535EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 7), APInt(32, 4)));536
537// [4, 2) /\ [1, 0) = [1, 0)538LHS = ConstantRange(APInt(32, 4), APInt(32, 2));539RHS = ConstantRange(APInt(32, 1), APInt(32, 0));540EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 2)));541
542// [15, 0) /\ [7, 6) = [15, 0)543LHS = ConstantRange(APInt(32, 15), APInt(32, 0));544RHS = ConstantRange(APInt(32, 7), APInt(32, 6));545EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 15), APInt(32, 0)));546}
547
548template <typename Fn1, typename Fn2, typename Fn3>549void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 ExactOpFn, Fn3 InResultFn) {550EnumerateTwoInterestingConstantRanges(551[=](const ConstantRange &CR1, const ConstantRange &CR2) {552unsigned Bits = CR1.getBitWidth();553SmallBitVector Elems(1 << Bits);554APInt Num(Bits, 0);555for (unsigned I = 0, Limit = 1 << Bits; I < Limit; ++I, ++Num)556if (InResultFn(CR1, CR2, Num))557Elems.set(Num.getZExtValue());558
559ConstantRange SmallestCR = OpFn(CR1, CR2, ConstantRange::Smallest);560TestRange(SmallestCR, Elems, PreferSmallest, {CR1, CR2});561
562ConstantRange UnsignedCR = OpFn(CR1, CR2, ConstantRange::Unsigned);563TestRange(UnsignedCR, Elems, PreferSmallestNonFullUnsigned, {CR1, CR2});564
565ConstantRange SignedCR = OpFn(CR1, CR2, ConstantRange::Signed);566TestRange(SignedCR, Elems, PreferSmallestNonFullSigned, {CR1, CR2});567
568std::optional<ConstantRange> ExactCR = ExactOpFn(CR1, CR2);569if (SmallestCR.isSizeLargerThan(Elems.count())) {570EXPECT_TRUE(!ExactCR);571} else {572EXPECT_EQ(SmallestCR, *ExactCR);573}574});575}
576
577TEST_F(ConstantRangeTest, IntersectWithExhaustive) {578testBinarySetOperationExhaustive(579[](const ConstantRange &CR1, const ConstantRange &CR2,580ConstantRange::PreferredRangeType Type) {581return CR1.intersectWith(CR2, Type);582},583[](const ConstantRange &CR1, const ConstantRange &CR2) {584return CR1.exactIntersectWith(CR2);585},586[](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {587return CR1.contains(N) && CR2.contains(N);588});589}
590
591TEST_F(ConstantRangeTest, UnionWithExhaustive) {592testBinarySetOperationExhaustive(593[](const ConstantRange &CR1, const ConstantRange &CR2,594ConstantRange::PreferredRangeType Type) {595return CR1.unionWith(CR2, Type);596},597[](const ConstantRange &CR1, const ConstantRange &CR2) {598return CR1.exactUnionWith(CR2);599},600[](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {601return CR1.contains(N) || CR2.contains(N);602});603}
604
605TEST_F(ConstantRangeTest, UnionWith) {606EXPECT_EQ(Wrap.unionWith(One),607ConstantRange(APInt(16, 0xaaa), APInt(16, 0xb)));608EXPECT_EQ(One.unionWith(Wrap), Wrap.unionWith(One));609EXPECT_EQ(Empty.unionWith(Empty), Empty);610EXPECT_EQ(Full.unionWith(Full), Full);611EXPECT_EQ(Some.unionWith(Wrap), Full);612
613// PR4545614EXPECT_EQ(ConstantRange(APInt(16, 14), APInt(16, 1)).unionWith(615ConstantRange(APInt(16, 0), APInt(16, 8))),616ConstantRange(APInt(16, 14), APInt(16, 8)));617EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(618ConstantRange(APInt(16, 4), APInt(16, 0))),619ConstantRange::getFull(16));620EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(621ConstantRange(APInt(16, 2), APInt(16, 1))),622ConstantRange::getFull(16));623}
624
625TEST_F(ConstantRangeTest, SetDifference) {626EXPECT_EQ(Full.difference(Empty), Full);627EXPECT_EQ(Full.difference(Full), Empty);628EXPECT_EQ(Empty.difference(Empty), Empty);629EXPECT_EQ(Empty.difference(Full), Empty);630
631ConstantRange A(APInt(16, 3), APInt(16, 7));632ConstantRange B(APInt(16, 5), APInt(16, 9));633ConstantRange C(APInt(16, 3), APInt(16, 5));634ConstantRange D(APInt(16, 7), APInt(16, 9));635ConstantRange E(APInt(16, 5), APInt(16, 4));636ConstantRange F(APInt(16, 7), APInt(16, 3));637EXPECT_EQ(A.difference(B), C);638EXPECT_EQ(B.difference(A), D);639EXPECT_EQ(E.difference(A), F);640}
641
642TEST_F(ConstantRangeTest, getActiveBits) {643EnumerateInterestingConstantRanges([&](const ConstantRange &CR) {644unsigned Exact = 0;645ForeachNumInConstantRange(CR, [&](const APInt &N) {646Exact = std::max(Exact, N.getActiveBits());647});648
649unsigned ResultCR = CR.getActiveBits();650EXPECT_EQ(Exact, ResultCR);651});652}
653TEST_F(ConstantRangeTest, losslessUnsignedTruncationZeroext) {654EnumerateInterestingConstantRanges([&](const ConstantRange &CR) {655unsigned Bits = CR.getBitWidth();656unsigned MinBitWidth = CR.getActiveBits();657if (MinBitWidth == 0) {658EXPECT_TRUE(CR.isEmptySet() ||659(CR.isSingleElement() && CR.getSingleElement()->isZero()));660return;661}662if (MinBitWidth == Bits)663return;664EXPECT_EQ(CR, CR.truncate(MinBitWidth).zeroExtend(Bits));665});666}
667
668TEST_F(ConstantRangeTest, getMinSignedBits) {669EnumerateInterestingConstantRanges([&](const ConstantRange &CR) {670unsigned Exact = 0;671ForeachNumInConstantRange(CR, [&](const APInt &N) {672Exact = std::max(Exact, N.getSignificantBits());673});674
675unsigned ResultCR = CR.getMinSignedBits();676EXPECT_EQ(Exact, ResultCR);677});678}
679TEST_F(ConstantRangeTest, losslessSignedTruncationSignext) {680EnumerateInterestingConstantRanges([&](const ConstantRange &CR) {681unsigned Bits = CR.getBitWidth();682unsigned MinBitWidth = CR.getMinSignedBits();683if (MinBitWidth == 0) {684EXPECT_TRUE(CR.isEmptySet());685return;686}687if (MinBitWidth == Bits)688return;689EXPECT_EQ(CR, CR.truncate(MinBitWidth).signExtend(Bits));690});691}
692
693TEST_F(ConstantRangeTest, SubtractAPInt) {694EXPECT_EQ(Full.subtract(APInt(16, 4)), Full);695EXPECT_EQ(Empty.subtract(APInt(16, 4)), Empty);696EXPECT_EQ(Some.subtract(APInt(16, 4)),697ConstantRange(APInt(16, 0x6), APInt(16, 0xaa6)));698EXPECT_EQ(Wrap.subtract(APInt(16, 4)),699ConstantRange(APInt(16, 0xaa6), APInt(16, 0x6)));700EXPECT_EQ(One.subtract(APInt(16, 4)),701ConstantRange(APInt(16, 0x6)));702}
703
704TEST_F(ConstantRangeTest, Add) {705EXPECT_EQ(Full.add(APInt(16, 4)), Full);706EXPECT_EQ(Full.add(Full), Full);707EXPECT_EQ(Full.add(Empty), Empty);708EXPECT_EQ(Full.add(One), Full);709EXPECT_EQ(Full.add(Some), Full);710EXPECT_EQ(Full.add(Wrap), Full);711EXPECT_EQ(Empty.add(Empty), Empty);712EXPECT_EQ(Empty.add(One), Empty);713EXPECT_EQ(Empty.add(Some), Empty);714EXPECT_EQ(Empty.add(Wrap), Empty);715EXPECT_EQ(Empty.add(APInt(16, 4)), Empty);716EXPECT_EQ(Some.add(APInt(16, 4)),717ConstantRange(APInt(16, 0xe), APInt(16, 0xaae)));718EXPECT_EQ(Wrap.add(APInt(16, 4)),719ConstantRange(APInt(16, 0xaae), APInt(16, 0xe)));720EXPECT_EQ(One.add(APInt(16, 4)),721ConstantRange(APInt(16, 0xe)));722
723TestBinaryOpExhaustive(724[](const ConstantRange &CR1, const ConstantRange &CR2) {725return CR1.add(CR2);726},727[](const APInt &N1, const APInt &N2) {728return N1 + N2;729});730}
731
732TEST_F(ConstantRangeTest, AddWithNoWrap) {733typedef OverflowingBinaryOperator OBO;734EXPECT_EQ(Empty.addWithNoWrap(Some, OBO::NoSignedWrap), Empty);735EXPECT_EQ(Some.addWithNoWrap(Empty, OBO::NoSignedWrap), Empty);736EXPECT_EQ(Full.addWithNoWrap(Full, OBO::NoSignedWrap), Full);737EXPECT_NE(Full.addWithNoWrap(Some, OBO::NoSignedWrap), Full);738EXPECT_NE(Some.addWithNoWrap(Full, OBO::NoSignedWrap), Full);739EXPECT_EQ(Full.addWithNoWrap(ConstantRange(APInt(16, 1), APInt(16, 2)),740OBO::NoSignedWrap),741ConstantRange(APInt(16, INT16_MIN + 1), APInt(16, INT16_MIN)));742EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 2))743.addWithNoWrap(Full, OBO::NoSignedWrap),744ConstantRange(APInt(16, INT16_MIN + 1), APInt(16, INT16_MIN)));745EXPECT_EQ(Full.addWithNoWrap(ConstantRange(APInt(16, -1), APInt(16, 0)),746OBO::NoSignedWrap),747ConstantRange(APInt(16, INT16_MIN), APInt(16, INT16_MAX)));748EXPECT_EQ(ConstantRange(APInt(8, 100), APInt(8, 120))749.addWithNoWrap(ConstantRange(APInt(8, 120), APInt(8, 123)),750OBO::NoSignedWrap),751ConstantRange(8, false));752EXPECT_EQ(ConstantRange(APInt(8, -120), APInt(8, -100))753.addWithNoWrap(ConstantRange(APInt(8, -110), APInt(8, -100)),754OBO::NoSignedWrap),755ConstantRange(8, false));756EXPECT_EQ(ConstantRange(APInt(8, 0), APInt(8, 101))757.addWithNoWrap(ConstantRange(APInt(8, -128), APInt(8, 28)),758OBO::NoSignedWrap),759ConstantRange(8, true));760EXPECT_EQ(ConstantRange(APInt(8, 0), APInt(8, 101))761.addWithNoWrap(ConstantRange(APInt(8, -120), APInt(8, 29)),762OBO::NoSignedWrap),763ConstantRange(APInt(8, -120), APInt(8, -128)));764EXPECT_EQ(ConstantRange(APInt(8, -50), APInt(8, 50))765.addWithNoWrap(ConstantRange(APInt(8, 10), APInt(8, 20)),766OBO::NoSignedWrap),767ConstantRange(APInt(8, -40), APInt(8, 69)));768EXPECT_EQ(ConstantRange(APInt(8, 10), APInt(8, 20))769.addWithNoWrap(ConstantRange(APInt(8, -50), APInt(8, 50)),770OBO::NoSignedWrap),771ConstantRange(APInt(8, -40), APInt(8, 69)));772EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -10))773.addWithNoWrap(ConstantRange(APInt(8, 5), APInt(8, 20)),774OBO::NoSignedWrap),775ConstantRange(APInt(8, 125), APInt(8, 9)));776EXPECT_EQ(ConstantRange(APInt(8, 5), APInt(8, 20))777.addWithNoWrap(ConstantRange(APInt(8, 120), APInt(8, -10)),778OBO::NoSignedWrap),779ConstantRange(APInt(8, 125), APInt(8, 9)));780
781TestBinaryOpExhaustive(782[](const ConstantRange &CR1, const ConstantRange &CR2) {783return CR1.addWithNoWrap(CR2, OBO::NoSignedWrap);784},785[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {786bool IsOverflow;787APInt Res = N1.sadd_ov(N2, IsOverflow);788if (IsOverflow)789return std::nullopt;790return Res;791},792PreferSmallest, CheckNonSignWrappedOnly);793
794EXPECT_EQ(Empty.addWithNoWrap(Some, OBO::NoUnsignedWrap), Empty);795EXPECT_EQ(Some.addWithNoWrap(Empty, OBO::NoUnsignedWrap), Empty);796EXPECT_EQ(Full.addWithNoWrap(Full, OBO::NoUnsignedWrap), Full);797EXPECT_NE(Full.addWithNoWrap(Some, OBO::NoUnsignedWrap), Full);798EXPECT_NE(Some.addWithNoWrap(Full, OBO::NoUnsignedWrap), Full);799EXPECT_EQ(Full.addWithNoWrap(ConstantRange(APInt(16, 1), APInt(16, 2)),800OBO::NoUnsignedWrap),801ConstantRange(APInt(16, 1), APInt(16, 0)));802EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 2))803.addWithNoWrap(Full, OBO::NoUnsignedWrap),804ConstantRange(APInt(16, 1), APInt(16, 0)));805EXPECT_EQ(ConstantRange(APInt(8, 200), APInt(8, 220))806.addWithNoWrap(ConstantRange(APInt(8, 100), APInt(8, 123)),807OBO::NoUnsignedWrap),808ConstantRange(8, false));809EXPECT_EQ(ConstantRange(APInt(8, 0), APInt(8, 101))810.addWithNoWrap(ConstantRange(APInt(8, 0), APInt(8, 156)),811OBO::NoUnsignedWrap),812ConstantRange(8, true));813EXPECT_EQ(ConstantRange(APInt(8, 0), APInt(8, 101))814.addWithNoWrap(ConstantRange(APInt(8, 10), APInt(8, 29)),815OBO::NoUnsignedWrap),816ConstantRange(APInt(8, 10), APInt(8, 129)));817EXPECT_EQ(ConstantRange(APInt(8, 20), APInt(8, 10))818.addWithNoWrap(ConstantRange(APInt(8, 50), APInt(8, 200)),819OBO::NoUnsignedWrap),820ConstantRange(APInt(8, 50), APInt(8, 0)));821EXPECT_EQ(ConstantRange(APInt(8, 10), APInt(8, 20))822.addWithNoWrap(ConstantRange(APInt(8, 50), APInt(8, 200)),823OBO::NoUnsignedWrap),824ConstantRange(APInt(8, 60), APInt(8, -37)));825EXPECT_EQ(ConstantRange(APInt(8, 20), APInt(8, -30))826.addWithNoWrap(ConstantRange(APInt(8, 5), APInt(8, 20)),827OBO::NoUnsignedWrap),828ConstantRange(APInt(8, 25), APInt(8, -11)));829EXPECT_EQ(ConstantRange(APInt(8, 5), APInt(8, 20))830.addWithNoWrap(ConstantRange(APInt(8, 20), APInt(8, -30)),831OBO::NoUnsignedWrap),832ConstantRange(APInt(8, 25), APInt(8, -11)));833
834TestBinaryOpExhaustive(835[](const ConstantRange &CR1, const ConstantRange &CR2) {836return CR1.addWithNoWrap(CR2, OBO::NoUnsignedWrap);837},838[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {839bool IsOverflow;840APInt Res = N1.uadd_ov(N2, IsOverflow);841if (IsOverflow)842return std::nullopt;843return Res;844},845PreferSmallest, CheckNonWrappedOnly);846
847EXPECT_EQ(ConstantRange(APInt(8, 50), APInt(8, 100))848.addWithNoWrap(ConstantRange(APInt(8, 20), APInt(8, 70)),849OBO::NoSignedWrap),850ConstantRange(APInt(8, 70), APInt(8, -128)));851EXPECT_EQ(ConstantRange(APInt(8, 50), APInt(8, 100))852.addWithNoWrap(ConstantRange(APInt(8, 20), APInt(8, 70)),853OBO::NoUnsignedWrap),854ConstantRange(APInt(8, 70), APInt(8, 169)));855EXPECT_EQ(ConstantRange(APInt(8, 50), APInt(8, 100))856.addWithNoWrap(ConstantRange(APInt(8, 20), APInt(8, 70)),857OBO::NoUnsignedWrap | OBO::NoSignedWrap),858ConstantRange(APInt(8, 70), APInt(8, -128)));859
860EXPECT_EQ(ConstantRange(APInt(8, -100), APInt(8, -50))861.addWithNoWrap(ConstantRange(APInt(8, 20), APInt(8, 30)),862OBO::NoSignedWrap),863ConstantRange(APInt(8, -80), APInt(8, -21)));864EXPECT_EQ(ConstantRange(APInt(8, -100), APInt(8, -50))865.addWithNoWrap(ConstantRange(APInt(8, 20), APInt(8, 30)),866OBO::NoUnsignedWrap),867ConstantRange(APInt(8, 176), APInt(8, 235)));868EXPECT_EQ(ConstantRange(APInt(8, -100), APInt(8, -50))869.addWithNoWrap(ConstantRange(APInt(8, 20), APInt(8, 30)),870OBO::NoUnsignedWrap | OBO::NoSignedWrap),871ConstantRange(APInt(8, 176), APInt(8, 235)));872
873TestBinaryOpExhaustive(874[](const ConstantRange &CR1, const ConstantRange &CR2) {875return CR1.addWithNoWrap(CR2, OBO::NoUnsignedWrap | OBO::NoSignedWrap);876},877[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {878bool IsOverflow1, IsOverflow2;879APInt Res1 = N1.uadd_ov(N2, IsOverflow1);880APInt Res2 = N1.sadd_ov(N2, IsOverflow2);881if (IsOverflow1 || IsOverflow2)882return std::nullopt;883assert(Res1 == Res2 && "Addition results differ?");884return Res1;885},886PreferSmallest, CheckNonWrappedOrSignWrappedOnly);887}
888
889TEST_F(ConstantRangeTest, Sub) {890EXPECT_EQ(Full.sub(APInt(16, 4)), Full);891EXPECT_EQ(Full.sub(Full), Full);892EXPECT_EQ(Full.sub(Empty), Empty);893EXPECT_EQ(Full.sub(One), Full);894EXPECT_EQ(Full.sub(Some), Full);895EXPECT_EQ(Full.sub(Wrap), Full);896EXPECT_EQ(Empty.sub(Empty), Empty);897EXPECT_EQ(Empty.sub(One), Empty);898EXPECT_EQ(Empty.sub(Some), Empty);899EXPECT_EQ(Empty.sub(Wrap), Empty);900EXPECT_EQ(Empty.sub(APInt(16, 4)), Empty);901EXPECT_EQ(Some.sub(APInt(16, 4)),902ConstantRange(APInt(16, 0x6), APInt(16, 0xaa6)));903EXPECT_EQ(Some.sub(Some),904ConstantRange(APInt(16, 0xf561), APInt(16, 0xaa0)));905EXPECT_EQ(Wrap.sub(APInt(16, 4)),906ConstantRange(APInt(16, 0xaa6), APInt(16, 0x6)));907EXPECT_EQ(One.sub(APInt(16, 4)),908ConstantRange(APInt(16, 0x6)));909
910TestBinaryOpExhaustive(911[](const ConstantRange &CR1, const ConstantRange &CR2) {912return CR1.sub(CR2);913},914[](const APInt &N1, const APInt &N2) {915return N1 - N2;916});917}
918
919TEST_F(ConstantRangeTest, SubWithNoWrap) {920typedef OverflowingBinaryOperator OBO;921TestBinaryOpExhaustive(922[](const ConstantRange &CR1, const ConstantRange &CR2) {923return CR1.subWithNoWrap(CR2, OBO::NoSignedWrap);924},925[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {926bool IsOverflow;927APInt Res = N1.ssub_ov(N2, IsOverflow);928if (IsOverflow)929return std::nullopt;930return Res;931},932PreferSmallest, CheckNonSignWrappedOnly);933TestBinaryOpExhaustive(934[](const ConstantRange &CR1, const ConstantRange &CR2) {935return CR1.subWithNoWrap(CR2, OBO::NoUnsignedWrap);936},937[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {938bool IsOverflow;939APInt Res = N1.usub_ov(N2, IsOverflow);940if (IsOverflow)941return std::nullopt;942return Res;943},944PreferSmallest, CheckNonWrappedOnly);945TestBinaryOpExhaustive(946[](const ConstantRange &CR1, const ConstantRange &CR2) {947return CR1.subWithNoWrap(CR2, OBO::NoUnsignedWrap | OBO::NoSignedWrap);948},949[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {950bool IsOverflow1, IsOverflow2;951APInt Res1 = N1.usub_ov(N2, IsOverflow1);952APInt Res2 = N1.ssub_ov(N2, IsOverflow2);953if (IsOverflow1 || IsOverflow2)954return std::nullopt;955assert(Res1 == Res2 && "Subtraction results differ?");956return Res1;957},958PreferSmallest, CheckNonWrappedOrSignWrappedOnly);959}
960
961TEST_F(ConstantRangeTest, Multiply) {962EXPECT_EQ(Full.multiply(Full), Full);963EXPECT_EQ(Full.multiply(Empty), Empty);964EXPECT_EQ(Full.multiply(One), Full);965EXPECT_EQ(Full.multiply(Some), Full);966EXPECT_EQ(Full.multiply(Wrap), Full);967EXPECT_EQ(Empty.multiply(Empty), Empty);968EXPECT_EQ(Empty.multiply(One), Empty);969EXPECT_EQ(Empty.multiply(Some), Empty);970EXPECT_EQ(Empty.multiply(Wrap), Empty);971EXPECT_EQ(One.multiply(One), ConstantRange(APInt(16, 0xa*0xa),972APInt(16, 0xa*0xa + 1)));973EXPECT_EQ(One.multiply(Some), ConstantRange(APInt(16, 0xa*0xa),974APInt(16, 0xa*0xaa9 + 1)));975EXPECT_EQ(One.multiply(Wrap), Full);976EXPECT_EQ(Some.multiply(Some), Full);977EXPECT_EQ(Some.multiply(Wrap), Full);978EXPECT_EQ(Wrap.multiply(Wrap), Full);979
980ConstantRange Zero(APInt(16, 0));981EXPECT_EQ(Zero.multiply(Full), Zero);982EXPECT_EQ(Zero.multiply(Some), Zero);983EXPECT_EQ(Zero.multiply(Wrap), Zero);984EXPECT_EQ(Full.multiply(Zero), Zero);985EXPECT_EQ(Some.multiply(Zero), Zero);986EXPECT_EQ(Wrap.multiply(Zero), Zero);987
988// http://llvm.org/PR4545989EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 6)).multiply(990ConstantRange(APInt(4, 6), APInt(4, 2))),991ConstantRange(4, /*isFullSet=*/true));992
993EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 0)).multiply(994ConstantRange(APInt(8, 252), APInt(8, 4))),995ConstantRange(APInt(8, 250), APInt(8, 9)));996EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 255)).multiply(997ConstantRange(APInt(8, 2), APInt(8, 4))),998ConstantRange(APInt(8, 250), APInt(8, 253)));999
1000// TODO: This should be return [-2, 0]1001EXPECT_EQ(ConstantRange(APInt(8, -2)).multiply(1002ConstantRange(APInt(8, 0), APInt(8, 2))),1003ConstantRange(APInt(8, -2), APInt(8, 1)));1004
1005// Multiplication by -1 should give precise results.1006EXPECT_EQ(ConstantRange(APInt(8, 3), APInt(8, -11))1007.multiply(ConstantRange(APInt(8, -1))),1008ConstantRange(APInt(8, 12), APInt(8, -2)));1009EXPECT_EQ(ConstantRange(APInt(8, -1))1010.multiply(ConstantRange(APInt(8, 3), APInt(8, -11))),1011ConstantRange(APInt(8, 12), APInt(8, -2)));1012
1013TestBinaryOpExhaustive(1014[](const ConstantRange &CR1, const ConstantRange &CR2) {1015return CR1.multiply(CR2);1016},1017[](const APInt &N1, const APInt &N2) {1018return N1 * N2;1019},1020PreferSmallest,1021[](const ConstantRange &, const ConstantRange &) {1022return false; // Check correctness only.1023});1024}
1025
1026TEST_F(ConstantRangeTest, MultiplyWithNoWrap) {1027using OBO = OverflowingBinaryOperator;1028
1029EXPECT_EQ(Empty.multiplyWithNoWrap(Some, OBO::NoUnsignedWrap), Empty);1030EXPECT_EQ(Some.multiplyWithNoWrap(Empty, OBO::NoUnsignedWrap), Empty);1031EXPECT_EQ(Full.multiplyWithNoWrap(Full, OBO::NoUnsignedWrap), Full);1032EXPECT_EQ(Full.multiplyWithNoWrap(Some, OBO::NoUnsignedWrap), Full);1033EXPECT_EQ(Some.multiplyWithNoWrap(Full, OBO::NoUnsignedWrap), Full);1034EXPECT_EQ(ConstantRange(APInt(4, 0), APInt(4, 2))1035.multiplyWithNoWrap(ConstantRange(APInt(4, 2), APInt(4, 0)),1036OBO::NoUnsignedWrap),1037ConstantRange::getFull(4));1038EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 5))1039.multiplyWithNoWrap(ConstantRange(APInt(4, 1), APInt(4, 5)),1040OBO::NoUnsignedWrap),1041ConstantRange(APInt(4, 1), APInt(4, 0)));1042EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 0))1043.multiplyWithNoWrap(ConstantRange(APInt(8, 252), APInt(8, 4)),1044OBO::NoUnsignedWrap),1045ConstantRange(APInt(8, 250), APInt(8, 9)));1046EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 255))1047.multiplyWithNoWrap(ConstantRange(APInt(8, 2), APInt(8, 4)),1048OBO::NoUnsignedWrap),1049ConstantRange::getEmpty(8));1050
1051EXPECT_EQ(Empty.multiplyWithNoWrap(Some, OBO::NoSignedWrap), Empty);1052EXPECT_EQ(Some.multiplyWithNoWrap(Empty, OBO::NoSignedWrap), Empty);1053EXPECT_EQ(Full.multiplyWithNoWrap(Full, OBO::NoSignedWrap), Full);1054EXPECT_EQ(Full.multiplyWithNoWrap(Some, OBO::NoSignedWrap), Full);1055EXPECT_EQ(Some.multiplyWithNoWrap(Full, OBO::NoSignedWrap), Full);1056EXPECT_EQ(1057ConstantRange(APInt(4, 0), APInt(4, 4))1058.multiplyWithNoWrap(ConstantRange(APInt(4, -5, true), APInt(4, 4)),1059OBO::NoSignedWrap),1060ConstantRange::getFull(4));1061EXPECT_EQ(ConstantRange(APInt(4, 0), APInt(4, 3))1062.multiplyWithNoWrap(ConstantRange(APInt(4, 0), APInt(4, 5)),1063OBO::NoSignedWrap),1064ConstantRange(APInt(4, 0), APInt(4, -8, true)));1065EXPECT_EQ(ConstantRange(APInt(8, 3), APInt(8, -11, true))1066.multiplyWithNoWrap(ConstantRange(APInt(8, -1, true)),1067OBO::NoSignedWrap),1068ConstantRange(APInt(8, 12), APInt(8, -2, true)));1069EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 255))1070.multiplyWithNoWrap(ConstantRange(APInt(8, 100), APInt(8, 121)),1071OBO::NoSignedWrap),1072ConstantRange::getEmpty(8));1073
1074TestBinaryOpExhaustive(1075[](const ConstantRange &CR1, const ConstantRange &CR2) {1076return CR1.multiplyWithNoWrap(CR2, OBO::NoUnsignedWrap);1077},1078[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {1079bool IsOverflow;1080APInt Res = N1.umul_ov(N2, IsOverflow);1081if (IsOverflow)1082return std::nullopt;1083return Res;1084},1085PreferSmallest, CheckCorrectnessOnly);1086TestBinaryOpExhaustive(1087[](const ConstantRange &CR1, const ConstantRange &CR2) {1088return CR1.multiplyWithNoWrap(CR2, OBO::NoSignedWrap);1089},1090[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {1091bool IsOverflow;1092APInt Res = N1.smul_ov(N2, IsOverflow);1093if (IsOverflow)1094return std::nullopt;1095return Res;1096},1097PreferSmallest, CheckCorrectnessOnly);1098TestBinaryOpExhaustive(1099[](const ConstantRange &CR1, const ConstantRange &CR2) {1100return CR1.multiplyWithNoWrap(CR2,1101OBO::NoUnsignedWrap | OBO::NoSignedWrap);1102},1103[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {1104bool IsOverflow1, IsOverflow2;1105APInt Res1 = N1.umul_ov(N2, IsOverflow1);1106APInt Res2 = N1.smul_ov(N2, IsOverflow2);1107if (IsOverflow1 || IsOverflow2)1108return std::nullopt;1109assert(Res1 == Res2 && "Multiplication results differ?");1110return Res1;1111},1112PreferSmallest, CheckCorrectnessOnly);1113}
1114
1115TEST_F(ConstantRangeTest, smul_fast) {1116TestBinaryOpExhaustive(1117[](const ConstantRange &CR1, const ConstantRange &CR2) {1118return CR1.smul_fast(CR2);1119},1120[](const APInt &N1, const APInt &N2) { return N1 * N2; }, PreferSmallest,1121CheckCorrectnessOnly);1122}
1123
1124TEST_F(ConstantRangeTest, UMax) {1125EXPECT_EQ(Full.umax(Full), Full);1126EXPECT_EQ(Full.umax(Empty), Empty);1127EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));1128EXPECT_EQ(Full.umax(Wrap), Full);1129EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));1130EXPECT_EQ(Empty.umax(Empty), Empty);1131EXPECT_EQ(Empty.umax(Some), Empty);1132EXPECT_EQ(Empty.umax(Wrap), Empty);1133EXPECT_EQ(Empty.umax(One), Empty);1134EXPECT_EQ(Some.umax(Some), Some);1135EXPECT_EQ(Some.umax(Wrap), ConstantRange(APInt(16, 0xa), APInt(16, 0)));1136EXPECT_EQ(Some.umax(One), Some);1137EXPECT_EQ(Wrap.umax(Wrap), Wrap);1138EXPECT_EQ(Wrap.umax(One), ConstantRange(APInt(16, 0xa), APInt(16, 0)));1139EXPECT_EQ(One.umax(One), One);1140
1141TestBinaryOpExhaustive(1142[](const ConstantRange &CR1, const ConstantRange &CR2) {1143return CR1.umax(CR2);1144},1145[](const APInt &N1, const APInt &N2) {1146return APIntOps::umax(N1, N2);1147},1148PreferSmallestNonFullUnsigned);1149}
1150
1151TEST_F(ConstantRangeTest, SMax) {1152EXPECT_EQ(Full.smax(Full), Full);1153EXPECT_EQ(Full.smax(Empty), Empty);1154EXPECT_EQ(Full.smax(Some), ConstantRange(APInt(16, 0xa),1155APInt::getSignedMinValue(16)));1156EXPECT_EQ(Full.smax(Wrap), Full);1157EXPECT_EQ(Full.smax(One), ConstantRange(APInt(16, 0xa),1158APInt::getSignedMinValue(16)));1159EXPECT_EQ(Empty.smax(Empty), Empty);1160EXPECT_EQ(Empty.smax(Some), Empty);1161EXPECT_EQ(Empty.smax(Wrap), Empty);1162EXPECT_EQ(Empty.smax(One), Empty);1163EXPECT_EQ(Some.smax(Some), Some);1164EXPECT_EQ(Some.smax(Wrap), ConstantRange(APInt(16, 0xa),1165APInt(16, (uint64_t)INT16_MIN)));1166EXPECT_EQ(Some.smax(One), Some);1167EXPECT_EQ(Wrap.smax(One), ConstantRange(APInt(16, 0xa),1168APInt(16, (uint64_t)INT16_MIN)));1169EXPECT_EQ(One.smax(One), One);1170
1171TestBinaryOpExhaustive(1172[](const ConstantRange &CR1, const ConstantRange &CR2) {1173return CR1.smax(CR2);1174},1175[](const APInt &N1, const APInt &N2) {1176return APIntOps::smax(N1, N2);1177},1178PreferSmallestNonFullSigned);1179}
1180
1181TEST_F(ConstantRangeTest, UMin) {1182EXPECT_EQ(Full.umin(Full), Full);1183EXPECT_EQ(Full.umin(Empty), Empty);1184EXPECT_EQ(Full.umin(Some), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));1185EXPECT_EQ(Full.umin(Wrap), Full);1186EXPECT_EQ(Empty.umin(Empty), Empty);1187EXPECT_EQ(Empty.umin(Some), Empty);1188EXPECT_EQ(Empty.umin(Wrap), Empty);1189EXPECT_EQ(Empty.umin(One), Empty);1190EXPECT_EQ(Some.umin(Some), Some);1191EXPECT_EQ(Some.umin(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));1192EXPECT_EQ(Some.umin(One), One);1193EXPECT_EQ(Wrap.umin(Wrap), Wrap);1194EXPECT_EQ(Wrap.umin(One), ConstantRange(APInt(16, 0), APInt(16, 0xb)));1195EXPECT_EQ(One.umin(One), One);1196
1197TestBinaryOpExhaustive(1198[](const ConstantRange &CR1, const ConstantRange &CR2) {1199return CR1.umin(CR2);1200},1201[](const APInt &N1, const APInt &N2) {1202return APIntOps::umin(N1, N2);1203},1204PreferSmallestNonFullUnsigned);1205}
1206
1207TEST_F(ConstantRangeTest, SMin) {1208EXPECT_EQ(Full.smin(Full), Full);1209EXPECT_EQ(Full.smin(Empty), Empty);1210EXPECT_EQ(Full.smin(Some), ConstantRange(APInt(16, (uint64_t)INT16_MIN),1211APInt(16, 0xaaa)));1212EXPECT_EQ(Full.smin(Wrap), Full);1213EXPECT_EQ(Empty.smin(Empty), Empty);1214EXPECT_EQ(Empty.smin(Some), Empty);1215EXPECT_EQ(Empty.smin(Wrap), Empty);1216EXPECT_EQ(Empty.smin(One), Empty);1217EXPECT_EQ(Some.smin(Some), Some);1218EXPECT_EQ(Some.smin(Wrap), ConstantRange(APInt(16, (uint64_t)INT16_MIN),1219APInt(16, 0xaaa)));1220EXPECT_EQ(Some.smin(One), One);1221EXPECT_EQ(Wrap.smin(Wrap), Wrap);1222EXPECT_EQ(Wrap.smin(One), ConstantRange(APInt(16, (uint64_t)INT16_MIN),1223APInt(16, 0xb)));1224EXPECT_EQ(One.smin(One), One);1225
1226TestBinaryOpExhaustive(1227[](const ConstantRange &CR1, const ConstantRange &CR2) {1228return CR1.smin(CR2);1229},1230[](const APInt &N1, const APInt &N2) {1231return APIntOps::smin(N1, N2);1232},1233PreferSmallestNonFullSigned);1234}
1235
1236TEST_F(ConstantRangeTest, UDiv) {1237EXPECT_EQ(Full.udiv(Full), Full);1238EXPECT_EQ(Full.udiv(Empty), Empty);1239EXPECT_EQ(Full.udiv(One), ConstantRange(APInt(16, 0),1240APInt(16, 0xffff / 0xa + 1)));1241EXPECT_EQ(Full.udiv(Some), ConstantRange(APInt(16, 0),1242APInt(16, 0xffff / 0xa + 1)));1243EXPECT_EQ(Full.udiv(Wrap), Full);1244EXPECT_EQ(Empty.udiv(Empty), Empty);1245EXPECT_EQ(Empty.udiv(One), Empty);1246EXPECT_EQ(Empty.udiv(Some), Empty);1247EXPECT_EQ(Empty.udiv(Wrap), Empty);1248EXPECT_EQ(One.udiv(One), ConstantRange(APInt(16, 1)));1249EXPECT_EQ(One.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 2)));1250EXPECT_EQ(One.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));1251EXPECT_EQ(Some.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 0x111)));1252EXPECT_EQ(Some.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));1253EXPECT_EQ(Wrap.udiv(Wrap), Full);1254
1255
1256ConstantRange Zero(APInt(16, 0));1257EXPECT_EQ(Zero.udiv(One), Zero);1258EXPECT_EQ(Zero.udiv(Full), Zero);1259
1260EXPECT_EQ(ConstantRange(APInt(16, 0), APInt(16, 99)).udiv(Full),1261ConstantRange(APInt(16, 0), APInt(16, 99)));1262EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 99)).udiv(Full),1263ConstantRange(APInt(16, 0), APInt(16, 99)));1264}
1265
1266TEST_F(ConstantRangeTest, SDiv) {1267ConstantRange OneBit = ConstantRange::getFull(1);1268EXPECT_EQ(OneBit.sdiv(OneBit), ConstantRange(APInt(1, 0)));1269
1270EnumerateTwoInterestingConstantRanges([&](const ConstantRange &CR1,1271const ConstantRange &CR2) {1272// Collect possible results in a bit vector. We store the signed value plus1273// a bias to make it unsigned.1274unsigned Bits = CR1.getBitWidth();1275int Bias = 1 << (Bits - 1);1276BitVector Results(1 << Bits);1277ForeachNumInConstantRange(CR1, [&](const APInt &N1) {1278ForeachNumInConstantRange(CR2, [&](const APInt &N2) {1279// Division by zero is UB.1280if (N2 == 0)1281return;1282
1283// SignedMin / -1 is UB.1284if (N1.isMinSignedValue() && N2.isAllOnes())1285return;1286
1287APInt N = N1.sdiv(N2);1288Results.set(N.getSExtValue() + Bias);1289});1290});1291
1292ConstantRange CR = CR1.sdiv(CR2);1293if (Results.none()) {1294EXPECT_TRUE(CR.isEmptySet());1295return;1296}1297
1298// If there is a non-full signed envelope, that should be the result.1299APInt SMin(Bits, Results.find_first() - Bias);1300APInt SMax(Bits, Results.find_last() - Bias);1301ConstantRange Envelope = ConstantRange::getNonEmpty(SMin, SMax + 1);1302if (!Envelope.isFullSet()) {1303EXPECT_EQ(Envelope, CR);1304return;1305}1306
1307// If the signed envelope is a full set, try to find a smaller sign wrapped1308// set that is separated in negative and positive components (or one which1309// can also additionally contain zero).1310int LastNeg = Results.find_last_in(0, Bias) - Bias;1311int LastPos = Results.find_next(Bias) - Bias;1312if (Results[Bias]) {1313if (LastNeg == -1)1314++LastNeg;1315else if (LastPos == 1)1316--LastPos;1317}1318
1319APInt WMax(Bits, LastNeg);1320APInt WMin(Bits, LastPos);1321ConstantRange Wrapped = ConstantRange::getNonEmpty(WMin, WMax + 1);1322EXPECT_EQ(Wrapped, CR);1323});1324}
1325
1326TEST_F(ConstantRangeTest, URem) {1327EXPECT_EQ(Full.urem(Empty), Empty);1328EXPECT_EQ(Empty.urem(Full), Empty);1329// urem by zero is poison.1330EXPECT_EQ(Full.urem(ConstantRange(APInt(16, 0))), Empty);1331// urem by full range doesn't contain MaxValue.1332EXPECT_EQ(Full.urem(Full), ConstantRange(APInt(16, 0), APInt(16, 0xffff)));1333// urem is upper bounded by maximum RHS minus one.1334EXPECT_EQ(Full.urem(ConstantRange(APInt(16, 0), APInt(16, 123))),1335ConstantRange(APInt(16, 0), APInt(16, 122)));1336// urem is upper bounded by maximum LHS.1337EXPECT_EQ(ConstantRange(APInt(16, 0), APInt(16, 123)).urem(Full),1338ConstantRange(APInt(16, 0), APInt(16, 123)));1339// If the LHS is always lower than the RHS, the result is the LHS.1340EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 20))1341.urem(ConstantRange(APInt(16, 20), APInt(16, 30))),1342ConstantRange(APInt(16, 10), APInt(16, 20)));1343// It has to be strictly lower, otherwise the top value may wrap to zero.1344EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 20))1345.urem(ConstantRange(APInt(16, 19), APInt(16, 30))),1346ConstantRange(APInt(16, 0), APInt(16, 20)));1347// [12, 14] % 10 is [2, 4], but we conservatively compute [0, 9].1348EXPECT_EQ(ConstantRange(APInt(16, 12), APInt(16, 15))1349.urem(ConstantRange(APInt(16, 10))),1350ConstantRange(APInt(16, 0), APInt(16, 10)));1351
1352TestBinaryOpExhaustive(1353[](const ConstantRange &CR1, const ConstantRange &CR2) {1354return CR1.urem(CR2);1355},1356[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {1357if (N2.isZero())1358return std::nullopt;1359return N1.urem(N2);1360},1361PreferSmallest, CheckSingleElementsOnly);1362}
1363
1364TEST_F(ConstantRangeTest, SRem) {1365EXPECT_EQ(Full.srem(Empty), Empty);1366EXPECT_EQ(Empty.srem(Full), Empty);1367// srem by zero is UB.1368EXPECT_EQ(Full.srem(ConstantRange(APInt(16, 0))), Empty);1369// srem by full range doesn't contain SignedMinValue.1370EXPECT_EQ(Full.srem(Full), ConstantRange(APInt::getSignedMinValue(16) + 1,1371APInt::getSignedMinValue(16)));1372
1373ConstantRange PosMod(APInt(16, 10), APInt(16, 21)); // [10, 20]1374ConstantRange NegMod(APInt(16, -20), APInt(16, -9)); // [-20, -10]1375ConstantRange IntMinMod(APInt::getSignedMinValue(16));1376
1377ConstantRange Expected(16, true);1378
1379// srem is bounded by abs(RHS) minus one.1380ConstantRange PosLargeLHS(APInt(16, 0), APInt(16, 41));1381Expected = ConstantRange(APInt(16, 0), APInt(16, 20));1382EXPECT_EQ(PosLargeLHS.srem(PosMod), Expected);1383EXPECT_EQ(PosLargeLHS.srem(NegMod), Expected);1384ConstantRange NegLargeLHS(APInt(16, -40), APInt(16, 1));1385Expected = ConstantRange(APInt(16, -19), APInt(16, 1));1386EXPECT_EQ(NegLargeLHS.srem(PosMod), Expected);1387EXPECT_EQ(NegLargeLHS.srem(NegMod), Expected);1388ConstantRange PosNegLargeLHS(APInt(16, -32), APInt(16, 38));1389Expected = ConstantRange(APInt(16, -19), APInt(16, 20));1390EXPECT_EQ(PosNegLargeLHS.srem(PosMod), Expected);1391EXPECT_EQ(PosNegLargeLHS.srem(NegMod), Expected);1392
1393// srem is bounded by LHS.1394ConstantRange PosLHS(APInt(16, 0), APInt(16, 16));1395EXPECT_EQ(PosLHS.srem(PosMod), PosLHS);1396EXPECT_EQ(PosLHS.srem(NegMod), PosLHS);1397EXPECT_EQ(PosLHS.srem(IntMinMod), PosLHS);1398ConstantRange NegLHS(APInt(16, -15), APInt(16, 1));1399EXPECT_EQ(NegLHS.srem(PosMod), NegLHS);1400EXPECT_EQ(NegLHS.srem(NegMod), NegLHS);1401EXPECT_EQ(NegLHS.srem(IntMinMod), NegLHS);1402ConstantRange PosNegLHS(APInt(16, -12), APInt(16, 18));1403EXPECT_EQ(PosNegLHS.srem(PosMod), PosNegLHS);1404EXPECT_EQ(PosNegLHS.srem(NegMod), PosNegLHS);1405EXPECT_EQ(PosNegLHS.srem(IntMinMod), PosNegLHS);1406
1407// srem is LHS if it is smaller than RHS.1408ConstantRange PosSmallLHS(APInt(16, 3), APInt(16, 8));1409EXPECT_EQ(PosSmallLHS.srem(PosMod), PosSmallLHS);1410EXPECT_EQ(PosSmallLHS.srem(NegMod), PosSmallLHS);1411EXPECT_EQ(PosSmallLHS.srem(IntMinMod), PosSmallLHS);1412ConstantRange NegSmallLHS(APInt(16, -7), APInt(16, -2));1413EXPECT_EQ(NegSmallLHS.srem(PosMod), NegSmallLHS);1414EXPECT_EQ(NegSmallLHS.srem(NegMod), NegSmallLHS);1415EXPECT_EQ(NegSmallLHS.srem(IntMinMod), NegSmallLHS);1416ConstantRange PosNegSmallLHS(APInt(16, -3), APInt(16, 8));1417EXPECT_EQ(PosNegSmallLHS.srem(PosMod), PosNegSmallLHS);1418EXPECT_EQ(PosNegSmallLHS.srem(NegMod), PosNegSmallLHS);1419EXPECT_EQ(PosNegSmallLHS.srem(IntMinMod), PosNegSmallLHS);1420
1421// Example of a suboptimal result:1422// [12, 14] srem 10 is [2, 4], but we conservatively compute [0, 9].1423EXPECT_EQ(ConstantRange(APInt(16, 12), APInt(16, 15))1424.srem(ConstantRange(APInt(16, 10))),1425ConstantRange(APInt(16, 0), APInt(16, 10)));1426
1427TestBinaryOpExhaustive(1428[](const ConstantRange &CR1, const ConstantRange &CR2) {1429return CR1.srem(CR2);1430},1431[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {1432if (N2.isZero())1433return std::nullopt;1434return N1.srem(N2);1435},1436PreferSmallest, CheckSingleElementsOnly);1437}
1438
1439TEST_F(ConstantRangeTest, Shl) {1440ConstantRange Some2(APInt(16, 0xfff), APInt(16, 0x8000));1441ConstantRange WrapNullMax(APInt(16, 0x1), APInt(16, 0x0));1442EXPECT_EQ(Full.shl(Full), Full);1443EXPECT_EQ(Full.shl(Empty), Empty);1444EXPECT_EQ(Full.shl(One), ConstantRange(APInt(16, 0),1445APInt(16, 0xfc00) + 1));1446EXPECT_EQ(Full.shl(Some), Full); // TODO: [0, (-1 << 0xa) + 1)1447EXPECT_EQ(Full.shl(Wrap), Full);1448EXPECT_EQ(Empty.shl(Empty), Empty);1449EXPECT_EQ(Empty.shl(One), Empty);1450EXPECT_EQ(Empty.shl(Some), Empty);1451EXPECT_EQ(Empty.shl(Wrap), Empty);1452EXPECT_EQ(One.shl(One), ConstantRange(APInt(16, 0xa << 0xa),1453APInt(16, (0xa << 0xa) + 1)));1454EXPECT_EQ(One.shl(Some), Full); // TODO: [0xa << 0xa, 0)1455EXPECT_EQ(One.shl(Wrap), Full); // TODO: [0xa, 0xa << 14 + 1)1456EXPECT_EQ(Some.shl(Some), Full); // TODO: [0xa << 0xa, 0xfc01)1457EXPECT_EQ(Some.shl(Wrap), Full); // TODO: [0xa, 0x7ff << 0x5 + 1)1458EXPECT_EQ(Wrap.shl(Wrap), Full);1459EXPECT_EQ(1460Some2.shl(ConstantRange(APInt(16, 0x1))),1461ConstantRange(APInt(16, 0xfff << 0x1), APInt(16, 0x7fff << 0x1) + 1));1462EXPECT_EQ(One.shl(WrapNullMax), Full);1463
1464ConstantRange NegOne(APInt(16, 0xffff));1465EXPECT_EQ(NegOne.shl(ConstantRange(APInt(16, 0), APInt(16, 5))),1466ConstantRange(APInt(16, 0xfff0), APInt(16, 0)));1467EXPECT_EQ(ConstantRange(APInt(16, 0xfffe), APInt(16, 0))1468.shl(ConstantRange(APInt(16, 0), APInt(16, 5))),1469ConstantRange(APInt(16, 0xffe0), APInt(16, 0)));1470
1471TestBinaryOpExhaustive(1472[](const ConstantRange &CR1, const ConstantRange &CR2) {1473return CR1.shl(CR2);1474},1475[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {1476if (N2.uge(N2.getBitWidth()))1477return std::nullopt;1478return N1.shl(N2);1479},1480PreferSmallestUnsigned,1481[](const ConstantRange &, const ConstantRange &CR2) {1482// We currently only produce precise results for single element RHS.1483return CR2.isSingleElement();1484});1485}
1486
1487TEST_F(ConstantRangeTest, Lshr) {1488EXPECT_EQ(Full.lshr(Full), Full);1489EXPECT_EQ(Full.lshr(Empty), Empty);1490EXPECT_EQ(Full.lshr(One), ConstantRange(APInt(16, 0),1491APInt(16, (0xffff >> 0xa) + 1)));1492EXPECT_EQ(Full.lshr(Some), ConstantRange(APInt(16, 0),1493APInt(16, (0xffff >> 0xa) + 1)));1494EXPECT_EQ(Full.lshr(Wrap), Full);1495EXPECT_EQ(Empty.lshr(Empty), Empty);1496EXPECT_EQ(Empty.lshr(One), Empty);1497EXPECT_EQ(Empty.lshr(Some), Empty);1498EXPECT_EQ(Empty.lshr(Wrap), Empty);1499EXPECT_EQ(One.lshr(One), ConstantRange(APInt(16, 0)));1500EXPECT_EQ(One.lshr(Some), ConstantRange(APInt(16, 0)));1501EXPECT_EQ(One.lshr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));1502EXPECT_EQ(Some.lshr(Some), ConstantRange(APInt(16, 0),1503APInt(16, (0xaaa >> 0xa) + 1)));1504EXPECT_EQ(Some.lshr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));1505EXPECT_EQ(Wrap.lshr(Wrap), Full);1506}
1507
1508TEST_F(ConstantRangeTest, Ashr) {1509EXPECT_EQ(Full.ashr(Full), Full);1510EXPECT_EQ(Full.ashr(Empty), Empty);1511EXPECT_EQ(Full.ashr(One), ConstantRange(APInt(16, 0xffe0),1512APInt(16, (0x7fff >> 0xa) + 1 )));1513ConstantRange Small(APInt(16, 0xa), APInt(16, 0xb));1514EXPECT_EQ(Full.ashr(Small), ConstantRange(APInt(16, 0xffe0),1515APInt(16, (0x7fff >> 0xa) + 1 )));1516EXPECT_EQ(Full.ashr(Some), ConstantRange(APInt(16, 0xffe0),1517APInt(16, (0x7fff >> 0xa) + 1 )));1518EXPECT_EQ(Full.ashr(Wrap), Full);1519EXPECT_EQ(Empty.ashr(Empty), Empty);1520EXPECT_EQ(Empty.ashr(One), Empty);1521EXPECT_EQ(Empty.ashr(Some), Empty);1522EXPECT_EQ(Empty.ashr(Wrap), Empty);1523EXPECT_EQ(One.ashr(One), ConstantRange(APInt(16, 0)));1524EXPECT_EQ(One.ashr(Some), ConstantRange(APInt(16, 0)));1525EXPECT_EQ(One.ashr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));1526EXPECT_EQ(Some.ashr(Some), ConstantRange(APInt(16, 0),1527APInt(16, (0xaaa >> 0xa) + 1)));1528EXPECT_EQ(Some.ashr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));1529EXPECT_EQ(Wrap.ashr(Wrap), Full);1530ConstantRange Neg(APInt(16, 0xf3f0, true), APInt(16, 0xf7f8, true));1531EXPECT_EQ(Neg.ashr(Small), ConstantRange(APInt(16, 0xfffc, true),1532APInt(16, 0xfffe, true)));1533}
1534
1535TEST(ConstantRange, MakeAllowedICmpRegion) {1536// PR82501537ConstantRange SMax = ConstantRange(APInt::getSignedMaxValue(32));1538EXPECT_TRUE(ConstantRange::makeAllowedICmpRegion(ICmpInst::ICMP_SGT, SMax)1539.isEmptySet());1540}
1541
1542TEST(ConstantRange, MakeSatisfyingICmpRegion) {1543ConstantRange LowHalf(APInt(8, 0), APInt(8, 128));1544ConstantRange HighHalf(APInt(8, 128), APInt(8, 0));1545ConstantRange EmptySet(8, /* isFullSet = */ false);1546
1547EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_NE, LowHalf),1548HighHalf);1549
1550EXPECT_EQ(1551ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_NE, HighHalf),1552LowHalf);1553
1554EXPECT_TRUE(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_EQ,1555HighHalf).isEmptySet());1556
1557ConstantRange UnsignedSample(APInt(8, 5), APInt(8, 200));1558
1559EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_ULT,1560UnsignedSample),1561ConstantRange(APInt(8, 0), APInt(8, 5)));1562
1563EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_ULE,1564UnsignedSample),1565ConstantRange(APInt(8, 0), APInt(8, 6)));1566
1567EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_UGT,1568UnsignedSample),1569ConstantRange(APInt(8, 200), APInt(8, 0)));1570
1571EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_UGE,1572UnsignedSample),1573ConstantRange(APInt(8, 199), APInt(8, 0)));1574
1575ConstantRange SignedSample(APInt(8, -5), APInt(8, 5));1576
1577EXPECT_EQ(1578ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SLT, SignedSample),1579ConstantRange(APInt(8, -128), APInt(8, -5)));1580
1581EXPECT_EQ(1582ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SLE, SignedSample),1583ConstantRange(APInt(8, -128), APInt(8, -4)));1584
1585EXPECT_EQ(1586ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SGT, SignedSample),1587ConstantRange(APInt(8, 5), APInt(8, -128)));1588
1589EXPECT_EQ(1590ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SGE, SignedSample),1591ConstantRange(APInt(8, 4), APInt(8, -128)));1592}
1593
1594void ICmpTestImpl(CmpInst::Predicate Pred) {1595EnumerateTwoInterestingConstantRanges(1596[&](const ConstantRange &CR1, const ConstantRange &CR2) {1597bool Exhaustive = true;1598ForeachNumInConstantRange(CR1, [&](const APInt &N1) {1599ForeachNumInConstantRange(CR2, [&](const APInt &N2) {1600Exhaustive &= ICmpInst::compare(N1, N2, Pred);1601});1602});1603EXPECT_EQ(CR1.icmp(Pred, CR2), Exhaustive);1604});1605}
1606
1607TEST(ConstantRange, ICmp) {1608for (auto Pred : ICmpInst::predicates())1609ICmpTestImpl(Pred);1610}
1611
1612TEST(ConstantRange, MakeGuaranteedNoWrapRegion) {1613const int IntMin4Bits = 8;1614const int IntMax4Bits = 7;1615typedef OverflowingBinaryOperator OBO;1616
1617for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {1618APInt C(4, Const, true /* = isSigned */);1619
1620auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion(1621Instruction::Add, C, OBO::NoUnsignedWrap);1622
1623EXPECT_FALSE(NUWRegion.isEmptySet());1624
1625auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(1626Instruction::Add, C, OBO::NoSignedWrap);1627
1628EXPECT_FALSE(NSWRegion.isEmptySet());1629
1630for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;1631++I) {1632bool Overflow = false;1633(void)I.uadd_ov(C, Overflow);1634EXPECT_FALSE(Overflow);1635}1636
1637for (APInt I = NSWRegion.getLower(), E = NSWRegion.getUpper(); I != E;1638++I) {1639bool Overflow = false;1640(void)I.sadd_ov(C, Overflow);1641EXPECT_FALSE(Overflow);1642}1643}1644
1645for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {1646APInt C(4, Const, true /* = isSigned */);1647
1648auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion(1649Instruction::Sub, C, OBO::NoUnsignedWrap);1650
1651EXPECT_FALSE(NUWRegion.isEmptySet());1652
1653auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(1654Instruction::Sub, C, OBO::NoSignedWrap);1655
1656EXPECT_FALSE(NSWRegion.isEmptySet());1657
1658for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;1659++I) {1660bool Overflow = false;1661(void)I.usub_ov(C, Overflow);1662EXPECT_FALSE(Overflow);1663}1664
1665for (APInt I = NSWRegion.getLower(), E = NSWRegion.getUpper(); I != E;1666++I) {1667bool Overflow = false;1668(void)I.ssub_ov(C, Overflow);1669EXPECT_FALSE(Overflow);1670}1671}1672
1673auto NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(1674Instruction::Add, ConstantRange(32, /* isFullSet = */ true),1675OBO::NoSignedWrap);1676EXPECT_TRUE(NSWForAllValues.isSingleElement() &&1677NSWForAllValues.getSingleElement()->isMinValue());1678
1679NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(1680Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),1681OBO::NoSignedWrap);1682EXPECT_TRUE(NSWForAllValues.isSingleElement() &&1683NSWForAllValues.getSingleElement()->isMaxValue());1684
1685auto NUWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(1686Instruction::Add, ConstantRange(32, /* isFullSet = */ true),1687OBO::NoUnsignedWrap);1688EXPECT_TRUE(NUWForAllValues.isSingleElement() &&1689NUWForAllValues.getSingleElement()->isMinValue());1690
1691NUWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(1692Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),1693OBO::NoUnsignedWrap);1694EXPECT_TRUE(NUWForAllValues.isSingleElement() &&1695NUWForAllValues.getSingleElement()->isMaxValue());1696
1697EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(1698Instruction::Add, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());1699EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(1700Instruction::Add, APInt(32, 0), OBO::NoSignedWrap).isFullSet());1701EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(1702Instruction::Sub, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());1703EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(1704Instruction::Sub, APInt(32, 0), OBO::NoSignedWrap).isFullSet());1705
1706ConstantRange OneToFive(APInt(32, 1), APInt(32, 6));1707EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1708Instruction::Add, OneToFive, OBO::NoSignedWrap),1709ConstantRange(APInt::getSignedMinValue(32),1710APInt::getSignedMaxValue(32) - 4));1711EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1712Instruction::Add, OneToFive, OBO::NoUnsignedWrap),1713ConstantRange(APInt::getMinValue(32), APInt::getMinValue(32) - 5));1714EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1715Instruction::Sub, OneToFive, OBO::NoSignedWrap),1716ConstantRange(APInt::getSignedMinValue(32) + 5,1717APInt::getSignedMinValue(32)));1718EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1719Instruction::Sub, OneToFive, OBO::NoUnsignedWrap),1720ConstantRange(APInt::getMinValue(32) + 5, APInt::getMinValue(32)));1721
1722ConstantRange MinusFiveToMinusTwo(APInt(32, -5), APInt(32, -1));1723EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1724Instruction::Add, MinusFiveToMinusTwo, OBO::NoSignedWrap),1725ConstantRange(APInt::getSignedMinValue(32) + 5,1726APInt::getSignedMinValue(32)));1727EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1728Instruction::Add, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),1729ConstantRange(APInt(32, 0), APInt(32, 2)));1730EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1731Instruction::Sub, MinusFiveToMinusTwo, OBO::NoSignedWrap),1732ConstantRange(APInt::getSignedMinValue(32),1733APInt::getSignedMaxValue(32) - 4));1734EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1735Instruction::Sub, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),1736ConstantRange(APInt::getMaxValue(32) - 1,1737APInt::getMinValue(32)));1738
1739ConstantRange MinusOneToOne(APInt(32, -1), APInt(32, 2));1740EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1741Instruction::Add, MinusOneToOne, OBO::NoSignedWrap),1742ConstantRange(APInt::getSignedMinValue(32) + 1,1743APInt::getSignedMinValue(32) - 1));1744EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1745Instruction::Add, MinusOneToOne, OBO::NoUnsignedWrap),1746ConstantRange(APInt(32, 0), APInt(32, 1)));1747EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1748Instruction::Sub, MinusOneToOne, OBO::NoSignedWrap),1749ConstantRange(APInt::getSignedMinValue(32) + 1,1750APInt::getSignedMinValue(32) - 1));1751EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1752Instruction::Sub, MinusOneToOne, OBO::NoUnsignedWrap),1753ConstantRange(APInt::getMaxValue(32),1754APInt::getMinValue(32)));1755
1756ConstantRange One(APInt(32, 1), APInt(32, 2));1757EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1758Instruction::Add, One, OBO::NoSignedWrap),1759ConstantRange(APInt::getSignedMinValue(32),1760APInt::getSignedMaxValue(32)));1761EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1762Instruction::Add, One, OBO::NoUnsignedWrap),1763ConstantRange(APInt::getMinValue(32), APInt::getMaxValue(32)));1764EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1765Instruction::Sub, One, OBO::NoSignedWrap),1766ConstantRange(APInt::getSignedMinValue(32) + 1,1767APInt::getSignedMinValue(32)));1768EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1769Instruction::Sub, One, OBO::NoUnsignedWrap),1770ConstantRange(APInt::getMinValue(32) + 1, APInt::getMinValue(32)));1771
1772ConstantRange OneLessThanBitWidth(APInt(32, 0), APInt(32, 31) + 1);1773ConstantRange UpToBitWidth(APInt(32, 0), APInt(32, 32) + 1);1774EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1775Instruction::Shl, UpToBitWidth, OBO::NoUnsignedWrap),1776ConstantRange::makeGuaranteedNoWrapRegion(1777Instruction::Shl, OneLessThanBitWidth, OBO::NoUnsignedWrap));1778EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1779Instruction::Shl, UpToBitWidth, OBO::NoSignedWrap),1780ConstantRange::makeGuaranteedNoWrapRegion(1781Instruction::Shl, OneLessThanBitWidth, OBO::NoSignedWrap));1782EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1783Instruction::Shl, UpToBitWidth, OBO::NoUnsignedWrap),1784ConstantRange(APInt(32, 0), APInt(32, 1) + 1));1785EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1786Instruction::Shl, UpToBitWidth, OBO::NoSignedWrap),1787ConstantRange(APInt(32, -1), APInt(32, 0) + 1));1788
1789EXPECT_EQ(1790ConstantRange::makeGuaranteedNoWrapRegion(1791Instruction::Shl, ConstantRange::getFull(32), OBO::NoUnsignedWrap),1792ConstantRange::makeGuaranteedNoWrapRegion(1793Instruction::Shl, OneLessThanBitWidth, OBO::NoUnsignedWrap));1794EXPECT_EQ(1795ConstantRange::makeGuaranteedNoWrapRegion(1796Instruction::Shl, ConstantRange::getFull(32), OBO::NoSignedWrap),1797ConstantRange::makeGuaranteedNoWrapRegion(1798Instruction::Shl, OneLessThanBitWidth, OBO::NoSignedWrap));1799
1800ConstantRange IllegalShAmt(APInt(32, 32), APInt(32, 0) + 1);1801EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1802Instruction::Shl, IllegalShAmt, OBO::NoUnsignedWrap),1803ConstantRange::getFull(32));1804EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1805Instruction::Shl, IllegalShAmt, OBO::NoSignedWrap),1806ConstantRange::getFull(32));1807
1808EXPECT_EQ(1809ConstantRange::makeGuaranteedNoWrapRegion(1810Instruction::Shl, ConstantRange(APInt(32, -32), APInt(32, 16) + 1),1811OBO::NoUnsignedWrap),1812ConstantRange::makeGuaranteedNoWrapRegion(1813Instruction::Shl, ConstantRange(APInt(32, 0), APInt(32, 16) + 1),1814OBO::NoUnsignedWrap));1815EXPECT_EQ(1816ConstantRange::makeGuaranteedNoWrapRegion(1817Instruction::Shl, ConstantRange(APInt(32, -32), APInt(32, 16) + 1),1818OBO::NoSignedWrap),1819ConstantRange::makeGuaranteedNoWrapRegion(1820Instruction::Shl, ConstantRange(APInt(32, 0), APInt(32, 16) + 1),1821OBO::NoSignedWrap));1822
1823EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1824Instruction::Shl,1825ConstantRange(APInt(32, -32), APInt(32, 16) + 1),1826OBO::NoUnsignedWrap),1827ConstantRange(APInt(32, 0), APInt(32, 65535) + 1));1828EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(1829Instruction::Shl,1830ConstantRange(APInt(32, -32), APInt(32, 16) + 1),1831OBO::NoSignedWrap),1832ConstantRange(APInt(32, -32768), APInt(32, 32767) + 1));1833}
1834
1835template<typename Fn>1836void TestNoWrapRegionExhaustive(Instruction::BinaryOps BinOp,1837unsigned NoWrapKind, Fn OverflowFn) {1838for (unsigned Bits : {1, 5}) {1839EnumerateConstantRanges(Bits, [&](const ConstantRange &CR) {1840if (CR.isEmptySet())1841return;1842if (Instruction::isShift(BinOp) && CR.getUnsignedMax().uge(Bits))1843return;1844
1845ConstantRange NoWrap =1846ConstantRange::makeGuaranteedNoWrapRegion(BinOp, CR, NoWrapKind);1847EnumerateAPInts(Bits, [&](const APInt &N1) {1848bool NoOverflow = true;1849bool Overflow = true;1850ForeachNumInConstantRange(CR, [&](const APInt &N2) {1851if (OverflowFn(N1, N2))1852NoOverflow = false;1853else1854Overflow = false;1855});1856EXPECT_EQ(NoOverflow, NoWrap.contains(N1));1857
1858// The no-wrap range is exact for single-element ranges.1859if (CR.isSingleElement()) {1860EXPECT_EQ(Overflow, !NoWrap.contains(N1));1861}1862});1863});1864}1865}
1866
1867// Show that makeGuaranteedNoWrapRegion() is maximal, and for single-element
1868// ranges also exact.
1869TEST(ConstantRange, NoWrapRegionExhaustive) {1870TestNoWrapRegionExhaustive(1871Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap,1872[](const APInt &N1, const APInt &N2) {1873bool Overflow;1874(void) N1.uadd_ov(N2, Overflow);1875return Overflow;1876});1877TestNoWrapRegionExhaustive(1878Instruction::Add, OverflowingBinaryOperator::NoSignedWrap,1879[](const APInt &N1, const APInt &N2) {1880bool Overflow;1881(void) N1.sadd_ov(N2, Overflow);1882return Overflow;1883});1884TestNoWrapRegionExhaustive(1885Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap,1886[](const APInt &N1, const APInt &N2) {1887bool Overflow;1888(void) N1.usub_ov(N2, Overflow);1889return Overflow;1890});1891TestNoWrapRegionExhaustive(1892Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap,1893[](const APInt &N1, const APInt &N2) {1894bool Overflow;1895(void) N1.ssub_ov(N2, Overflow);1896return Overflow;1897});1898TestNoWrapRegionExhaustive(1899Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap,1900[](const APInt &N1, const APInt &N2) {1901bool Overflow;1902(void) N1.umul_ov(N2, Overflow);1903return Overflow;1904});1905TestNoWrapRegionExhaustive(1906Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap,1907[](const APInt &N1, const APInt &N2) {1908bool Overflow;1909(void) N1.smul_ov(N2, Overflow);1910return Overflow;1911});1912TestNoWrapRegionExhaustive(Instruction::Shl,1913OverflowingBinaryOperator::NoUnsignedWrap,1914[](const APInt &N1, const APInt &N2) {1915bool Overflow;1916(void)N1.ushl_ov(N2, Overflow);1917return Overflow;1918});1919TestNoWrapRegionExhaustive(Instruction::Shl,1920OverflowingBinaryOperator::NoSignedWrap,1921[](const APInt &N1, const APInt &N2) {1922bool Overflow;1923(void)N1.sshl_ov(N2, Overflow);1924return Overflow;1925});1926}
1927
1928TEST(ConstantRange, GetEquivalentICmp) {1929APInt RHS;1930CmpInst::Predicate Pred;1931
1932EXPECT_TRUE(ConstantRange(APInt::getMinValue(32), APInt(32, 100))1933.getEquivalentICmp(Pred, RHS));1934EXPECT_EQ(Pred, CmpInst::ICMP_ULT);1935EXPECT_EQ(RHS, APInt(32, 100));1936
1937EXPECT_TRUE(ConstantRange(APInt::getSignedMinValue(32), APInt(32, 100))1938.getEquivalentICmp(Pred, RHS));1939EXPECT_EQ(Pred, CmpInst::ICMP_SLT);1940EXPECT_EQ(RHS, APInt(32, 100));1941
1942EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getMinValue(32))1943.getEquivalentICmp(Pred, RHS));1944EXPECT_EQ(Pred, CmpInst::ICMP_UGE);1945EXPECT_EQ(RHS, APInt(32, 100));1946
1947EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getSignedMinValue(32))1948.getEquivalentICmp(Pred, RHS));1949EXPECT_EQ(Pred, CmpInst::ICMP_SGE);1950EXPECT_EQ(RHS, APInt(32, 100));1951
1952EXPECT_TRUE(1953ConstantRange(32, /*isFullSet=*/true).getEquivalentICmp(Pred, RHS));1954EXPECT_EQ(Pred, CmpInst::ICMP_UGE);1955EXPECT_EQ(RHS, APInt(32, 0));1956
1957EXPECT_TRUE(1958ConstantRange(32, /*isFullSet=*/false).getEquivalentICmp(Pred, RHS));1959EXPECT_EQ(Pred, CmpInst::ICMP_ULT);1960EXPECT_EQ(RHS, APInt(32, 0));1961
1962EXPECT_FALSE(ConstantRange(APInt(32, 100), APInt(32, 200))1963.getEquivalentICmp(Pred, RHS));1964
1965EXPECT_FALSE(ConstantRange(APInt::getSignedMinValue(32) - APInt(32, 100),1966APInt::getSignedMinValue(32) + APInt(32, 100))1967.getEquivalentICmp(Pred, RHS));1968
1969EXPECT_FALSE(ConstantRange(APInt::getMinValue(32) - APInt(32, 100),1970APInt::getMinValue(32) + APInt(32, 100))1971.getEquivalentICmp(Pred, RHS));1972
1973EXPECT_TRUE(ConstantRange(APInt(32, 100)).getEquivalentICmp(Pred, RHS));1974EXPECT_EQ(Pred, CmpInst::ICMP_EQ);1975EXPECT_EQ(RHS, APInt(32, 100));1976
1977EXPECT_TRUE(1978ConstantRange(APInt(32, 100)).inverse().getEquivalentICmp(Pred, RHS));1979EXPECT_EQ(Pred, CmpInst::ICMP_NE);1980EXPECT_EQ(RHS, APInt(32, 100));1981
1982EXPECT_TRUE(1983ConstantRange(APInt(512, 100)).inverse().getEquivalentICmp(Pred, RHS));1984EXPECT_EQ(Pred, CmpInst::ICMP_NE);1985EXPECT_EQ(RHS, APInt(512, 100));1986
1987// NB! It would be correct for the following four calls to getEquivalentICmp1988// to return ordered predicates like CmpInst::ICMP_ULT or CmpInst::ICMP_UGT.1989// However, that's not the case today.1990
1991EXPECT_TRUE(ConstantRange(APInt(32, 0)).getEquivalentICmp(Pred, RHS));1992EXPECT_EQ(Pred, CmpInst::ICMP_EQ);1993EXPECT_EQ(RHS, APInt(32, 0));1994
1995EXPECT_TRUE(1996ConstantRange(APInt(32, 0)).inverse().getEquivalentICmp(Pred, RHS));1997EXPECT_EQ(Pred, CmpInst::ICMP_NE);1998EXPECT_EQ(RHS, APInt(32, 0));1999
2000EXPECT_TRUE(ConstantRange(APInt(32, -1)).getEquivalentICmp(Pred, RHS));2001EXPECT_EQ(Pred, CmpInst::ICMP_EQ);2002EXPECT_EQ(RHS, APInt(32, -1));2003
2004EXPECT_TRUE(2005ConstantRange(APInt(32, -1)).inverse().getEquivalentICmp(Pred, RHS));2006EXPECT_EQ(Pred, CmpInst::ICMP_NE);2007EXPECT_EQ(RHS, APInt(32, -1));2008
2009EnumerateInterestingConstantRanges([](const ConstantRange &CR) {2010unsigned Bits = CR.getBitWidth();2011CmpInst::Predicate Pred;2012APInt RHS, Offset;2013CR.getEquivalentICmp(Pred, RHS, Offset);2014EnumerateAPInts(Bits, [&](const APInt &N) {2015bool Result = ICmpInst::compare(N + Offset, RHS, Pred);2016EXPECT_EQ(CR.contains(N), Result);2017});2018
2019if (CR.getEquivalentICmp(Pred, RHS)) {2020EnumerateAPInts(Bits, [&](const APInt &N) {2021bool Result = ICmpInst::compare(N, RHS, Pred);2022EXPECT_EQ(CR.contains(N), Result);2023});2024}2025});2026}
2027
2028#define EXPECT_MAY_OVERFLOW(op) \2029EXPECT_EQ(ConstantRange::OverflowResult::MayOverflow, (op))2030#define EXPECT_ALWAYS_OVERFLOWS_LOW(op) \2031EXPECT_EQ(ConstantRange::OverflowResult::AlwaysOverflowsLow, (op))2032#define EXPECT_ALWAYS_OVERFLOWS_HIGH(op) \2033EXPECT_EQ(ConstantRange::OverflowResult::AlwaysOverflowsHigh, (op))2034#define EXPECT_NEVER_OVERFLOWS(op) \2035EXPECT_EQ(ConstantRange::OverflowResult::NeverOverflows, (op))2036
2037TEST_F(ConstantRangeTest, UnsignedAddOverflow) {2038// Ill-defined - may overflow is a conservative result.2039EXPECT_MAY_OVERFLOW(Some.unsignedAddMayOverflow(Empty));2040EXPECT_MAY_OVERFLOW(Empty.unsignedAddMayOverflow(Some));2041
2042// Never overflow despite one full/wrap set.2043ConstantRange Zero(APInt::getZero(16));2044EXPECT_NEVER_OVERFLOWS(Full.unsignedAddMayOverflow(Zero));2045EXPECT_NEVER_OVERFLOWS(Wrap.unsignedAddMayOverflow(Zero));2046EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Full));2047EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Wrap));2048
2049// But usually full/wrap always may overflow.2050EXPECT_MAY_OVERFLOW(Full.unsignedAddMayOverflow(One));2051EXPECT_MAY_OVERFLOW(Wrap.unsignedAddMayOverflow(One));2052EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Full));2053EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Wrap));2054
2055ConstantRange A(APInt(16, 0xfd00), APInt(16, 0xfe00));2056ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));2057ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));2058EXPECT_NEVER_OVERFLOWS(A.unsignedAddMayOverflow(B1));2059EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(B2));2060EXPECT_NEVER_OVERFLOWS(B1.unsignedAddMayOverflow(A));2061EXPECT_MAY_OVERFLOW(B2.unsignedAddMayOverflow(A));2062
2063ConstantRange C1(APInt(16, 0x0299), APInt(16, 0x0400));2064ConstantRange C2(APInt(16, 0x0300), APInt(16, 0x0400));2065EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(C1));2066EXPECT_ALWAYS_OVERFLOWS_HIGH(A.unsignedAddMayOverflow(C2));2067EXPECT_MAY_OVERFLOW(C1.unsignedAddMayOverflow(A));2068EXPECT_ALWAYS_OVERFLOWS_HIGH(C2.unsignedAddMayOverflow(A));2069}
2070
2071TEST_F(ConstantRangeTest, UnsignedSubOverflow) {2072// Ill-defined - may overflow is a conservative result.2073EXPECT_MAY_OVERFLOW(Some.unsignedSubMayOverflow(Empty));2074EXPECT_MAY_OVERFLOW(Empty.unsignedSubMayOverflow(Some));2075
2076// Never overflow despite one full/wrap set.2077ConstantRange Zero(APInt::getZero(16));2078ConstantRange Max(APInt::getAllOnes(16));2079EXPECT_NEVER_OVERFLOWS(Full.unsignedSubMayOverflow(Zero));2080EXPECT_NEVER_OVERFLOWS(Wrap.unsignedSubMayOverflow(Zero));2081EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Full));2082EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Wrap));2083
2084// But usually full/wrap always may overflow.2085EXPECT_MAY_OVERFLOW(Full.unsignedSubMayOverflow(One));2086EXPECT_MAY_OVERFLOW(Wrap.unsignedSubMayOverflow(One));2087EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Full));2088EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Wrap));2089
2090ConstantRange A(APInt(16, 0x0000), APInt(16, 0x0100));2091ConstantRange B(APInt(16, 0x0100), APInt(16, 0x0200));2092EXPECT_NEVER_OVERFLOWS(B.unsignedSubMayOverflow(A));2093EXPECT_ALWAYS_OVERFLOWS_LOW(A.unsignedSubMayOverflow(B));2094
2095ConstantRange A1(APInt(16, 0x0000), APInt(16, 0x0101));2096ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));2097EXPECT_NEVER_OVERFLOWS(B1.unsignedSubMayOverflow(A1));2098EXPECT_MAY_OVERFLOW(A1.unsignedSubMayOverflow(B1));2099
2100ConstantRange A2(APInt(16, 0x0000), APInt(16, 0x0102));2101ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));2102EXPECT_MAY_OVERFLOW(B2.unsignedSubMayOverflow(A2));2103EXPECT_MAY_OVERFLOW(A2.unsignedSubMayOverflow(B2));2104}
2105
2106TEST_F(ConstantRangeTest, SignedAddOverflow) {2107// Ill-defined - may overflow is a conservative result.2108EXPECT_MAY_OVERFLOW(Some.signedAddMayOverflow(Empty));2109EXPECT_MAY_OVERFLOW(Empty.signedAddMayOverflow(Some));2110
2111// Never overflow despite one full/wrap set.2112ConstantRange Zero(APInt::getZero(16));2113EXPECT_NEVER_OVERFLOWS(Full.signedAddMayOverflow(Zero));2114EXPECT_NEVER_OVERFLOWS(Wrap.signedAddMayOverflow(Zero));2115EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Full));2116EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Wrap));2117
2118// But usually full/wrap always may overflow.2119EXPECT_MAY_OVERFLOW(Full.signedAddMayOverflow(One));2120EXPECT_MAY_OVERFLOW(Wrap.signedAddMayOverflow(One));2121EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Full));2122EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Wrap));2123
2124ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));2125ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));2126ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));2127EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B1));2128EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B2));2129ConstantRange B3(APInt(16, 0x8000), APInt(16, 0x0201));2130ConstantRange B4(APInt(16, 0x8000), APInt(16, 0x0202));2131EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B3));2132EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B4));2133ConstantRange B5(APInt(16, 0x0299), APInt(16, 0x0400));2134ConstantRange B6(APInt(16, 0x0300), APInt(16, 0x0400));2135EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B5));2136EXPECT_ALWAYS_OVERFLOWS_HIGH(A.signedAddMayOverflow(B6));2137
2138ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));2139ConstantRange D1(APInt(16, 0xfe00), APInt(16, 0xff00));2140ConstantRange D2(APInt(16, 0xfd99), APInt(16, 0xff00));2141EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D1));2142EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D2));2143ConstantRange D3(APInt(16, 0xfe00), APInt(16, 0x8000));2144ConstantRange D4(APInt(16, 0xfd99), APInt(16, 0x8000));2145EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D3));2146EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D4));2147ConstantRange D5(APInt(16, 0xfc00), APInt(16, 0xfd02));2148ConstantRange D6(APInt(16, 0xfc00), APInt(16, 0xfd01));2149EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D5));2150EXPECT_ALWAYS_OVERFLOWS_LOW(C.signedAddMayOverflow(D6));2151
2152ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));2153EXPECT_NEVER_OVERFLOWS(E.signedAddMayOverflow(E));2154ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7000));2155EXPECT_MAY_OVERFLOW(F.signedAddMayOverflow(F));2156}
2157
2158TEST_F(ConstantRangeTest, SignedSubOverflow) {2159// Ill-defined - may overflow is a conservative result.2160EXPECT_MAY_OVERFLOW(Some.signedSubMayOverflow(Empty));2161EXPECT_MAY_OVERFLOW(Empty.signedSubMayOverflow(Some));2162
2163// Never overflow despite one full/wrap set.2164ConstantRange Zero(APInt::getZero(16));2165EXPECT_NEVER_OVERFLOWS(Full.signedSubMayOverflow(Zero));2166EXPECT_NEVER_OVERFLOWS(Wrap.signedSubMayOverflow(Zero));2167
2168// But usually full/wrap always may overflow.2169EXPECT_MAY_OVERFLOW(Full.signedSubMayOverflow(One));2170EXPECT_MAY_OVERFLOW(Wrap.signedSubMayOverflow(One));2171EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Full));2172EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Wrap));2173
2174ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));2175ConstantRange B1(APInt(16, 0xfe00), APInt(16, 0xff00));2176ConstantRange B2(APInt(16, 0xfd99), APInt(16, 0xff00));2177EXPECT_NEVER_OVERFLOWS(A.signedSubMayOverflow(B1));2178EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B2));2179ConstantRange B3(APInt(16, 0xfc00), APInt(16, 0xfd02));2180ConstantRange B4(APInt(16, 0xfc00), APInt(16, 0xfd01));2181EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B3));2182EXPECT_ALWAYS_OVERFLOWS_HIGH(A.signedSubMayOverflow(B4));2183
2184ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));2185ConstantRange D1(APInt(16, 0x0100), APInt(16, 0x0201));2186ConstantRange D2(APInt(16, 0x0100), APInt(16, 0x0202));2187EXPECT_NEVER_OVERFLOWS(C.signedSubMayOverflow(D1));2188EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D2));2189ConstantRange D3(APInt(16, 0x0299), APInt(16, 0x0400));2190ConstantRange D4(APInt(16, 0x0300), APInt(16, 0x0400));2191EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D3));2192EXPECT_ALWAYS_OVERFLOWS_LOW(C.signedSubMayOverflow(D4));2193
2194ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));2195EXPECT_NEVER_OVERFLOWS(E.signedSubMayOverflow(E));2196ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7001));2197EXPECT_MAY_OVERFLOW(F.signedSubMayOverflow(F));2198}
2199
2200template <typename Fn1, typename Fn2>2201static void TestOverflowExhaustive(Fn1 OverflowFn, Fn2 MayOverflowFn) {2202// Constant range overflow checks are tested exhaustively on 4-bit numbers.2203EnumerateTwoInterestingConstantRanges([=](const ConstantRange &CR1,2204const ConstantRange &CR2) {2205// Loop over all N1 in CR1 and N2 in CR2 and check whether any of the2206// operations have overflow / have no overflow.2207bool RangeHasOverflowLow = false;2208bool RangeHasOverflowHigh = false;2209bool RangeHasNoOverflow = false;2210ForeachNumInConstantRange(CR1, [&](const APInt &N1) {2211ForeachNumInConstantRange(CR2, [&](const APInt &N2) {2212bool IsOverflowHigh;2213if (!OverflowFn(IsOverflowHigh, N1, N2)) {2214RangeHasNoOverflow = true;2215return;2216}2217
2218if (IsOverflowHigh)2219RangeHasOverflowHigh = true;2220else2221RangeHasOverflowLow = true;2222});2223});2224
2225ConstantRange::OverflowResult OR = MayOverflowFn(CR1, CR2);2226switch (OR) {2227case ConstantRange::OverflowResult::AlwaysOverflowsLow:2228EXPECT_TRUE(RangeHasOverflowLow);2229EXPECT_FALSE(RangeHasOverflowHigh);2230EXPECT_FALSE(RangeHasNoOverflow);2231break;2232case ConstantRange::OverflowResult::AlwaysOverflowsHigh:2233EXPECT_TRUE(RangeHasOverflowHigh);2234EXPECT_FALSE(RangeHasOverflowLow);2235EXPECT_FALSE(RangeHasNoOverflow);2236break;2237case ConstantRange::OverflowResult::NeverOverflows:2238EXPECT_FALSE(RangeHasOverflowLow);2239EXPECT_FALSE(RangeHasOverflowHigh);2240EXPECT_TRUE(RangeHasNoOverflow);2241break;2242case ConstantRange::OverflowResult::MayOverflow:2243// We return MayOverflow for empty sets as a conservative result,2244// but of course neither the RangeHasOverflow nor the2245// RangeHasNoOverflow flags will be set.2246if (CR1.isEmptySet() || CR2.isEmptySet())2247break;2248
2249EXPECT_TRUE(RangeHasOverflowLow || RangeHasOverflowHigh);2250EXPECT_TRUE(RangeHasNoOverflow);2251break;2252}2253});2254}
2255
2256TEST_F(ConstantRangeTest, UnsignedAddOverflowExhaustive) {2257TestOverflowExhaustive(2258[](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {2259bool Overflow;2260(void) N1.uadd_ov(N2, Overflow);2261IsOverflowHigh = true;2262return Overflow;2263},2264[](const ConstantRange &CR1, const ConstantRange &CR2) {2265return CR1.unsignedAddMayOverflow(CR2);2266});2267}
2268
2269TEST_F(ConstantRangeTest, UnsignedSubOverflowExhaustive) {2270TestOverflowExhaustive(2271[](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {2272bool Overflow;2273(void) N1.usub_ov(N2, Overflow);2274IsOverflowHigh = false;2275return Overflow;2276},2277[](const ConstantRange &CR1, const ConstantRange &CR2) {2278return CR1.unsignedSubMayOverflow(CR2);2279});2280}
2281
2282TEST_F(ConstantRangeTest, UnsignedMulOverflowExhaustive) {2283TestOverflowExhaustive(2284[](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {2285bool Overflow;2286(void) N1.umul_ov(N2, Overflow);2287IsOverflowHigh = true;2288return Overflow;2289},2290[](const ConstantRange &CR1, const ConstantRange &CR2) {2291return CR1.unsignedMulMayOverflow(CR2);2292});2293}
2294
2295TEST_F(ConstantRangeTest, SignedAddOverflowExhaustive) {2296TestOverflowExhaustive(2297[](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {2298bool Overflow;2299(void) N1.sadd_ov(N2, Overflow);2300IsOverflowHigh = N1.isNonNegative();2301return Overflow;2302},2303[](const ConstantRange &CR1, const ConstantRange &CR2) {2304return CR1.signedAddMayOverflow(CR2);2305});2306}
2307
2308TEST_F(ConstantRangeTest, SignedSubOverflowExhaustive) {2309TestOverflowExhaustive(2310[](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {2311bool Overflow;2312(void) N1.ssub_ov(N2, Overflow);2313IsOverflowHigh = N1.isNonNegative();2314return Overflow;2315},2316[](const ConstantRange &CR1, const ConstantRange &CR2) {2317return CR1.signedSubMayOverflow(CR2);2318});2319}
2320
2321TEST_F(ConstantRangeTest, FromKnownBits) {2322KnownBits Unknown(16);2323EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/false));2324EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/true));2325
2326// .10..01. -> unsigned 01000010 (66) to 11011011 (219)2327// -> signed 11000010 (194) to 01011011 (91)2328KnownBits Known(8);2329Known.Zero = 36;2330Known.One = 66;2331ConstantRange Unsigned(APInt(8, 66), APInt(8, 219 + 1));2332ConstantRange Signed(APInt(8, 194), APInt(8, 91 + 1));2333EXPECT_EQ(Unsigned, ConstantRange::fromKnownBits(Known, /*signed*/false));2334EXPECT_EQ(Signed, ConstantRange::fromKnownBits(Known, /*signed*/true));2335
2336// 1.10.10. -> 10100100 (164) to 11101101 (237)2337Known.Zero = 18;2338Known.One = 164;2339ConstantRange CR1(APInt(8, 164), APInt(8, 237 + 1));2340EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/false));2341EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/true));2342
2343// 01.0.1.0 -> 01000100 (68) to 01101110 (110)2344Known.Zero = 145;2345Known.One = 68;2346ConstantRange CR2(APInt(8, 68), APInt(8, 110 + 1));2347EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/false));2348EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/true));2349}
2350
2351TEST_F(ConstantRangeTest, FromKnownBitsExhaustive) {2352unsigned Bits = 4;2353unsigned Max = 1 << Bits;2354KnownBits Known(Bits);2355for (unsigned Zero = 0; Zero < Max; ++Zero) {2356for (unsigned One = 0; One < Max; ++One) {2357Known.Zero = Zero;2358Known.One = One;2359if (Known.hasConflict() || Known.isUnknown())2360continue;2361
2362SmallBitVector Elems(1 << Bits);2363for (unsigned N = 0; N < Max; ++N) {2364APInt Num(Bits, N);2365if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0)2366continue;2367Elems.set(Num.getZExtValue());2368}2369
2370TestRange(ConstantRange::fromKnownBits(Known, false),2371Elems, PreferSmallestUnsigned, {});2372TestRange(ConstantRange::fromKnownBits(Known, true),2373Elems, PreferSmallestSigned, {});2374}2375}2376}
2377
2378TEST_F(ConstantRangeTest, ToKnownBits) {2379EnumerateInterestingConstantRanges([&](const ConstantRange &CR) {2380KnownBits Known = CR.toKnownBits();2381KnownBits ExpectedKnown(CR.getBitWidth());2382ExpectedKnown.Zero.setAllBits();2383ExpectedKnown.One.setAllBits();2384ForeachNumInConstantRange(CR, [&](const APInt &N) {2385ExpectedKnown.One &= N;2386ExpectedKnown.Zero &= ~N;2387});2388// For an empty CR any result would be legal.2389if (!CR.isEmptySet()) {2390EXPECT_EQ(ExpectedKnown, Known);2391}2392});2393}
2394
2395TEST_F(ConstantRangeTest, Negative) {2396// All elements in an empty set (of which there are none) are both negative2397// and non-negative. Empty & full sets checked explicitly for clarity, but2398// they are also covered by the exhaustive test below.2399EXPECT_TRUE(Empty.isAllNegative());2400EXPECT_TRUE(Empty.isAllNonNegative());2401EXPECT_TRUE(Empty.isAllPositive());2402EXPECT_FALSE(Full.isAllNegative());2403EXPECT_FALSE(Full.isAllNonNegative());2404EXPECT_FALSE(Full.isAllPositive());2405
2406EnumerateInterestingConstantRanges([](const ConstantRange &CR) {2407bool AllNegative = true;2408bool AllNonNegative = true;2409bool AllPositive = true;2410ForeachNumInConstantRange(CR, [&](const APInt &N) {2411if (!N.isNegative())2412AllNegative = false;2413if (!N.isNonNegative())2414AllNonNegative = false;2415if (!N.isStrictlyPositive())2416AllPositive = false;2417});2418assert(2419(CR.isEmptySet() || !AllNegative || !AllNonNegative || !AllPositive) &&2420"Only empty set can be all negative, all non-negative, and all "2421"positive");2422
2423EXPECT_EQ(AllNegative, CR.isAllNegative());2424EXPECT_EQ(AllNonNegative, CR.isAllNonNegative());2425EXPECT_EQ(AllPositive, CR.isAllPositive());2426});2427}
2428
2429TEST_F(ConstantRangeTest, UAddSat) {2430TestBinaryOpExhaustive(2431[](const ConstantRange &CR1, const ConstantRange &CR2) {2432return CR1.uadd_sat(CR2);2433},2434[](const APInt &N1, const APInt &N2) {2435return N1.uadd_sat(N2);2436},2437PreferSmallestUnsigned);2438}
2439
2440TEST_F(ConstantRangeTest, USubSat) {2441TestBinaryOpExhaustive(2442[](const ConstantRange &CR1, const ConstantRange &CR2) {2443return CR1.usub_sat(CR2);2444},2445[](const APInt &N1, const APInt &N2) {2446return N1.usub_sat(N2);2447},2448PreferSmallestUnsigned);2449}
2450
2451TEST_F(ConstantRangeTest, UMulSat) {2452TestBinaryOpExhaustive(2453[](const ConstantRange &CR1, const ConstantRange &CR2) {2454return CR1.umul_sat(CR2);2455},2456[](const APInt &N1, const APInt &N2) { return N1.umul_sat(N2); },2457PreferSmallestUnsigned);2458}
2459
2460TEST_F(ConstantRangeTest, UShlSat) {2461TestBinaryOpExhaustive(2462[](const ConstantRange &CR1, const ConstantRange &CR2) {2463return CR1.ushl_sat(CR2);2464},2465[](const APInt &N1, const APInt &N2) { return N1.ushl_sat(N2); },2466PreferSmallestUnsigned);2467}
2468
2469TEST_F(ConstantRangeTest, SAddSat) {2470TestBinaryOpExhaustive(2471[](const ConstantRange &CR1, const ConstantRange &CR2) {2472return CR1.sadd_sat(CR2);2473},2474[](const APInt &N1, const APInt &N2) {2475return N1.sadd_sat(N2);2476},2477PreferSmallestSigned);2478}
2479
2480TEST_F(ConstantRangeTest, SSubSat) {2481TestBinaryOpExhaustive(2482[](const ConstantRange &CR1, const ConstantRange &CR2) {2483return CR1.ssub_sat(CR2);2484},2485[](const APInt &N1, const APInt &N2) {2486return N1.ssub_sat(N2);2487},2488PreferSmallestSigned);2489}
2490
2491TEST_F(ConstantRangeTest, SMulSat) {2492TestBinaryOpExhaustive(2493[](const ConstantRange &CR1, const ConstantRange &CR2) {2494return CR1.smul_sat(CR2);2495},2496[](const APInt &N1, const APInt &N2) { return N1.smul_sat(N2); },2497PreferSmallestSigned);2498}
2499
2500TEST_F(ConstantRangeTest, SShlSat) {2501TestBinaryOpExhaustive(2502[](const ConstantRange &CR1, const ConstantRange &CR2) {2503return CR1.sshl_sat(CR2);2504},2505[](const APInt &N1, const APInt &N2) { return N1.sshl_sat(N2); },2506PreferSmallestSigned);2507}
2508
2509TEST_F(ConstantRangeTest, Abs) {2510TestUnaryOpExhaustive(2511[](const ConstantRange &CR) { return CR.abs(); },2512[](const APInt &N) { return N.abs(); });2513
2514TestUnaryOpExhaustive(2515[](const ConstantRange &CR) { return CR.abs(/*IntMinIsPoison=*/true); },2516[](const APInt &N) -> std::optional<APInt> {2517if (N.isMinSignedValue())2518return std::nullopt;2519return N.abs();2520});2521}
2522
2523TEST_F(ConstantRangeTest, Ctlz) {2524TestUnaryOpExhaustive(2525[](const ConstantRange &CR) { return CR.ctlz(); },2526[](const APInt &N) { return APInt(N.getBitWidth(), N.countl_zero()); });2527
2528TestUnaryOpExhaustive(2529[](const ConstantRange &CR) { return CR.ctlz(/*ZeroIsPoison=*/true); },2530[](const APInt &N) -> std::optional<APInt> {2531if (N.isZero())2532return std::nullopt;2533return APInt(N.getBitWidth(), N.countl_zero());2534});2535}
2536
2537TEST_F(ConstantRangeTest, Cttz) {2538TestUnaryOpExhaustive(2539[](const ConstantRange &CR) { return CR.cttz(); },2540[](const APInt &N) { return APInt(N.getBitWidth(), N.countr_zero()); });2541
2542TestUnaryOpExhaustive(2543[](const ConstantRange &CR) { return CR.cttz(/*ZeroIsPoison=*/true); },2544[](const APInt &N) -> std::optional<APInt> {2545if (N.isZero())2546return std::nullopt;2547return APInt(N.getBitWidth(), N.countr_zero());2548});2549}
2550
2551TEST_F(ConstantRangeTest, Ctpop) {2552TestUnaryOpExhaustive(2553[](const ConstantRange &CR) { return CR.ctpop(); },2554[](const APInt &N) { return APInt(N.getBitWidth(), N.popcount()); });2555}
2556
2557TEST_F(ConstantRangeTest, castOps) {2558ConstantRange A(APInt(16, 66), APInt(16, 128));2559ConstantRange FpToI8 = A.castOp(Instruction::FPToSI, 8);2560EXPECT_EQ(8u, FpToI8.getBitWidth());2561EXPECT_TRUE(FpToI8.isFullSet());2562
2563ConstantRange FpToI16 = A.castOp(Instruction::FPToSI, 16);2564EXPECT_EQ(16u, FpToI16.getBitWidth());2565EXPECT_EQ(A, FpToI16);2566
2567ConstantRange FPExtToDouble = A.castOp(Instruction::FPExt, 64);2568EXPECT_EQ(64u, FPExtToDouble.getBitWidth());2569EXPECT_TRUE(FPExtToDouble.isFullSet());2570
2571ConstantRange PtrToInt = A.castOp(Instruction::PtrToInt, 64);2572EXPECT_EQ(64u, PtrToInt.getBitWidth());2573EXPECT_TRUE(PtrToInt.isFullSet());2574
2575ConstantRange IntToPtr = A.castOp(Instruction::IntToPtr, 64);2576EXPECT_EQ(64u, IntToPtr.getBitWidth());2577EXPECT_TRUE(IntToPtr.isFullSet());2578
2579ConstantRange UIToFP = A.castOp(Instruction::UIToFP, 16);2580EXPECT_EQ(16u, UIToFP.getBitWidth());2581EXPECT_TRUE(UIToFP.isFullSet());2582
2583ConstantRange UIToFP2 = A.castOp(Instruction::UIToFP, 64);2584ConstantRange B(APInt(64, 0), APInt(64, 65536));2585EXPECT_EQ(64u, UIToFP2.getBitWidth());2586EXPECT_EQ(B, UIToFP2);2587
2588ConstantRange SIToFP = A.castOp(Instruction::SIToFP, 16);2589EXPECT_EQ(16u, SIToFP.getBitWidth());2590EXPECT_TRUE(SIToFP.isFullSet());2591
2592ConstantRange SIToFP2 = A.castOp(Instruction::SIToFP, 64);2593ConstantRange C(APInt(64, -32768), APInt(64, 32768));2594EXPECT_EQ(64u, SIToFP2.getBitWidth());2595EXPECT_EQ(C, SIToFP2);2596}
2597
2598TEST_F(ConstantRangeTest, binaryAnd) {2599// Single element ranges.2600ConstantRange R16(APInt(8, 16));2601ConstantRange R20(APInt(8, 20));2602EXPECT_EQ(*R16.binaryAnd(R16).getSingleElement(), APInt(8, 16));2603EXPECT_EQ(*R16.binaryAnd(R20).getSingleElement(), APInt(8, 16 & 20));2604
2605ConstantRange R16_32(APInt(8, 16), APInt(8, 32));2606// 'And' with a high bits mask.2607ConstantRange R32(APInt(8, 32));2608EXPECT_TRUE(R16_32.binaryAnd(R32).getSingleElement()->isZero());2609EXPECT_TRUE(R32.binaryAnd(R16_32).getSingleElement()->isZero());2610// 'And' with a low bits mask. Handled conservatively for now.2611ConstantRange R4(APInt(8, 4));2612ConstantRange R0_5(APInt(8, 0), APInt(8, 5));2613EXPECT_EQ(R16_32.binaryAnd(R4), R0_5);2614EXPECT_EQ(R4.binaryAnd(R16_32), R0_5);2615
2616// Ranges with more than one element. Handled conservatively for now.2617ConstantRange R0_99(APInt(8, 0), APInt(8, 99));2618ConstantRange R0_32(APInt(8, 0), APInt(8, 32));2619EXPECT_EQ(R16_32.binaryAnd(R0_99), R0_32);2620EXPECT_EQ(R0_99.binaryAnd(R16_32), R0_32);2621
2622TestBinaryOpExhaustive(2623[](const ConstantRange &CR1, const ConstantRange &CR2) {2624return CR1.binaryAnd(CR2);2625},2626[](const APInt &N1, const APInt &N2) { return N1 & N2; }, PreferSmallest,2627CheckSingleElementsOnly);2628}
2629
2630TEST_F(ConstantRangeTest, binaryOr) {2631// Single element ranges.2632ConstantRange R16(APInt(8, 16));2633ConstantRange R20(APInt(8, 20));2634EXPECT_EQ(*R16.binaryOr(R16).getSingleElement(), APInt(8, 16));2635EXPECT_EQ(*R16.binaryOr(R20).getSingleElement(), APInt(8, 16 | 20));2636
2637ConstantRange R16_32(APInt(8, 16), APInt(8, 32));2638// 'Or' with a high bits mask.2639// KnownBits estimate is important, otherwise the maximum included element2640// would be 2^8 - 1.2641ConstantRange R32(APInt(8, 32));2642ConstantRange R48_64(APInt(8, 48), APInt(8, 64));2643EXPECT_EQ(R16_32.binaryOr(R32), R48_64);2644EXPECT_EQ(R32.binaryOr(R16_32), R48_64);2645// 'Or' with a low bits mask.2646ConstantRange R4(APInt(8, 4));2647ConstantRange R0_16(APInt(8, 0), APInt(8, 16));2648ConstantRange R4_16(APInt(8, 4), APInt(8, 16));2649EXPECT_EQ(R0_16.binaryOr(R4), R4_16);2650EXPECT_EQ(R4.binaryOr(R0_16), R4_16);2651
2652// Ranges with more than one element. Handled conservatively for now.2653// UMaxUMin estimate is important, otherwise the lower bound would be zero.2654ConstantRange R0_64(APInt(8, 0), APInt(8, 64));2655ConstantRange R5_32(APInt(8, 5), APInt(8, 32));2656ConstantRange R5_64(APInt(8, 5), APInt(8, 64));2657EXPECT_EQ(R0_64.binaryOr(R5_32), R5_64);2658EXPECT_EQ(R5_32.binaryOr(R0_64), R5_64);2659
2660TestBinaryOpExhaustive(2661[](const ConstantRange &CR1, const ConstantRange &CR2) {2662return CR1.binaryOr(CR2);2663},2664[](const APInt &N1, const APInt &N2) { return N1 | N2; }, PreferSmallest,2665CheckSingleElementsOnly);2666}
2667
2668TEST_F(ConstantRangeTest, binaryXor) {2669// Single element ranges.2670ConstantRange R16(APInt(8, 16));2671ConstantRange R20(APInt(8, 20));2672EXPECT_EQ(*R16.binaryXor(R16).getSingleElement(), APInt(8, 0));2673EXPECT_EQ(*R16.binaryXor(R20).getSingleElement(), APInt(8, 16 ^ 20));2674
2675// Ranges with more than a single element.2676ConstantRange R16_35(APInt(8, 16), APInt(8, 35));2677ConstantRange R0_99(APInt(8, 0), APInt(8, 99));2678EXPECT_EQ(R16_35.binaryXor(R16_35), ConstantRange(APInt(8, 0), APInt(8, 64)));2679EXPECT_EQ(R16_35.binaryXor(R0_99), ConstantRange(APInt(8, 0), APInt(8, 128)));2680EXPECT_EQ(R0_99.binaryXor(R16_35), ConstantRange(APInt(8, 0), APInt(8, 128)));2681
2682// Treat xor A, B as sub nsw nuw A, B2683ConstantRange R0_51(APInt(8, 0), APInt(8, 51));2684ConstantRange R63(APInt(8, 63));2685EXPECT_EQ(R0_51.binaryXor(R63), ConstantRange(APInt(8, 13), APInt(8, 64)));2686EXPECT_EQ(R63.binaryXor(R0_51), ConstantRange(APInt(8, 13), APInt(8, 64)));2687
2688TestBinaryOpExhaustive(2689[](const ConstantRange &CR1, const ConstantRange &CR2) {2690return CR1.binaryXor(CR2);2691},2692[](const APInt &N1, const APInt &N2) {2693return N1 ^ N2;2694},2695PreferSmallest,2696CheckSingleElementsOnly);2697}
2698
2699TEST_F(ConstantRangeTest, binaryNot) {2700TestUnaryOpExhaustive(2701[](const ConstantRange &CR) { return CR.binaryNot(); },2702[](const APInt &N) { return ~N; },2703PreferSmallest);2704TestUnaryOpExhaustive(2705[](const ConstantRange &CR) {2706return CR.binaryXor(ConstantRange(APInt::getAllOnes(CR.getBitWidth())));2707},2708[](const APInt &N) { return ~N; }, PreferSmallest);2709TestUnaryOpExhaustive(2710[](const ConstantRange &CR) {2711return ConstantRange(APInt::getAllOnes(CR.getBitWidth())).binaryXor(CR);2712},2713[](const APInt &N) { return ~N; }, PreferSmallest);2714}
2715
2716template <typename T>2717void testConstantRangeICmpPredEquivalence(ICmpInst::Predicate SrcPred, T Func) {2718EnumerateTwoInterestingConstantRanges(2719[&](const ConstantRange &CR1, const ConstantRange &CR2) {2720ICmpInst::Predicate TgtPred;2721bool ExpectedEquivalent;2722std::tie(TgtPred, ExpectedEquivalent) = Func(CR1, CR2);2723if (TgtPred == CmpInst::Predicate::BAD_ICMP_PREDICATE)2724return;2725bool TrulyEquivalent = true;2726ForeachNumInConstantRange(CR1, [&](const APInt &N1) {2727if (!TrulyEquivalent)2728return;2729ForeachNumInConstantRange(CR2, [&](const APInt &N2) {2730if (!TrulyEquivalent)2731return;2732TrulyEquivalent &= ICmpInst::compare(N1, N2, SrcPred) ==2733ICmpInst::compare(N1, N2, TgtPred);2734});2735});2736ASSERT_EQ(TrulyEquivalent, ExpectedEquivalent);2737});2738}
2739
2740TEST_F(ConstantRangeTest, areInsensitiveToSignednessOfICmpPredicate) {2741for (auto Pred : ICmpInst::predicates()) {2742if (ICmpInst::isEquality(Pred))2743continue;2744ICmpInst::Predicate FlippedSignednessPred =2745ICmpInst::getFlippedSignednessPredicate(Pred);2746testConstantRangeICmpPredEquivalence(Pred, [FlippedSignednessPred](2747const ConstantRange &CR1,2748const ConstantRange &CR2) {2749return std::make_pair(2750FlippedSignednessPred,2751ConstantRange::areInsensitiveToSignednessOfICmpPredicate(CR1, CR2));2752});2753}2754}
2755
2756TEST_F(ConstantRangeTest, areInsensitiveToSignednessOfInvertedICmpPredicate) {2757for (auto Pred : ICmpInst::predicates()) {2758if (ICmpInst::isEquality(Pred))2759continue;2760ICmpInst::Predicate InvertedFlippedSignednessPred =2761ICmpInst::getInversePredicate(2762ICmpInst::getFlippedSignednessPredicate(Pred));2763testConstantRangeICmpPredEquivalence(2764Pred, [InvertedFlippedSignednessPred](const ConstantRange &CR1,2765const ConstantRange &CR2) {2766return std::make_pair(2767InvertedFlippedSignednessPred,2768ConstantRange::areInsensitiveToSignednessOfInvertedICmpPredicate(2769CR1, CR2));2770});2771}2772}
2773
2774TEST_F(ConstantRangeTest, getEquivalentPredWithFlippedSignedness) {2775for (auto Pred : ICmpInst::predicates()) {2776if (ICmpInst::isEquality(Pred))2777continue;2778testConstantRangeICmpPredEquivalence(2779Pred, [Pred](const ConstantRange &CR1, const ConstantRange &CR2) {2780return std::make_pair(2781ConstantRange::getEquivalentPredWithFlippedSignedness(Pred, CR1,2782CR2),2783/*ExpectedEquivalent=*/true);2784});2785}2786}
2787
2788TEST_F(ConstantRangeTest, isSizeLargerThan) {2789EXPECT_FALSE(Empty.isSizeLargerThan(0));2790
2791EXPECT_TRUE(Full.isSizeLargerThan(0));2792EXPECT_TRUE(Full.isSizeLargerThan(65535));2793EXPECT_FALSE(Full.isSizeLargerThan(65536));2794
2795EXPECT_TRUE(One.isSizeLargerThan(0));2796EXPECT_FALSE(One.isSizeLargerThan(1));2797}
2798
2799TEST_F(ConstantRangeTest, MakeMaskNotEqualRange) {2800// Mask: 0b0001, C: 0b0001. MMNE() = [2, 1)2801ConstantRange CR(APInt(4, 2), APInt(4, 1));2802EXPECT_EQ(CR, ConstantRange::makeMaskNotEqualRange(APInt(4, 1), APInt(4, 1)));2803EXPECT_NE(CR, ConstantRange::makeMaskNotEqualRange(APInt(4, 0),2804APInt(4, -1, true)));2805EXPECT_TRUE(CR.contains(APInt(4, 7)));2806EXPECT_TRUE(CR.contains(APInt(4, 15)));2807
2808// Mask: 0b0100, C: 0b0100. MMNE() = [-8, 4)2809ConstantRange CR2(APInt(4, -8, true), APInt(4, 4));2810auto MMNE = ConstantRange::makeMaskNotEqualRange(APInt(4, 4), APInt(4, 4));2811EXPECT_EQ(CR2, MMNE);2812EXPECT_NE(ConstantRange::getNonEmpty(APInt(4, 0), APInt(4, -4, true)), MMNE);2813
2814// CR: [-16, -8). MMNE() = [-8, -16)2815ConstantRange CR3(APInt(8, 240), APInt(8, 248));2816EXPECT_EQ(CR3.inverse(),2817ConstantRange::makeMaskNotEqualRange(APInt(8, 248), APInt(8, 240)));2818
2819// Mask: 0, C: 0b1111: unsatisfiable.2820EXPECT_EQ(ConstantRange::getFull(4),2821ConstantRange::makeMaskNotEqualRange(APInt(4, 0), APInt(4, 15)));2822}
2823
2824TEST_F(ConstantRangeTest, MakeMaskNotEqualRangeExhaustive) {2825unsigned Bits = 4;2826unsigned Max = 1 << Bits;2827
2828EnumerateAPInts(Bits, [&](const APInt &Mask) {2829EnumerateAPInts(Bits, [&](const APInt &C) {2830SmallBitVector Elems(Max);2831for (unsigned N = 0; N < Max; ++N) {2832APInt Num(Bits, N);2833if ((Num & Mask) == C)2834continue;2835Elems.set(Num.getZExtValue());2836}2837
2838// Only test optimality with PreferSmallest. E.g., given Mask = 0b0001, C2839// = 0b0001, a possible better range would be [0, 15) when preferring the2840// smallest unsigned, however we conservatively return [2, 1).2841TestRange(ConstantRange::makeMaskNotEqualRange(Mask, C), Elems,2842PreferSmallest, {});2843});2844});2845}
2846
2847} // anonymous namespace2848