From 7fbe5d4b2ab905792158669149ae4f547761ac9c Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Thu, 7 Nov 2019 01:21:29 +0300 Subject: [ConstantRange] Add `subWithNoWrap()` method Summary: Much like D67339, adds ConstantRange handling for when we know no-wrap behavior of the `sub`. Unlike addWithNoWrap(), we only get lucky re returning empty set for signed wrap. For unsigned, we must perform overflow check manually. A patch that makes use of this in LVI (CVP) to be posted later. Reviewers: nikic, shchenz, efriedma Reviewed By: nikic Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69918 --- llvm/unittests/IR/ConstantRangeTest.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'llvm/unittests/IR') diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index eb79711250c..4bc620f3ce8 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -934,6 +934,34 @@ TEST_F(ConstantRangeTest, Sub) { ConstantRange(APInt(16, 0x6))); } +TEST_F(ConstantRangeTest, SubWithNoWrap) { + typedef OverflowingBinaryOperator OBO; + TestAddWithNoSignedWrapExhaustive( + [](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.subWithNoWrap(CR2, OBO::NoSignedWrap); + }, + [](bool &IsOverflow, const APInt &N1, const APInt &N2) { + return N1.ssub_ov(N2, IsOverflow); + }); + TestAddWithNoUnsignedWrapExhaustive( + [](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.subWithNoWrap(CR2, OBO::NoUnsignedWrap); + }, + [](bool &IsOverflow, const APInt &N1, const APInt &N2) { + return N1.usub_ov(N2, IsOverflow); + }); + TestAddWithNoSignedUnsignedWrapExhaustive( + [](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.subWithNoWrap(CR2, OBO::NoUnsignedWrap | OBO::NoSignedWrap); + }, + [](bool &IsOverflow, const APInt &N1, const APInt &N2) { + return N1.ssub_ov(N2, IsOverflow); + }, + [](bool &IsOverflow, const APInt &N1, const APInt &N2) { + return N1.usub_ov(N2, IsOverflow); + }); +} + TEST_F(ConstantRangeTest, Multiply) { EXPECT_EQ(Full.multiply(Full), Full); EXPECT_EQ(Full.multiply(Empty), Empty); -- cgit v1.2.3