brintos

brintos / llvm-project-archived public Read only

0
0
Text · 119.4 KiB · 89a0fae Raw
3561 lines · cpp
1//===- ValueTrackingTest.cpp - ValueTracking 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Analysis/ValueTracking.h"10#include "llvm/ADT/FloatingPointMode.h"11#include "llvm/Analysis/AssumptionCache.h"12#include "llvm/Analysis/FloatingPointPredicateUtils.h"13#include "llvm/AsmParser/Parser.h"14#include "llvm/IR/ConstantRange.h"15#include "llvm/IR/Dominators.h"16#include "llvm/IR/Function.h"17#include "llvm/IR/IRBuilder.h"18#include "llvm/IR/InstIterator.h"19#include "llvm/IR/Instructions.h"20#include "llvm/IR/IntrinsicInst.h"21#include "llvm/IR/LLVMContext.h"22#include "llvm/IR/Module.h"23#include "llvm/Support/ErrorHandling.h"24#include "llvm/Support/KnownBits.h"25#include "llvm/Support/KnownFPClass.h"26#include "llvm/Support/SourceMgr.h"27#include "llvm/Transforms/Utils/Local.h"28#include "gtest/gtest.h"29 30using namespace llvm;31 32namespace {33 34static Instruction *findInstructionByNameOrNull(Function *F, StringRef Name) {35  for (Instruction &I : instructions(F))36    if (I.getName() == Name)37      return &I;38 39  return nullptr;40}41 42static Instruction &findInstructionByName(Function *F, StringRef Name) {43  auto *I = findInstructionByNameOrNull(F, Name);44  if (I)45    return *I;46 47  llvm_unreachable("Expected value not found");48}49 50class ValueTrackingTest : public testing::Test {51protected:52  std::unique_ptr<Module> parseModule(StringRef Assembly) {53    SMDiagnostic Error;54    std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);55 56    std::string errMsg;57    raw_string_ostream os(errMsg);58    Error.print("", os);59    EXPECT_TRUE(M) << errMsg;60 61    return M;62  }63 64  void parseAssembly(StringRef Assembly) {65    M = parseModule(Assembly);66    ASSERT_TRUE(M);67 68    F = M->getFunction("test");69    ASSERT_TRUE(F) << "Test must have a function @test";70    if (!F)71      return;72 73    A = findInstructionByNameOrNull(F, "A");74    ASSERT_TRUE(A) << "@test must have an instruction %A";75    A2 = findInstructionByNameOrNull(F, "A2");76    A3 = findInstructionByNameOrNull(F, "A3");77    A4 = findInstructionByNameOrNull(F, "A4");78    A5 = findInstructionByNameOrNull(F, "A5");79    A6 = findInstructionByNameOrNull(F, "A6");80    A7 = findInstructionByNameOrNull(F, "A7");81 82    CxtI = findInstructionByNameOrNull(F, "CxtI");83    CxtI2 = findInstructionByNameOrNull(F, "CxtI2");84    CxtI3 = findInstructionByNameOrNull(F, "CxtI3");85  }86 87  LLVMContext Context;88  std::unique_ptr<Module> M;89  Function *F = nullptr;90  Instruction *A = nullptr;91  // Instructions (optional)92  Instruction *A2 = nullptr, *A3 = nullptr, *A4 = nullptr, *A5 = nullptr,93              *A6 = nullptr, *A7 = nullptr;94 95  // Context instructions (optional)96  Instruction *CxtI = nullptr, *CxtI2 = nullptr, *CxtI3 = nullptr;97};98 99class MatchSelectPatternTest : public ValueTrackingTest {100protected:101  void expectPattern(const SelectPatternResult &P) {102    Value *LHS, *RHS;103    Instruction::CastOps CastOp;104    SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp);105    EXPECT_EQ(P.Flavor, R.Flavor);106    EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);107    EXPECT_EQ(P.Ordered, R.Ordered);108  }109};110 111class ComputeKnownBitsTest : public ValueTrackingTest {112protected:113  void expectKnownBits(uint64_t Zero, uint64_t One) {114    auto Known = computeKnownBits(A, M->getDataLayout());115    ASSERT_FALSE(Known.hasConflict());116    EXPECT_EQ(Known.One.getZExtValue(), One);117    EXPECT_EQ(Known.Zero.getZExtValue(), Zero);118  }119};120 121class ComputeKnownFPClassTest : public ValueTrackingTest {122protected:123  void expectKnownFPClass(unsigned KnownTrue, std::optional<bool> SignBitKnown,124                          Instruction *TestVal = nullptr) {125    if (!TestVal)126      TestVal = A;127 128    KnownFPClass Known = computeKnownFPClass(TestVal, M->getDataLayout());129    EXPECT_EQ(KnownTrue, Known.KnownFPClasses);130    EXPECT_EQ(SignBitKnown, Known.SignBit);131  }132};133}134 135TEST_F(MatchSelectPatternTest, SimpleFMin) {136  parseAssembly(137      "define float @test(float %a) {\n"138      "  %1 = fcmp ult float %a, 5.0\n"139      "  %A = select i1 %1, float %a, float 5.0\n"140      "  ret float %A\n"141      "}\n");142  expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});143}144 145TEST_F(MatchSelectPatternTest, SimpleFMax) {146  parseAssembly(147      "define float @test(float %a) {\n"148      "  %1 = fcmp ogt float %a, 5.0\n"149      "  %A = select i1 %1, float %a, float 5.0\n"150      "  ret float %A\n"151      "}\n");152  expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});153}154 155TEST_F(MatchSelectPatternTest, SwappedFMax) {156  parseAssembly(157      "define float @test(float %a) {\n"158      "  %1 = fcmp olt float 5.0, %a\n"159      "  %A = select i1 %1, float %a, float 5.0\n"160      "  ret float %A\n"161      "}\n");162  expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});163}164 165TEST_F(MatchSelectPatternTest, SwappedFMax2) {166  parseAssembly(167      "define float @test(float %a) {\n"168      "  %1 = fcmp olt float %a, 5.0\n"169      "  %A = select i1 %1, float 5.0, float %a\n"170      "  ret float %A\n"171      "}\n");172  expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});173}174 175TEST_F(MatchSelectPatternTest, SwappedFMax3) {176  parseAssembly(177      "define float @test(float %a) {\n"178      "  %1 = fcmp ult float %a, 5.0\n"179      "  %A = select i1 %1, float 5.0, float %a\n"180      "  ret float %A\n"181      "}\n");182  expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});183}184 185TEST_F(MatchSelectPatternTest, FastFMin) {186  parseAssembly(187      "define float @test(float %a) {\n"188      "  %1 = fcmp nnan olt float %a, 5.0\n"189      "  %A = select i1 %1, float %a, float 5.0\n"190      "  ret float %A\n"191      "}\n");192  expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, true});193}194 195TEST_F(MatchSelectPatternTest, FastFMinUnordered) {196  parseAssembly("define float @test(float %a) {\n"197                "  %1 = fcmp nnan ult float %a, 5.0\n"198                "  %A = select i1 %1, float %a, float 5.0\n"199                "  ret float %A\n"200                "}\n");201  expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});202}203 204TEST_F(MatchSelectPatternTest, FMinConstantZero) {205  parseAssembly(206      "define float @test(float %a) {\n"207      "  %1 = fcmp ole float %a, 0.0\n"208      "  %A = select i1 %1, float %a, float 0.0\n"209      "  ret float %A\n"210      "}\n");211  // This shouldn't be matched, as %a could be -0.0.212  expectPattern({SPF_UNKNOWN, SPNB_NA, false});213}214 215TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) {216  parseAssembly("define float @test(float %a) {\n"217                "  %1 = fcmp nsz ole float %a, 0.0\n"218                "  %A = select nsz i1 %1, float %a, float 0.0\n"219                "  ret float %A\n"220                "}\n");221  // But this should be, because we've ignored signed zeroes.222  expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});223}224 225TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero1) {226  parseAssembly(227      "define float @test(float %a) {\n"228      "  %1 = fcmp olt float -0.0, %a\n"229      "  %A = select i1 %1, float 0.0, float %a\n"230      "  ret float %A\n"231      "}\n");232  // The sign of zero doesn't matter in fcmp.233  expectPattern({SPF_UNKNOWN, SPNB_NA, false});234}235 236TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero2) {237  parseAssembly(238      "define float @test(float %a) {\n"239      "  %1 = fcmp ogt float %a, -0.0\n"240      "  %A = select i1 %1, float 0.0, float %a\n"241      "  ret float %A\n"242      "}\n");243  // The sign of zero doesn't matter in fcmp.244  expectPattern({SPF_UNKNOWN, SPNB_NA, false});245}246 247TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero3) {248  parseAssembly(249      "define float @test(float %a) {\n"250      "  %1 = fcmp olt float 0.0, %a\n"251      "  %A = select i1 %1, float -0.0, float %a\n"252      "  ret float %A\n"253      "}\n");254  // The sign of zero doesn't matter in fcmp.255  expectPattern({SPF_UNKNOWN, SPNB_NA, false});256}257 258TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero4) {259  parseAssembly(260      "define float @test(float %a) {\n"261      "  %1 = fcmp ogt float %a, 0.0\n"262      "  %A = select i1 %1, float -0.0, float %a\n"263      "  ret float %A\n"264      "}\n");265  // The sign of zero doesn't matter in fcmp.266  expectPattern({SPF_UNKNOWN, SPNB_NA, false});267}268 269TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero5) {270  parseAssembly(271      "define float @test(float %a) {\n"272      "  %1 = fcmp ogt float -0.0, %a\n"273      "  %A = select i1 %1, float %a, float 0.0\n"274      "  ret float %A\n"275      "}\n");276  // The sign of zero doesn't matter in fcmp.277  expectPattern({SPF_UNKNOWN, SPNB_NA, false});278}279 280TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero6) {281  parseAssembly(282      "define float @test(float %a) {\n"283      "  %1 = fcmp olt float %a, -0.0\n"284      "  %A = select i1 %1, float %a, float 0.0\n"285      "  ret float %A\n"286      "}\n");287  // The sign of zero doesn't matter in fcmp.288  expectPattern({SPF_UNKNOWN, SPNB_NA, false});289}290 291TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero7) {292  parseAssembly(293      "define float @test(float %a) {\n"294      "  %1 = fcmp ogt float 0.0, %a\n"295      "  %A = select i1 %1, float %a, float -0.0\n"296      "  ret float %A\n"297      "}\n");298  // The sign of zero doesn't matter in fcmp.299  expectPattern({SPF_UNKNOWN, SPNB_NA, false});300}301 302TEST_F(MatchSelectPatternTest, FMinMismatchConstantZero8) {303  parseAssembly(304      "define float @test(float %a) {\n"305      "  %1 = fcmp olt float %a, 0.0\n"306      "  %A = select i1 %1, float %a, float -0.0\n"307      "  ret float %A\n"308      "}\n");309  // The sign of zero doesn't matter in fcmp.310  expectPattern({SPF_UNKNOWN, SPNB_NA, false});311}312 313TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero1) {314  parseAssembly(315      "define float @test(float %a) {\n"316      "  %1 = fcmp ogt float -0.0, %a\n"317      "  %A = select i1 %1, float 0.0, float %a\n"318      "  ret float %A\n"319      "}\n");320  // The sign of zero doesn't matter in fcmp.321  expectPattern({SPF_UNKNOWN, SPNB_NA, false});322}323 324TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero2) {325  parseAssembly(326      "define float @test(float %a) {\n"327      "  %1 = fcmp olt float %a, -0.0\n"328      "  %A = select i1 %1, float 0.0, float %a\n"329      "  ret float %A\n"330      "}\n");331  // The sign of zero doesn't matter in fcmp.332  expectPattern({SPF_UNKNOWN, SPNB_NA, false});333}334 335TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero3) {336  parseAssembly(337      "define float @test(float %a) {\n"338      "  %1 = fcmp ogt float 0.0, %a\n"339      "  %A = select i1 %1, float -0.0, float %a\n"340      "  ret float %A\n"341      "}\n");342  // The sign of zero doesn't matter in fcmp.343  expectPattern({SPF_UNKNOWN, SPNB_NA, false});344}345 346TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero4) {347  parseAssembly(348      "define float @test(float %a) {\n"349      "  %1 = fcmp olt float %a, 0.0\n"350      "  %A = select i1 %1, float -0.0, float %a\n"351      "  ret float %A\n"352      "}\n");353  // The sign of zero doesn't matter in fcmp.354  expectPattern({SPF_UNKNOWN, SPNB_NA, false});355}356 357TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero5) {358  parseAssembly(359      "define float @test(float %a) {\n"360      "  %1 = fcmp olt float -0.0, %a\n"361      "  %A = select i1 %1, float %a, float 0.0\n"362      "  ret float %A\n"363      "}\n");364  // The sign of zero doesn't matter in fcmp.365  expectPattern({SPF_UNKNOWN, SPNB_NA, false});366}367 368TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero6) {369  parseAssembly(370      "define float @test(float %a) {\n"371      "  %1 = fcmp ogt float %a, -0.0\n"372      "  %A = select i1 %1, float %a, float 0.0\n"373      "  ret float %A\n"374      "}\n");375  // The sign of zero doesn't matter in fcmp.376  expectPattern({SPF_UNKNOWN, SPNB_NA, false});377}378 379TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero7) {380  parseAssembly(381      "define float @test(float %a) {\n"382      "  %1 = fcmp olt float 0.0, %a\n"383      "  %A = select i1 %1, float %a, float -0.0\n"384      "  ret float %A\n"385      "}\n");386  // The sign of zero doesn't matter in fcmp.387  expectPattern({SPF_UNKNOWN, SPNB_NA, false});388}389 390TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZero8) {391  parseAssembly(392      "define float @test(float %a) {\n"393      "  %1 = fcmp ogt float %a, 0.0\n"394      "  %A = select i1 %1, float %a, float -0.0\n"395      "  ret float %A\n"396      "}\n");397  // The sign of zero doesn't matter in fcmp.398  expectPattern({SPF_UNKNOWN, SPNB_NA, false});399}400 401TEST_F(MatchSelectPatternTest, FMinMismatchConstantZeroVecUndef) {402  parseAssembly(403      "define <2 x float> @test(<2 x float> %a) {\n"404      "  %1 = fcmp ogt <2 x float> %a, <float -0.0, float -0.0>\n"405      "  %A = select <2 x i1> %1, <2 x float> <float undef, float 0.0>, <2 x float> %a\n"406      "  ret <2 x float> %A\n"407      "}\n");408  // An undef in a vector constant can not be back-propagated for this analysis.409  expectPattern({SPF_UNKNOWN, SPNB_NA, false});410}411 412TEST_F(MatchSelectPatternTest, FMaxMismatchConstantZeroVecUndef) {413  parseAssembly(414      "define <2 x float> @test(<2 x float> %a) {\n"415      "  %1 = fcmp ogt <2 x float> %a, zeroinitializer\n"416      "  %A = select <2 x i1> %1, <2 x float> %a, <2 x float> <float -0.0, float undef>\n"417      "  ret <2 x float> %A\n"418      "}\n");419  // An undef in a vector constant can not be back-propagated for this analysis.420  expectPattern({SPF_UNKNOWN, SPNB_NA, false});421}422 423TEST_F(MatchSelectPatternTest, VectorFMinimum) {424  parseAssembly(425      "define <4 x float> @test(<4 x float> %a) {\n"426      "  %1 = fcmp ule <4 x float> %a, \n"427      "    <float 5.0, float 5.0, float 5.0, float 5.0>\n"428      "  %A = select <4 x i1> %1, <4 x float> %a,\n"429      "     <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"430      "  ret <4 x float> %A\n"431      "}\n");432  // Check that pattern matching works on vectors where each lane has the same433  // unordered pattern.434  expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});435}436 437TEST_F(MatchSelectPatternTest, VectorFMinOtherOrdered) {438  parseAssembly(439      "define <4 x float> @test(<4 x float> %a) {\n"440      "  %1 = fcmp ole <4 x float> %a, \n"441      "    <float 5.0, float 5.0, float 5.0, float 5.0>\n"442      "  %A = select <4 x i1> %1, <4 x float> %a,\n"443      "     <4 x float> <float 5.0, float 5.0, float 5.0, float 5.0>\n"444      "  ret <4 x float> %A\n"445      "}\n");446  // Check that pattern matching works on vectors where each lane has the same447  // ordered pattern.448  expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});449}450 451TEST_F(MatchSelectPatternTest, VectorNotFMinimum) {452  parseAssembly(453      "define <4 x float> @test(<4 x float> %a) {\n"454      "  %1 = fcmp ule <4 x float> %a, \n"455      "    <float 5.0, float 0x7ff8000000000000, float 5.0, float 5.0>\n"456      "  %A = select <4 x i1> %1, <4 x float> %a,\n"457      "     <4 x float> <float 5.0, float 0x7ff8000000000000, float 5.0, float "458      "5.0>\n"459      "  ret <4 x float> %A\n"460      "}\n");461  // The lane that contains a NaN (0x7ff80...) behaves like a462  // non-NaN-propagating min and the other lines behave like a NaN-propagating463  // min, so check that neither is returned.464  expectPattern({SPF_UNKNOWN, SPNB_NA, false});465}466 467TEST_F(MatchSelectPatternTest, VectorNotFMinZero) {468  parseAssembly(469      "define <4 x float> @test(<4 x float> %a) {\n"470      "  %1 = fcmp ule <4 x float> %a, \n"471      "    <float 5.0, float -0.0, float 5.0, float 5.0>\n"472      "  %A = select <4 x i1> %1, <4 x float> %a,\n"473      "     <4 x float> <float 5.0, float 0.0, float 5.0, float 5.0>\n"474      "  ret <4 x float> %A\n"475      "}\n");476  // Always selects the second lane of %a if it is positive or negative zero, so477  // this is stricter than a min.478  expectPattern({SPF_UNKNOWN, SPNB_NA, false});479}480 481TEST_F(MatchSelectPatternTest, DoubleCastU) {482  parseAssembly(483      "define i32 @test(i8 %a, i8 %b) {\n"484      "  %1 = icmp ult i8 %a, %b\n"485      "  %2 = zext i8 %a to i32\n"486      "  %3 = zext i8 %b to i32\n"487      "  %A = select i1 %1, i32 %2, i32 %3\n"488      "  ret i32 %A\n"489      "}\n");490  // We should be able to look through the situation where we cast both operands491  // to the select.492  expectPattern({SPF_UMIN, SPNB_NA, false});493}494 495TEST_F(MatchSelectPatternTest, DoubleCastS) {496  parseAssembly(497      "define i32 @test(i8 %a, i8 %b) {\n"498      "  %1 = icmp slt i8 %a, %b\n"499      "  %2 = sext i8 %a to i32\n"500      "  %3 = sext i8 %b to i32\n"501      "  %A = select i1 %1, i32 %2, i32 %3\n"502      "  ret i32 %A\n"503      "}\n");504  // We should be able to look through the situation where we cast both operands505  // to the select.506  expectPattern({SPF_SMIN, SPNB_NA, false});507}508 509TEST_F(MatchSelectPatternTest, DoubleCastBad) {510  parseAssembly(511      "define i32 @test(i8 %a, i8 %b) {\n"512      "  %1 = icmp ult i8 %a, %b\n"513      "  %2 = zext i8 %a to i32\n"514      "  %3 = sext i8 %b to i32\n"515      "  %A = select i1 %1, i32 %2, i32 %3\n"516      "  ret i32 %A\n"517      "}\n");518  // The cast types here aren't the same, so we cannot match an UMIN.519  expectPattern({SPF_UNKNOWN, SPNB_NA, false});520}521 522TEST_F(MatchSelectPatternTest, NotNotSMin) {523  parseAssembly(524      "define i8 @test(i8 %a, i8 %b) {\n"525      "  %cmp = icmp sgt i8 %a, %b\n"526      "  %an = xor i8 %a, -1\n"527      "  %bn = xor i8 %b, -1\n"528      "  %A = select i1 %cmp, i8 %an, i8 %bn\n"529      "  ret i8 %A\n"530      "}\n");531  expectPattern({SPF_SMIN, SPNB_NA, false});532}533 534TEST_F(MatchSelectPatternTest, NotNotSMinSwap) {535  parseAssembly(536      "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n"537      "  %cmp = icmp slt <2 x i8> %a, %b\n"538      "  %an = xor <2 x i8> %a, <i8 -1, i8-1>\n"539      "  %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n"540      "  %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n"541      "  ret <2 x i8> %A\n"542      "}\n");543  expectPattern({SPF_SMIN, SPNB_NA, false});544}545 546TEST_F(MatchSelectPatternTest, NotNotSMax) {547  parseAssembly(548      "define i8 @test(i8 %a, i8 %b) {\n"549      "  %cmp = icmp slt i8 %a, %b\n"550      "  %an = xor i8 %a, -1\n"551      "  %bn = xor i8 %b, -1\n"552      "  %A = select i1 %cmp, i8 %an, i8 %bn\n"553      "  ret i8 %A\n"554      "}\n");555  expectPattern({SPF_SMAX, SPNB_NA, false});556}557 558TEST_F(MatchSelectPatternTest, NotNotSMaxSwap) {559  parseAssembly(560      "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n"561      "  %cmp = icmp sgt <2 x i8> %a, %b\n"562      "  %an = xor <2 x i8> %a, <i8 -1, i8-1>\n"563      "  %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n"564      "  %A = select <2 x i1> %cmp, <2 x i8> %bn, <2 x i8> %an\n"565      "  ret <2 x i8> %A\n"566      "}\n");567  expectPattern({SPF_SMAX, SPNB_NA, false});568}569 570TEST_F(MatchSelectPatternTest, NotNotUMin) {571  parseAssembly(572      "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n"573      "  %cmp = icmp ugt <2 x i8> %a, %b\n"574      "  %an = xor <2 x i8> %a, <i8 -1, i8-1>\n"575      "  %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n"576      "  %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n"577      "  ret <2 x i8> %A\n"578      "}\n");579  expectPattern({SPF_UMIN, SPNB_NA, false});580}581 582TEST_F(MatchSelectPatternTest, NotNotUMinSwap) {583  parseAssembly(584      "define i8 @test(i8 %a, i8 %b) {\n"585      "  %cmp = icmp ult i8 %a, %b\n"586      "  %an = xor i8 %a, -1\n"587      "  %bn = xor i8 %b, -1\n"588      "  %A = select i1 %cmp, i8 %bn, i8 %an\n"589      "  ret i8 %A\n"590      "}\n");591  expectPattern({SPF_UMIN, SPNB_NA, false});592}593 594TEST_F(MatchSelectPatternTest, NotNotUMax) {595  parseAssembly(596      "define <2 x i8> @test(<2 x i8> %a, <2 x i8> %b) {\n"597      "  %cmp = icmp ult <2 x i8> %a, %b\n"598      "  %an = xor <2 x i8> %a, <i8 -1, i8-1>\n"599      "  %bn = xor <2 x i8> %b, <i8 -1, i8-1>\n"600      "  %A = select <2 x i1> %cmp, <2 x i8> %an, <2 x i8> %bn\n"601      "  ret <2 x i8> %A\n"602      "}\n");603  expectPattern({SPF_UMAX, SPNB_NA, false});604}605 606TEST_F(MatchSelectPatternTest, NotNotUMaxSwap) {607  parseAssembly(608      "define i8 @test(i8 %a, i8 %b) {\n"609      "  %cmp = icmp ugt i8 %a, %b\n"610      "  %an = xor i8 %a, -1\n"611      "  %bn = xor i8 %b, -1\n"612      "  %A = select i1 %cmp, i8 %bn, i8 %an\n"613      "  ret i8 %A\n"614      "}\n");615  expectPattern({SPF_UMAX, SPNB_NA, false});616}617 618TEST_F(MatchSelectPatternTest, NotNotEq) {619  parseAssembly(620      "define i8 @test(i8 %a, i8 %b) {\n"621      "  %cmp = icmp eq i8 %a, %b\n"622      "  %an = xor i8 %a, -1\n"623      "  %bn = xor i8 %b, -1\n"624      "  %A = select i1 %cmp, i8 %bn, i8 %an\n"625      "  ret i8 %A\n"626      "}\n");627  expectPattern({SPF_UNKNOWN, SPNB_NA, false});628}629 630TEST_F(MatchSelectPatternTest, NotNotNe) {631  parseAssembly(632      "define i8 @test(i8 %a, i8 %b) {\n"633      "  %cmp = icmp ne i8 %a, %b\n"634      "  %an = xor i8 %a, -1\n"635      "  %bn = xor i8 %b, -1\n"636      "  %A = select i1 %cmp, i8 %bn, i8 %an\n"637      "  ret i8 %A\n"638      "}\n");639  expectPattern({SPF_UNKNOWN, SPNB_NA, false});640}641 642TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {643  StringRef Assembly =644      "declare void @nounwind_readonly(ptr) nounwind readonly "645      "declare void @nounwind_argmemonly(ptr) nounwind argmemonly "646      "declare void @nounwind_willreturn(ptr) nounwind willreturn "647      "declare void @throws_but_readonly(ptr) readonly "648      "declare void @throws_but_argmemonly(ptr) argmemonly "649      "declare void @throws_but_willreturn(ptr) willreturn "650      " "651      "declare void @unknown(ptr) "652      " "653      "define void @f(ptr %p) { "654      "  call void @nounwind_readonly(ptr %p) "655      "  call void @nounwind_argmemonly(ptr %p) "656      "  call void @nounwind_willreturn(ptr %p)"657      "  call void @throws_but_readonly(ptr %p) "658      "  call void @throws_but_argmemonly(ptr %p) "659      "  call void @throws_but_willreturn(ptr %p) "660      "  call void @unknown(ptr %p) nounwind readonly "661      "  call void @unknown(ptr %p) nounwind argmemonly "662      "  call void @unknown(ptr %p) nounwind willreturn "663      "  call void @unknown(ptr %p) readonly "664      "  call void @unknown(ptr %p) argmemonly "665      "  call void @unknown(ptr %p) willreturn "666      "  ret void "667      "} ";668 669  LLVMContext Context;670  SMDiagnostic Error;671  auto M = parseAssemblyString(Assembly, Error, Context);672  assert(M && "Bad assembly?");673 674  auto *F = M->getFunction("f");675  assert(F && "Bad assembly?");676 677  auto &BB = F->getEntryBlock();678  bool ExpectedAnswers[] = {679      false, // call void @nounwind_readonly(ptr %p)680      false, // call void @nounwind_argmemonly(ptr %p)681      true,  // call void @nounwind_willreturn(ptr %p)682      false, // call void @throws_but_readonly(ptr %p)683      false, // call void @throws_but_argmemonly(ptr %p)684      false, // call void @throws_but_willreturn(ptr %p)685      false, // call void @unknown(ptr %p) nounwind readonly686      false, // call void @unknown(ptr %p) nounwind argmemonly687      true,  // call void @unknown(ptr %p) nounwind willreturn688      false, // call void @unknown(ptr %p) readonly689      false, // call void @unknown(ptr %p) argmemonly690      false, // call void @unknown(ptr %p) willreturn691      false, // ret void692  };693 694  int Index = 0;695  for (auto &I : BB) {696    EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I),697              ExpectedAnswers[Index])698        << "Incorrect answer at instruction " << Index << " = " << I;699    Index++;700  }701}702 703TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) {704  parseAssembly(705      "define i32 @test(i32 %a) {\n"706      "  %A = ashr i32 %a, -1\n"707      "  ret i32 %A\n"708      "}\n");709  EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 32u);710}711 712// No guarantees for canonical IR in this analysis, so this just bails out.713TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle) {714  parseAssembly(715      "define <2 x i32> @test() {\n"716      "  %A = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> <i32 0, i32 0>\n"717      "  ret <2 x i32> %A\n"718      "}\n");719  EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);720}721 722// No guarantees for canonical IR in this analysis, so a shuffle element that723// references an undef value means this can't return any extra information.724TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) {725  parseAssembly(726      "define <2 x i32> @test(<2 x i1> %x) {\n"727      "  %sext = sext <2 x i1> %x to <2 x i32>\n"728      "  %A = shufflevector <2 x i32> %sext, <2 x i32> undef, <2 x i32> <i32 0, i32 2>\n"729      "  ret <2 x i32> %A\n"730      "}\n");731  EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);732}733 734TEST_F(ValueTrackingTest, impliesPoisonTest_Identity) {735  parseAssembly("define void @test(i32 %x, i32 %y) {\n"736                "  %A = add i32 %x, %y\n"737                "  ret void\n"738                "}");739  EXPECT_TRUE(impliesPoison(A, A));740}741 742TEST_F(ValueTrackingTest, impliesPoisonTest_ICmp) {743  parseAssembly("define void @test(i32 %x) {\n"744                "  %A2 = icmp eq i32 %x, 0\n"745                "  %A = icmp eq i32 %x, 1\n"746                "  ret void\n"747                "}");748  EXPECT_TRUE(impliesPoison(A2, A));749}750 751TEST_F(ValueTrackingTest, impliesPoisonTest_ICmpUnknown) {752  parseAssembly("define void @test(i32 %x, i32 %y) {\n"753                "  %A2 = icmp eq i32 %x, %y\n"754                "  %A = icmp eq i32 %x, 1\n"755                "  ret void\n"756                "}");757  EXPECT_FALSE(impliesPoison(A2, A));758}759 760TEST_F(ValueTrackingTest, impliesPoisonTest_AddNswOkay) {761  parseAssembly("define void @test(i32 %x) {\n"762                "  %A2 = add nsw i32 %x, 1\n"763                "  %A = add i32 %A2, 1\n"764                "  ret void\n"765                "}");766  EXPECT_TRUE(impliesPoison(A2, A));767}768 769TEST_F(ValueTrackingTest, impliesPoisonTest_AddNswOkay2) {770  parseAssembly("define void @test(i32 %x) {\n"771                "  %A2 = add i32 %x, 1\n"772                "  %A = add nsw i32 %A2, 1\n"773                "  ret void\n"774                "}");775  EXPECT_TRUE(impliesPoison(A2, A));776}777 778TEST_F(ValueTrackingTest, impliesPoisonTest_AddNsw) {779  parseAssembly("define void @test(i32 %x) {\n"780                "  %A2 = add nsw i32 %x, 1\n"781                "  %A = add i32 %x, 1\n"782                "  ret void\n"783                "}");784  EXPECT_FALSE(impliesPoison(A2, A));785}786 787TEST_F(ValueTrackingTest, impliesPoisonTest_Cmp) {788  parseAssembly("define void @test(i32 %x, i32 %y, i1 %c) {\n"789                "  %A2 = icmp eq i32 %x, %y\n"790                "  %A0 = icmp ult i32 %x, %y\n"791                "  %A = or i1 %A0, %c\n"792                "  ret void\n"793                "}");794  EXPECT_TRUE(impliesPoison(A2, A));795}796 797TEST_F(ValueTrackingTest, impliesPoisonTest_FCmpFMF) {798  parseAssembly("define void @test(float %x, float %y, i1 %c) {\n"799                "  %A2 = fcmp nnan oeq float %x, %y\n"800                "  %A0 = fcmp olt float %x, %y\n"801                "  %A = or i1 %A0, %c\n"802                "  ret void\n"803                "}");804  EXPECT_FALSE(impliesPoison(A2, A));805}806 807TEST_F(ValueTrackingTest, impliesPoisonTest_AddSubSameOps) {808  parseAssembly("define void @test(i32 %x, i32 %y, i1 %c) {\n"809                "  %A2 = add i32 %x, %y\n"810                "  %A = sub i32 %x, %y\n"811                "  ret void\n"812                "}");813  EXPECT_TRUE(impliesPoison(A2, A));814}815 816TEST_F(ValueTrackingTest, impliesPoisonTest_MaskCmp) {817  parseAssembly("define void @test(i32 %x, i32 %y, i1 %c) {\n"818                "  %M2 = and i32 %x, 7\n"819                "  %A2 = icmp eq i32 %M2, 1\n"820                "  %M = and i32 %x, 15\n"821                "  %A = icmp eq i32 %M, 3\n"822                "  ret void\n"823                "}");824  EXPECT_TRUE(impliesPoison(A2, A));825}826 827TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle_Pointers) {828  parseAssembly(829      "define <2 x ptr> @test(<2 x ptr> %x) {\n"830      "  %A = shufflevector <2 x ptr> zeroinitializer, <2 x ptr> undef, <2 x i32> zeroinitializer\n"831      "  ret <2 x ptr> %A\n"832      "}\n");833  EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 64u);834}835 836TEST(ValueTracking, propagatesPoison) {837  std::string AsmHead =838      "declare i32 @g(i32)\n"839      "define void @f(i32 %x, i32 %y, i32 %shamt, float %fx, float %fy, "840      "i1 %cond, ptr %p) {\n";841  std::string AsmTail = "  ret void\n}";842  // (propagates poison?, IR instruction)843  SmallVector<std::tuple<bool, std::string, unsigned>, 32> Data = {844      {true, "add i32 %x, %y", 0},845      {true, "add i32 %x, %y", 1},846      {true, "add nsw nuw i32 %x, %y", 0},847      {true, "add nsw nuw i32 %x, %y", 1},848      {true, "ashr i32 %x, %y", 0},849      {true, "ashr i32 %x, %y", 1},850      {true, "lshr exact i32 %x, 31", 0},851      {true, "lshr exact i32 %x, 31", 1},852      {true, "fadd float %fx, %fy", 0},853      {true, "fadd float %fx, %fy", 1},854      {true, "fsub float %fx, %fy", 0},855      {true, "fsub float %fx, %fy", 1},856      {true, "fmul float %fx, %fy", 0},857      {true, "fmul float %fx, %fy", 1},858      {true, "fdiv float %fx, %fy", 0},859      {true, "fdiv float %fx, %fy", 1},860      {true, "frem float %fx, %fy", 0},861      {true, "frem float %fx, %fy", 1},862      {true, "fneg float %fx", 0},863      {true, "fcmp oeq float %fx, %fy", 0},864      {true, "fcmp oeq float %fx, %fy", 1},865      {true, "icmp eq i32 %x, %y", 0},866      {true, "icmp eq i32 %x, %y", 1},867      {true, "getelementptr i8, ptr %p, i32 %x", 0},868      {true, "getelementptr i8, ptr %p, i32 %x", 1},869      {true, "getelementptr inbounds i8, ptr %p, i32 %x", 0},870      {true, "getelementptr inbounds i8, ptr %p, i32 %x", 1},871      {true, "bitcast float %fx to i32", 0},872      {true, "select i1 %cond, i32 %x, i32 %y", 0},873      {false, "select i1 %cond, i32 %x, i32 %y", 1},874      {false, "select i1 %cond, i32 %x, i32 %y", 2},875      {false, "freeze i32 %x", 0},876      {true, "udiv i32 %x, %y", 0},877      {true, "udiv i32 %x, %y", 1},878      {true, "urem i32 %x, %y", 0},879      {true, "urem i32 %x, %y", 1},880      {true, "sdiv exact i32 %x, %y", 0},881      {true, "sdiv exact i32 %x, %y", 1},882      {true, "srem i32 %x, %y", 0},883      {true, "srem i32 %x, %y", 1},884      {false, "call i32 @g(i32 %x)", 0},885      {false, "call i32 @g(i32 %x)", 1},886      {true, "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)", 0},887      {true, "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)", 0},888      {true, "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)", 0},889      {true, "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)", 0},890      {true, "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)", 0},891      {true, "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)", 0},892      {true, "call i32 @llvm.sadd.sat.i32(i32 %x, i32 %y)", 0},893      {true, "call i32 @llvm.ssub.sat.i32(i32 %x, i32 %y)", 0},894      {true, "call i32 @llvm.sshl.sat.i32(i32 %x, i32 %y)", 0},895      {true, "call i32 @llvm.uadd.sat.i32(i32 %x, i32 %y)", 0},896      {true, "call i32 @llvm.usub.sat.i32(i32 %x, i32 %y)", 0},897      {true, "call i32 @llvm.ushl.sat.i32(i32 %x, i32 %y)", 0},898      {true, "call i32 @llvm.ctpop.i32(i32 %x)", 0},899      {true, "call i32 @llvm.ctlz.i32(i32 %x, i1 true)", 0},900      {true, "call i32 @llvm.cttz.i32(i32 %x, i1 true)", 0},901      {true, "call i32 @llvm.abs.i32(i32 %x, i1 true)", 0},902      {true, "call i32 @llvm.smax.i32(i32 %x, i32 %y)", 0},903      {true, "call i32 @llvm.smin.i32(i32 %x, i32 %y)", 0},904      {true, "call i32 @llvm.umax.i32(i32 %x, i32 %y)", 0},905      {true, "call i32 @llvm.umin.i32(i32 %x, i32 %y)", 0},906      {true, "call i32 @llvm.bitreverse.i32(i32 %x)", 0},907      {true, "call i32 @llvm.bswap.i32(i32 %x)", 0},908      {false, "call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt)", 0},909      {false, "call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt)", 1},910      {false, "call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %shamt)", 2},911      {false, "call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt)", 0},912      {false, "call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt)", 1},913      {false, "call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %shamt)", 2},914      {true, "call float @llvm.sqrt.f32(float %fx)", 0},915      {true, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0},916      {true, "call float @llvm.sin.f32(float %fx)", 0},917      {true, "call float @llvm.cos.f32(float %fx)", 0},918      {true, "call float @llvm.pow.f32(float %fx, float %fy)", 0},919      {true, "call float @llvm.exp.f32(float %fx)", 0},920      {true, "call float @llvm.exp2.f32(float %fx)", 0},921      {true, "call float @llvm.log.f32(float %fx)", 0},922      {true, "call float @llvm.log10.f32(float %fx)", 0},923      {true, "call float @llvm.log2.f32(float %fx)", 0},924      {false, "call float @llvm.fma.f32(float %fx, float %fx, float %fy)", 0},925      {false, "call float @llvm.fabs.f32(float %fx)", 0},926      {false, "call float @llvm.minnum.f32(float %fx, float %fy)", 0},927      {false, "call float @llvm.maxnum.f32(float %fx, float %fy)", 0},928      {false, "call float @llvm.minimum.f32(float %fx, float %fy)", 0},929      {false, "call float @llvm.maximum.f32(float %fx, float %fy)", 0},930      {false, "call float @llvm.copysign.f32(float %fx, float %fy)", 0},931      {true, "call float @llvm.floor.f32(float %fx)", 0},932      {true, "call float @llvm.ceil.f32(float %fx)", 0},933      {true, "call float @llvm.trunc.f32(float %fx)", 0},934      {true, "call float @llvm.rint.f32(float %fx)", 0},935      {true, "call float @llvm.nearbyint.f32(float %fx)", 0},936      {true, "call float @llvm.round.f32(float %fx)", 0},937      {true, "call float @llvm.roundeven.f32(float %fx)", 0},938      {false, "call i32 @llvm.lround.f32(float %fx)", 0},939      {false, "call i64 @llvm.llround.f32(float %fx)", 0},940      {true, "call i32 @llvm.lrint.f32(float %fx)", 0},941      {true, "call i64 @llvm.llrint.f32(float %fx)", 0},942      {false, "call float @llvm.fmuladd.f32(float %fx, float %fx, float %fy)",943       0}};944 945  std::string AssemblyStr = AsmHead;946  for (auto &Itm : Data)947    AssemblyStr += std::get<1>(Itm) + "\n";948  AssemblyStr += AsmTail;949 950  LLVMContext Context;951  SMDiagnostic Error;952  auto M = parseAssemblyString(AssemblyStr, Error, Context);953  assert(M && "Bad assembly?");954 955  auto *F = M->getFunction("f");956  assert(F && "Bad assembly?");957 958  auto &BB = F->getEntryBlock();959 960  int Index = 0;961  for (auto &I : BB) {962    if (isa<ReturnInst>(&I))963      break;964    bool ExpectedVal = std::get<0>(Data[Index]);965    unsigned OpIdx = std::get<2>(Data[Index]);966    EXPECT_EQ(propagatesPoison(I.getOperandUse(OpIdx)), ExpectedVal)967        << "Incorrect answer at instruction " << Index << " = " << I;968    Index++;969  }970}971 972TEST_F(ValueTrackingTest, programUndefinedIfPoison) {973  parseAssembly("declare i32 @any_num()"974                "define void @test(i32 %mask) {\n"975                "  %A = call i32 @any_num()\n"976                "  %B = or i32 %A, %mask\n"977                "  udiv i32 1, %B"978                "  ret void\n"979                "}\n");980  // If %A was poison, udiv raises UB regardless of %mask's value981  EXPECT_EQ(programUndefinedIfPoison(A), true);982}983 984TEST_F(ValueTrackingTest, programUndefinedIfPoisonSelect) {985  parseAssembly("declare i32 @any_num()"986                "define void @test(i1 %Cond) {\n"987                "  %A = call i32 @any_num()\n"988                "  %B = add i32 %A, 1\n"989                "  %C = select i1 %Cond, i32 %A, i32 %B\n"990                "  udiv i32 1, %C"991                "  ret void\n"992                "}\n");993  // If A is poison, B is also poison, and therefore C is poison regardless of994  // the value of %Cond.995  EXPECT_EQ(programUndefinedIfPoison(A), true);996}997 998TEST_F(ValueTrackingTest, programUndefinedIfUndefOrPoison) {999  parseAssembly("declare i32 @any_num()"1000                "define void @test(i32 %mask) {\n"1001                "  %A = call i32 @any_num()\n"1002                "  %B = or i32 %A, %mask\n"1003                "  udiv i32 1, %B"1004                "  ret void\n"1005                "}\n");1006  // If %A was undef and %mask was 1, udiv does not raise UB1007  EXPECT_EQ(programUndefinedIfUndefOrPoison(A), false);1008}1009 1010TEST_F(ValueTrackingTest, isGuaranteedNotToBePoison_exploitBranchCond) {1011  parseAssembly("declare i1 @any_bool()"1012                "define void @test(i1 %y) {\n"1013                "  %A = call i1 @any_bool()\n"1014                "  %cond = and i1 %A, %y\n"1015                "  br i1 %cond, label %BB1, label %BB2\n"1016                "BB1:\n"1017                "  ret void\n"1018                "BB2:\n"1019                "  ret void\n"1020                "}\n");1021  DominatorTree DT(*F);1022  for (auto &BB : *F) {1023    if (&BB == &F->getEntryBlock())1024      continue;1025 1026    EXPECT_EQ(isGuaranteedNotToBePoison(A, nullptr, BB.getTerminator(), &DT),1027              true)1028        << "isGuaranteedNotToBePoison does not hold at " << *BB.getTerminator();1029  }1030}1031 1032TEST_F(ValueTrackingTest, isGuaranteedNotToBePoison_phi) {1033  parseAssembly("declare i32 @any_i32(i32)"1034                "define void @test() {\n"1035                "ENTRY:\n"1036                "  br label %LOOP\n"1037                "LOOP:\n"1038                "  %A = phi i32 [0, %ENTRY], [%A.next, %NEXT]\n"1039                "  %A.next = call i32 @any_i32(i32 %A)\n"1040                "  %cond = icmp eq i32 %A.next, 0\n"1041                "  br i1 %cond, label %NEXT, label %EXIT\n"1042                "NEXT:\n"1043                "  br label %LOOP\n"1044                "EXIT:\n"1045                "  ret void\n"1046                "}\n");1047  DominatorTree DT(*F);1048  for (auto &BB : *F) {1049    if (BB.getName() == "LOOP") {1050      EXPECT_EQ(isGuaranteedNotToBePoison(A, nullptr, A, &DT), true)1051          << "isGuaranteedNotToBePoison does not hold";1052    }1053  }1054}1055 1056TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison) {1057  parseAssembly("declare void @f(i32 noundef)"1058                "define void @test(i32 %x) {\n"1059                "  %A = bitcast i32 %x to i32\n"1060                "  call void @f(i32 noundef %x)\n"1061                "  ret void\n"1062                "}\n");1063  EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(A), true);1064  EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(UndefValue::get(IntegerType::get(Context, 8))), false);1065  EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(PoisonValue::get(IntegerType::get(Context, 8))), false);1066  EXPECT_EQ(isGuaranteedNotToBePoison(UndefValue::get(IntegerType::get(Context, 8))), true);1067  EXPECT_EQ(isGuaranteedNotToBePoison(PoisonValue::get(IntegerType::get(Context, 8))), false);1068 1069  Type *Int32Ty = Type::getInt32Ty(Context);1070  Constant *CU = UndefValue::get(Int32Ty);1071  Constant *CP = PoisonValue::get(Int32Ty);1072  Constant *C1 = ConstantInt::get(Int32Ty, 1);1073  Constant *C2 = ConstantInt::get(Int32Ty, 2);1074 1075  {1076    Constant *V1 = ConstantVector::get({C1, C2});1077    EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(V1));1078    EXPECT_TRUE(isGuaranteedNotToBePoison(V1));1079  }1080 1081  {1082    Constant *V2 = ConstantVector::get({C1, CU});1083    EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(V2));1084    EXPECT_TRUE(isGuaranteedNotToBePoison(V2));1085  }1086 1087  {1088    Constant *V3 = ConstantVector::get({C1, CP});1089    EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(V3));1090    EXPECT_FALSE(isGuaranteedNotToBePoison(V3));1091  }1092}1093 1094TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_splat) {1095  parseAssembly(1096      "define <4 x i32> @test(i32 noundef %x) {\n"1097      "  %ins = insertelement <4 x i32> poison, i32 %x, i32 0\n"1098      "  %A = shufflevector <4 x i32> %ins, <4 x i32> poison, <4 x i32> zeroinitializer\n"1099      "  ret <4 x i32> %A\n"1100      "}");1101  EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(A));1102}1103 1104TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_assume) {1105  parseAssembly("declare i1 @f_i1()\n"1106                "declare i32 @f_i32()\n"1107                "declare void @llvm.assume(i1)\n"1108                "define void @test() {\n"1109                "  %A = call i32 @f_i32()\n"1110                "  %cond = call i1 @f_i1()\n"1111                "  %CxtI = add i32 0, 0\n"1112                "  br i1 %cond, label %BB1, label %EXIT\n"1113                "BB1:\n"1114                "  %CxtI2 = add i32 0, 0\n"1115                "  %cond2 = call i1 @f_i1()\n"1116                "  call void @llvm.assume(i1 true) [ \"noundef\"(i32 %A) ]\n"1117                "  br i1 %cond2, label %BB2, label %EXIT\n"1118                "BB2:\n"1119                "  %CxtI3 = add i32 0, 0\n"1120                "  ret void\n"1121                "EXIT:\n"1122                "  ret void\n"1123                "}");1124  AssumptionCache AC(*F);1125  DominatorTree DT(*F);1126  EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI, &DT));1127  EXPECT_FALSE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI2, &DT));1128  EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(A, &AC, CxtI3, &DT));1129}1130 1131TEST(ValueTracking, canCreatePoisonOrUndef) {1132  std::string AsmHead =1133      "@s = external dso_local global i32, align 1\n"1134      "declare i32 @g(i32)\n"1135      "declare {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)\n"1136      "declare {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)\n"1137      "declare {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b)\n"1138      "declare {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)\n"1139      "declare {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)\n"1140      "declare {i32, i1} @llvm.umul.with.overflow.i32(i32 %a, i32 %b)\n"1141      "define void @f(i32 %x, i32 %y, float %fx, float %fy, i1 %cond, "1142      "<4 x i32> %vx, <4 x i32> %vx2, <vscale x 4 x i32> %svx, ptr %p) {\n";1143  std::string AsmTail = "  ret void\n}";1144  // (can create poison?, can create undef?, IR instruction)1145  SmallVector<std::pair<std::pair<bool, bool>, std::string>, 32> Data = {1146      {{false, false}, "add i32 %x, %y"},1147      {{true, false}, "add nsw nuw i32 %x, %y"},1148      {{true, false}, "shl i32 %x, %y"},1149      {{true, false}, "shl <4 x i32> %vx, %vx2"},1150      {{true, false}, "shl nsw i32 %x, %y"},1151      {{true, false}, "shl nsw <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"},1152      {{false, false}, "shl i32 %x, 31"},1153      {{true, false}, "shl i32 %x, 32"},1154      {{false, false}, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"},1155      {{true, false}, "shl <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"},1156      {{true, false}, "ashr i32 %x, %y"},1157      {{true, false}, "ashr exact i32 %x, %y"},1158      {{false, false}, "ashr i32 %x, 31"},1159      {{true, false}, "ashr exact i32 %x, 31"},1160      {{false, false}, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"},1161      {{true, false}, "ashr <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 32>"},1162      {{true, false}, "ashr exact <4 x i32> %vx, <i32 0, i32 1, i32 2, i32 3>"},1163      {{true, false}, "lshr i32 %x, %y"},1164      {{true, false}, "lshr exact i32 %x, 31"},1165      {{false, false}, "udiv i32 %x, %y"},1166      {{true, false}, "udiv exact i32 %x, %y"},1167      {{false, false}, "getelementptr i8, ptr %p, i32 %x"},1168      {{true, false}, "getelementptr inbounds i8, ptr %p, i32 %x"},1169      {{true, false}, "fneg nnan float %fx"},1170      {{false, false}, "fneg float %fx"},1171      {{false, false}, "fadd float %fx, %fy"},1172      {{true, false}, "fadd nnan float %fx, %fy"},1173      {{false, false}, "urem i32 %x, %y"},1174      {{true, false}, "fptoui float %fx to i32"},1175      {{true, false}, "fptosi float %fx to i32"},1176      {{false, false}, "bitcast float %fx to i32"},1177      {{false, false}, "select i1 %cond, i32 %x, i32 %y"},1178      {{true, false}, "select nnan i1 %cond, float %fx, float %fy"},1179      {{true, false}, "extractelement <4 x i32> %vx, i32 %x"},1180      {{false, false}, "extractelement <4 x i32> %vx, i32 3"},1181      {{true, false}, "extractelement <vscale x 4 x i32> %svx, i32 4"},1182      {{true, false}, "insertelement <4 x i32> %vx, i32 %x, i32 %y"},1183      {{false, false}, "insertelement <4 x i32> %vx, i32 %x, i32 3"},1184      {{true, false}, "insertelement <vscale x 4 x i32> %svx, i32 %x, i32 4"},1185      {{false, false}, "freeze i32 %x"},1186      {{false, false},1187       "shufflevector <4 x i32> %vx, <4 x i32> %vx2, "1188       "<4 x i32> <i32 0, i32 1, i32 2, i32 3>"},1189      {{true, false},1190       "shufflevector <4 x i32> %vx, <4 x i32> %vx2, "1191       "<4 x i32> <i32 0, i32 1, i32 2, i32 poison>"},1192      {{true, false},1193       "shufflevector <vscale x 4 x i32> %svx, "1194       "<vscale x 4 x i32> %svx, <vscale x 4 x i32> poison"},1195      {{true, false}, "call i32 @g(i32 %x)"},1196      {{false, false}, "call noundef i32 @g(i32 %x)"},1197      {{true, false}, "fcmp nnan oeq float %fx, %fy"},1198      {{false, false}, "fcmp oeq float %fx, %fy"},1199      {{true, false}, "ashr i32 %x, ptrtoint (ptr @s to i32)"},1200      {{false, false},1201       "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)"},1202      {{false, false},1203       "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)"},1204      {{false, false},1205       "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)"},1206      {{false, false},1207       "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)"},1208      {{false, false},1209       "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)"},1210      {{false, false},1211       "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)"}};1212 1213  std::string AssemblyStr = AsmHead;1214  for (auto &Itm : Data)1215    AssemblyStr += Itm.second + "\n";1216  AssemblyStr += AsmTail;1217 1218  LLVMContext Context;1219  SMDiagnostic Error;1220  auto M = parseAssemblyString(AssemblyStr, Error, Context);1221  assert(M && "Bad assembly?");1222 1223  auto *F = M->getFunction("f");1224  assert(F && "Bad assembly?");1225 1226  auto &BB = F->getEntryBlock();1227 1228  int Index = 0;1229  for (auto &I : BB) {1230    if (isa<ReturnInst>(&I))1231      break;1232    bool Poison = Data[Index].first.first;1233    bool Undef = Data[Index].first.second;1234    EXPECT_EQ(canCreatePoison(cast<Operator>(&I)), Poison)1235        << "Incorrect answer of canCreatePoison at instruction " << Index1236        << " = " << I;1237    EXPECT_EQ(canCreateUndefOrPoison(cast<Operator>(&I)), Undef || Poison)1238        << "Incorrect answer of canCreateUndef at instruction " << Index1239        << " = " << I;1240    Index++;1241  }1242}1243 1244TEST_F(ValueTrackingTest, computePtrAlignment) {1245  parseAssembly("declare i1 @f_i1()\n"1246                "declare ptr @f_i8p()\n"1247                "declare void @llvm.assume(i1)\n"1248                "define void @test() {\n"1249                "  %A = call ptr @f_i8p()\n"1250                "  %cond = call i1 @f_i1()\n"1251                "  %CxtI = add i32 0, 0\n"1252                "  br i1 %cond, label %BB1, label %EXIT\n"1253                "BB1:\n"1254                "  %CxtI2 = add i32 0, 0\n"1255                "  %cond2 = call i1 @f_i1()\n"1256                "  call void @llvm.assume(i1 true) [ \"align\"(ptr %A, i64 16) ]\n"1257                "  br i1 %cond2, label %BB2, label %EXIT\n"1258                "BB2:\n"1259                "  %CxtI3 = add i32 0, 0\n"1260                "  ret void\n"1261                "EXIT:\n"1262                "  ret void\n"1263                "}");1264  AssumptionCache AC(*F);1265  DominatorTree DT(*F);1266  const DataLayout &DL = M->getDataLayout();1267  EXPECT_EQ(getKnownAlignment(A, DL, CxtI, &AC, &DT), Align(1));1268  EXPECT_EQ(getKnownAlignment(A, DL, CxtI2, &AC, &DT), Align(1));1269  EXPECT_EQ(getKnownAlignment(A, DL, CxtI3, &AC, &DT), Align(16));1270}1271 1272TEST_F(ValueTrackingTest, MatchBinaryIntrinsicRecurrenceUMax) {1273  auto M = parseModule(R"(1274    define i8 @test(i8 %a, i8 %b) {1275    entry:1276      br label %loop1277    loop:1278      %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]1279      %umax.acc = phi i8 [ %umax, %loop ], [ %a, %entry ]1280      %umax = call i8 @llvm.umax.i8(i8 %umax.acc, i8 %b)1281      %iv.next = add nuw i8 %iv, 11282      %cmp = icmp ult i8 %iv.next, 101283      br i1 %cmp, label %loop, label %exit1284    exit:1285      ret i8 %umax1286    }1287  )");1288 1289  auto *F = M->getFunction("test");1290  auto *II = &cast<IntrinsicInst>(findInstructionByName(F, "umax"));1291  auto *UMaxAcc = &cast<PHINode>(findInstructionByName(F, "umax.acc"));1292  PHINode *PN;1293  Value *Init, *OtherOp;1294  EXPECT_TRUE(matchSimpleBinaryIntrinsicRecurrence(II, PN, Init, OtherOp));1295  EXPECT_EQ(UMaxAcc, PN);1296  EXPECT_EQ(F->getArg(0), Init);1297  EXPECT_EQ(F->getArg(1), OtherOp);1298}1299 1300TEST_F(ValueTrackingTest, MatchBinaryIntrinsicRecurrenceNegativeFSHR) {1301  auto M = parseModule(R"(1302    define i8 @test(i8 %a, i8 %b, i8 %c) {1303    entry:1304      br label %loop1305    loop:1306      %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]1307      %fshr.acc = phi i8 [ %fshr, %loop ], [ %a, %entry ]1308      %fshr = call i8 @llvm.fshr.i8(i8 %fshr.acc, i8 %b, i8 %c)1309      %iv.next = add nuw i8 %iv, 11310      %cmp = icmp ult i8 %iv.next, 101311      br i1 %cmp, label %loop, label %exit1312    exit:1313      ret i8 %fshr1314    }1315  )");1316 1317  auto *F = M->getFunction("test");1318  auto *II = &cast<IntrinsicInst>(findInstructionByName(F, "fshr"));1319  PHINode *PN;1320  Value *Init, *OtherOp;1321  EXPECT_FALSE(matchSimpleBinaryIntrinsicRecurrence(II, PN, Init, OtherOp));1322}1323 1324TEST_F(ComputeKnownBitsTest, ComputeKnownBits) {1325  parseAssembly(1326      "define i32 @test(i32 %a, i32 %b) {\n"1327      "  %ash = mul i32 %a, 8\n"1328      "  %aad = add i32 %ash, 7\n"1329      "  %aan = and i32 %aad, 4095\n"1330      "  %bsh = shl i32 %b, 4\n"1331      "  %bad = or i32 %bsh, 6\n"1332      "  %ban = and i32 %bad, 4095\n"1333      "  %A = mul i32 %aan, %ban\n"1334      "  ret i32 %A\n"1335      "}\n");1336  expectKnownBits(/*zero*/ 4278190085u, /*one*/ 10u);1337}1338 1339TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) {1340  parseAssembly(1341      "define i32 @test(i32 %a, i32 %b) {\n"1342      "  %aa = shl i32 %a, 5\n"1343      "  %bb = shl i32 %b, 5\n"1344      "  %aaa = or i32 %aa, 24\n"1345      "  %bbb = or i32 %bb, 28\n"1346      "  %A = mul i32 %aaa, %bbb\n"1347      "  ret i32 %A\n"1348      "}\n");1349  expectKnownBits(/*zero*/ 95u, /*one*/ 32u);1350}1351 1352TEST_F(ComputeKnownFPClassTest, SelectPos0) {1353  parseAssembly(1354      "define float @test(i1 %cond) {\n"1355      "  %A = select i1 %cond, float 0.0, float 0.0"1356      "  ret float %A\n"1357      "}\n");1358  expectKnownFPClass(fcPosZero, false);1359}1360 1361TEST_F(ComputeKnownFPClassTest, SelectNeg0) {1362  parseAssembly(1363      "define float @test(i1 %cond) {\n"1364      "  %A = select i1 %cond, float -0.0, float -0.0"1365      "  ret float %A\n"1366      "}\n");1367  expectKnownFPClass(fcNegZero, true);1368}1369 1370TEST_F(ComputeKnownFPClassTest, SelectPosOrNeg0) {1371  parseAssembly(1372      "define float @test(i1 %cond) {\n"1373      "  %A = select i1 %cond, float 0.0, float -0.0"1374      "  ret float %A\n"1375      "}\n");1376  expectKnownFPClass(fcZero, std::nullopt);1377}1378 1379TEST_F(ComputeKnownFPClassTest, SelectPosInf) {1380  parseAssembly(1381      "define float @test(i1 %cond) {\n"1382      "  %A = select i1 %cond, float 0x7FF0000000000000, float 0x7FF0000000000000"1383      "  ret float %A\n"1384      "}\n");1385  expectKnownFPClass(fcPosInf, false);1386}1387 1388TEST_F(ComputeKnownFPClassTest, SelectNegInf) {1389  parseAssembly(1390      "define float @test(i1 %cond) {\n"1391      "  %A = select i1 %cond, float 0xFFF0000000000000, float 0xFFF0000000000000"1392      "  ret float %A\n"1393      "}\n");1394  expectKnownFPClass(fcNegInf, true);1395}1396 1397TEST_F(ComputeKnownFPClassTest, SelectPosOrNegInf) {1398  parseAssembly(1399      "define float @test(i1 %cond) {\n"1400      "  %A = select i1 %cond, float 0x7FF0000000000000, float 0xFFF0000000000000"1401      "  ret float %A\n"1402      "}\n");1403  expectKnownFPClass(fcInf, std::nullopt);1404}1405 1406TEST_F(ComputeKnownFPClassTest, SelectNNaN) {1407  parseAssembly(1408      "define float @test(i1 %cond, float %arg0, float %arg1) {\n"1409      "  %A = select nnan i1 %cond, float %arg0, float %arg1"1410      "  ret float %A\n"1411      "}\n");1412  expectKnownFPClass(~fcNan, std::nullopt);1413}1414 1415TEST_F(ComputeKnownFPClassTest, SelectNInf) {1416  parseAssembly(1417      "define float @test(i1 %cond, float %arg0, float %arg1) {\n"1418      "  %A = select ninf i1 %cond, float %arg0, float %arg1"1419      "  ret float %A\n"1420      "}\n");1421  expectKnownFPClass(~fcInf, std::nullopt);1422}1423 1424TEST_F(ComputeKnownFPClassTest, SelectNNaNNInf) {1425  parseAssembly(1426      "define float @test(i1 %cond, float %arg0, float %arg1) {\n"1427      "  %A = select nnan ninf i1 %cond, float %arg0, float %arg1"1428      "  ret float %A\n"1429      "}\n");1430  expectKnownFPClass(~(fcNan | fcInf), std::nullopt);1431}1432 1433TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgUnionAll) {1434  parseAssembly(1435      "define float @test(i1 %cond, float nofpclass(snan ninf nsub pzero pnorm) %arg0, float nofpclass(qnan nnorm nzero psub pinf) %arg1) {\n"1436      "  %A = select i1 %cond, float %arg0, float %arg1"1437      "  ret float %A\n"1438      "}\n");1439  expectKnownFPClass(fcAllFlags, std::nullopt);1440}1441 1442TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoNan) {1443  parseAssembly(1444      "define float @test(i1 %cond, float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {\n"1445      "  %A = select i1 %cond, float %arg0, float %arg1"1446      "  ret float %A\n"1447      "}\n");1448  expectKnownFPClass(~fcNan, std::nullopt);1449}1450 1451TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoPInf) {1452  parseAssembly(1453      "define float @test(i1 %cond, float nofpclass(inf) %arg0, float nofpclass(pinf) %arg1) {\n"1454      "  %A = select i1 %cond, float %arg0, float %arg1"1455      "  ret float %A\n"1456      "}\n");1457  expectKnownFPClass(~fcPosInf, std::nullopt);1458}1459 1460TEST_F(ComputeKnownFPClassTest, SelectNoFPClassArgNoNInf) {1461  parseAssembly(1462      "define float @test(i1 %cond, float nofpclass(ninf) %arg0, float nofpclass(inf) %arg1) {\n"1463      "  %A = select i1 %cond, float %arg0, float %arg1"1464      "  ret float %A\n"1465      "}\n");1466  expectKnownFPClass(~fcNegInf, std::nullopt);1467}1468 1469TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoNan) {1470  parseAssembly(1471      "declare float @func()\n"1472      "define float @test() {\n"1473      "  %A = call nofpclass(nan) float @func()\n"1474      "  ret float %A\n"1475      "}\n");1476  expectKnownFPClass(~fcNan, std::nullopt);1477}1478 1479TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoZeros) {1480  parseAssembly(1481      "declare float @func()\n"1482      "define float @test() {\n"1483      "  %A = call nofpclass(zero) float @func()\n"1484      "  ret float %A\n"1485      "}\n");1486  expectKnownFPClass(~fcZero, std::nullopt);1487}1488 1489TEST_F(ComputeKnownFPClassTest, SelectNoFPClassDeclarationNoNan) {1490  parseAssembly(1491      "declare nofpclass(nan) float @no_nans()\n"1492      "define float @test() {\n"1493      "  %A = call float @no_nans()\n"1494      "  ret float %A\n"1495      "}\n");1496  expectKnownFPClass(~fcNan, std::nullopt);1497}1498 1499// Check nofpclass + ninf works on a callsite1500TEST_F(ComputeKnownFPClassTest, SelectNoFPClassCallSiteNoZerosNInfFlags) {1501  parseAssembly(1502      "declare float @func()\n"1503      "define float @test() {\n"1504      "  %A = call ninf nofpclass(zero) float @func()\n"1505      "  ret float %A\n"1506      "}\n");1507  expectKnownFPClass(~(fcZero | fcInf), std::nullopt);1508}1509 1510TEST_F(ComputeKnownFPClassTest, FNegNInf) {1511  parseAssembly(1512      "define float @test(float %arg) {\n"1513      "  %A = fneg ninf float %arg"1514      "  ret float %A\n"1515      "}\n");1516  expectKnownFPClass(~fcInf, std::nullopt);1517}1518 1519TEST_F(ComputeKnownFPClassTest, FabsUnknown) {1520  parseAssembly(1521      "declare float @llvm.fabs.f32(float)"1522      "define float @test(float %arg) {\n"1523      "  %A = call float @llvm.fabs.f32(float %arg)"1524      "  ret float %A\n"1525      "}\n");1526  expectKnownFPClass(fcPositive | fcNan, false);1527}1528 1529TEST_F(ComputeKnownFPClassTest, FNegFabsUnknown) {1530  parseAssembly(1531      "declare float @llvm.fabs.f32(float)"1532      "define float @test(float %arg) {\n"1533      "  %fabs = call float @llvm.fabs.f32(float %arg)"1534      "  %A = fneg float %fabs"1535      "  ret float %A\n"1536      "}\n");1537  expectKnownFPClass(fcNegative | fcNan, true);1538}1539 1540TEST_F(ComputeKnownFPClassTest, NegFabsNInf) {1541  parseAssembly(1542      "declare float @llvm.fabs.f32(float)"1543      "define float @test(float %arg) {\n"1544      "  %fabs = call ninf float @llvm.fabs.f32(float %arg)"1545      "  %A = fneg float %fabs"1546      "  ret float %A\n"1547      "}\n");1548  expectKnownFPClass((fcNegative & ~fcNegInf) | fcNan, true);1549}1550 1551TEST_F(ComputeKnownFPClassTest, FNegFabsNNaN) {1552  parseAssembly(1553      "declare float @llvm.fabs.f32(float)"1554      "define float @test(float %arg) {\n"1555      "  %fabs = call nnan float @llvm.fabs.f32(float %arg)"1556      "  %A = fneg float %fabs"1557      "  ret float %A\n"1558      "}\n");1559  expectKnownFPClass(fcNegative, true);1560}1561 1562TEST_F(ComputeKnownFPClassTest, CopySignNNanSrc0) {1563  parseAssembly(1564      "declare float @llvm.fabs.f32(float)\n"1565      "declare float @llvm.copysign.f32(float, float)\n"1566      "define float @test(float %arg0, float %arg1) {\n"1567      "  %fabs = call nnan float @llvm.fabs.f32(float %arg0)"1568      "  %A = call float @llvm.copysign.f32(float %fabs, float %arg1)"1569      "  ret float %A\n"1570      "}\n");1571  expectKnownFPClass(~fcNan, std::nullopt);1572}1573 1574TEST_F(ComputeKnownFPClassTest, CopySignNInfSrc0_NegSign) {1575  parseAssembly(1576      "declare float @llvm.log.f32(float)\n"1577      "declare float @llvm.copysign.f32(float, float)\n"1578      "define float @test(float %arg0, float %arg1) {\n"1579      "  %ninf = call ninf float @llvm.log.f32(float %arg0)"1580      "  %A = call float @llvm.copysign.f32(float %ninf, float -1.0)"1581      "  ret float %A\n"1582      "}\n");1583  expectKnownFPClass(fcNegFinite | fcNan, true);1584}1585 1586TEST_F(ComputeKnownFPClassTest, CopySignNInfSrc0_PosSign) {1587  parseAssembly(1588      "declare float @llvm.sqrt.f32(float)\n"1589      "declare float @llvm.copysign.f32(float, float)\n"1590      "define float @test(float %arg0, float %arg1) {\n"1591      "  %ninf = call ninf float @llvm.sqrt.f32(float %arg0)"1592      "  %A = call float @llvm.copysign.f32(float %ninf, float 1.0)"1593      "  ret float %A\n"1594      "}\n");1595  expectKnownFPClass(fcPosFinite | fcNan, false);1596}1597 1598TEST_F(ComputeKnownFPClassTest, UIToFP) {1599  parseAssembly(1600      "define float @test(i32 %arg0, i16 %arg1) {\n"1601      "  %A = uitofp i32 %arg0 to float"1602      "  %A2 = uitofp i16 %arg1 to half"1603      "  ret float %A\n"1604      "}\n");1605  expectKnownFPClass(fcPosFinite & ~fcSubnormal, false, A);1606  expectKnownFPClass(fcPositive & ~fcSubnormal, false, A2);1607}1608 1609TEST_F(ComputeKnownFPClassTest, SIToFP) {1610  parseAssembly(1611      "define float @test(i32 %arg0, i16 %arg1, i17 %arg2) {\n"1612      "  %A = sitofp i32 %arg0 to float"1613      "  %A2 = sitofp i16 %arg1 to half"1614      "  %A3 = sitofp i17 %arg2 to half"1615      "  ret float %A\n"1616      "}\n");1617  expectKnownFPClass(fcFinite & ~fcNegZero & ~fcSubnormal, std::nullopt, A);1618  expectKnownFPClass(fcFinite & ~fcNegZero & ~fcSubnormal, std::nullopt, A2);1619  expectKnownFPClass(~(fcNan | fcNegZero | fcSubnormal), std::nullopt, A3);1620}1621 1622TEST_F(ComputeKnownFPClassTest, FAdd) {1623  parseAssembly(1624      "define float @test(float nofpclass(nan inf) %nnan.ninf, float nofpclass(nan) %nnan, float nofpclass(qnan) %no.qnan, float %unknown) {\n"1625      "  %A = fadd float %nnan, %nnan.ninf"1626      "  %A2 = fadd float %nnan.ninf, %nnan"1627      "  %A3 = fadd float %nnan.ninf, %unknown"1628      "  %A4 = fadd float %nnan.ninf, %no.qnan"1629      "  %A5 = fadd float %nnan, %nnan"1630      "  ret float %A\n"1631      "}\n");1632  expectKnownFPClass(fcFinite | fcInf, std::nullopt, A);1633  expectKnownFPClass(fcFinite | fcInf, std::nullopt, A2);1634  expectKnownFPClass(fcAllFlags, std::nullopt, A3);1635  expectKnownFPClass(fcAllFlags, std::nullopt, A4);1636  expectKnownFPClass(fcAllFlags, std::nullopt, A5);1637}1638 1639TEST_F(ComputeKnownFPClassTest, FSub) {1640  parseAssembly(1641      "define float @test(float nofpclass(nan inf) %nnan.ninf, float nofpclass(nan) %nnan, float nofpclass(qnan) %no.qnan, float %unknown) {\n"1642      "  %A = fsub float %nnan, %nnan.ninf"1643      "  %A2 = fsub float %nnan.ninf, %nnan"1644      "  %A3 = fsub float %nnan.ninf, %unknown"1645      "  %A4 = fsub float %nnan.ninf, %no.qnan"1646      "  %A5 = fsub float %nnan, %nnan"1647      "  ret float %A\n"1648      "}\n");1649  expectKnownFPClass(fcFinite | fcInf, std::nullopt, A);1650  expectKnownFPClass(fcFinite | fcInf, std::nullopt, A2);1651  expectKnownFPClass(fcAllFlags, std::nullopt, A3);1652  expectKnownFPClass(fcAllFlags, std::nullopt, A4);1653  expectKnownFPClass(fcAllFlags, std::nullopt, A5);1654}1655 1656TEST_F(ComputeKnownFPClassTest, FMul) {1657  parseAssembly(1658      "define float @test(float nofpclass(nan inf) %nnan.ninf0, float nofpclass(nan inf) %nnan.ninf1, float nofpclass(nan) %nnan, float nofpclass(qnan) %no.qnan, float %unknown) {\n"1659      "  %A = fmul float %nnan.ninf0, %nnan.ninf1"1660      "  %A2 = fmul float %nnan.ninf0, %nnan"1661      "  %A3 = fmul float %nnan, %nnan.ninf0"1662      "  %A4 = fmul float %nnan.ninf0, %no.qnan"1663      "  %A5 = fmul float %nnan, %nnan"1664      "  ret float %A\n"1665      "}\n");1666  expectKnownFPClass(fcFinite | fcInf, std::nullopt, A);1667  expectKnownFPClass(fcAllFlags, std::nullopt, A2);1668  expectKnownFPClass(fcAllFlags, std::nullopt, A3);1669  expectKnownFPClass(fcAllFlags, std::nullopt, A4);1670  expectKnownFPClass(fcPositive | fcNan, std::nullopt, A5);1671}1672 1673TEST_F(ComputeKnownFPClassTest, FMulNoZero) {1674  parseAssembly(1675      "define float @test(float nofpclass(zero) %no.zero, float nofpclass(zero nan) %no.zero.nan0, float nofpclass(zero nan) %no.zero.nan1, float nofpclass(nzero nan) %no.negzero.nan, float nofpclass(pzero nan) %no.poszero.nan, float nofpclass(inf nan) %no.inf.nan, float nofpclass(inf) %no.inf, float nofpclass(nan) %no.nan) {\n"1676      "  %A = fmul float %no.zero.nan0, %no.zero.nan1"1677      "  %A2 = fmul float %no.zero, %no.zero"1678      "  %A3 = fmul float %no.poszero.nan, %no.zero.nan0"1679      "  %A4 = fmul float %no.nan, %no.zero"1680      "  %A5 = fmul float %no.zero, %no.inf"1681      "  %A6 = fmul float %no.zero.nan0, %no.nan"1682      "  %A7 = fmul float %no.nan, %no.zero.nan0"1683      "  ret float %A\n"1684      "}\n");1685  expectKnownFPClass(fcFinite | fcInf, std::nullopt, A);1686  expectKnownFPClass(fcPositive | fcNan, std::nullopt, A2);1687  expectKnownFPClass(fcAllFlags, std::nullopt, A3);1688  expectKnownFPClass(fcAllFlags, std::nullopt, A4);1689  expectKnownFPClass(fcAllFlags, std::nullopt, A5);1690  expectKnownFPClass(fcAllFlags, std::nullopt, A6);1691  expectKnownFPClass(fcAllFlags, std::nullopt, A7);1692}1693 1694TEST_F(ComputeKnownFPClassTest, MinimumNumSignBit) {1695  parseAssembly(1696      R"(1697      define float @test(1698          float %unknown,1699          float nofpclass(nan) %nnan,1700          float nofpclass(nan pinf pnorm psub pzero) %nnan.nopos,1701          float nofpclass(nan ninf nnorm nsub nzero) %nnan.noneg,1702          float nofpclass(ninf nnorm nsub nzero) %noneg,1703          float nofpclass(pinf pnorm psub pzero) %nopos) {1704        %A = call float @llvm.minimumnum.f32(float %nnan.nopos, float %unknown)1705        %A2 = call float @llvm.minimumnum.f32(float %unknown, float %nnan.nopos)1706        %A3 = call float @llvm.minimumnum.f32(float %nnan.noneg, float %unknown)1707        %A4 = call float @llvm.minimumnum.f32(float %unknown, float %nnan.noneg)1708        %A5 = call float @llvm.minimumnum.f32(float %nnan.nopos, float %nnan.noneg)1709        %A6 = call float @llvm.minimumnum.f32(float %nopos, float %nnan.noneg)1710        %A7 = call float @llvm.minimumnum.f32(float %nnan.nopos, float %noneg)1711        ret float %A1712      })");1713  expectKnownFPClass(fcNegative, true, A);1714  expectKnownFPClass(fcNegative, true, A2);1715  expectKnownFPClass(~fcNan, std::nullopt, A3);1716  expectKnownFPClass(~fcNan, std::nullopt, A4);1717  expectKnownFPClass(fcNegative, true, A5);1718  expectKnownFPClass(~fcNan, std::nullopt, A6);1719  expectKnownFPClass(fcNegative, true, A7);1720}1721 1722TEST_F(ComputeKnownFPClassTest, MaximumNumSignBit) {1723  parseAssembly(1724      R"(1725    define float @test(1726        float %unknown,1727        float nofpclass(nan) %nnan,1728        float nofpclass(nan pinf pnorm psub pzero) %nnan.nopos,1729        float nofpclass(nan ninf nnorm nsub nzero) %nnan.noneg,1730        float nofpclass(ninf nnorm nsub nzero) %noneg,1731        float nofpclass(pinf pnorm psub pzero) %nopos) {1732      %A = call float @llvm.maximumnum.f32(float %nnan.noneg, float %unknown)1733      %A2 = call float @llvm.maximumnum.f32(float %unknown, float %nnan.noneg)1734      %A3 = call float @llvm.maximumnum.f32(float %nnan.nopos, float %unknown)1735      %A4 = call float @llvm.maximumnum.f32(float %unknown, float %nnan.nopos)1736      %A5 = call float @llvm.maximumnum.f32(float %nnan.noneg, float %nnan.nopos)1737      %A6 = call float @llvm.maximumnum.f32(float %noneg, float %nnan.nopos)1738      %A7 = call float @llvm.maximumnum.f32(float %nnan.noneg, float %nopos)1739      ret float %A1740    })");1741  expectKnownFPClass(fcPositive, false, A);1742  expectKnownFPClass(fcPositive, false, A2);1743  expectKnownFPClass(~fcNan, std::nullopt, A3);1744  expectKnownFPClass(~fcNan, std::nullopt, A4);1745  expectKnownFPClass(fcPositive, false, A5);1746  expectKnownFPClass(~fcNan, std::nullopt, A6);1747  expectKnownFPClass(fcPositive, false, A7);1748}1749 1750TEST_F(ComputeKnownFPClassTest, Phi) {1751  parseAssembly(1752      "define float @test(i1 %cond, float nofpclass(nan inf) %arg0, float nofpclass(nan) %arg1) {\n"1753      "entry:\n"1754      "  br i1 %cond, label %bb0, label %bb1\n"1755      "bb0:\n"1756      "  br label %ret\n"1757      "bb1:\n"1758      "  br label %ret\n"1759      "ret:\n"1760      "  %A = phi float [ %arg0, %bb0 ],  [ %arg1, %bb1 ]\n"1761      "  ret float %A\n"1762      "}\n");1763  expectKnownFPClass(~fcNan, std::nullopt);1764}1765 1766TEST_F(ComputeKnownFPClassTest, PhiKnownSignFalse) {1767  parseAssembly(1768      "declare float @llvm.fabs.f32(float)"1769      "define float @test(i1 %cond, float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {\n"1770      "entry:\n"1771      "  br i1 %cond, label %bb0, label %bb1\n"1772      "bb0:\n"1773      "  %fabs.arg0 = call float @llvm.fabs.f32(float %arg0)\n"1774      "  br label %ret\n"1775      "bb1:\n"1776      "  %fabs.arg1 = call float @llvm.fabs.f32(float %arg1)\n"1777      "  br label %ret\n"1778      "ret:\n"1779      "  %A = phi float [ %fabs.arg0, %bb0 ],  [ %fabs.arg1, %bb1 ]\n"1780      "  ret float %A\n"1781      "}\n");1782  expectKnownFPClass(fcPositive, false);1783}1784 1785TEST_F(ComputeKnownFPClassTest, PhiKnownSignTrue) {1786  parseAssembly(1787      "declare float @llvm.fabs.f32(float)"1788      "define float @test(i1 %cond, float nofpclass(nan) %arg0, float %arg1) {\n"1789      "entry:\n"1790      "  br i1 %cond, label %bb0, label %bb1\n"1791      "bb0:\n"1792      "  %fabs.arg0 = call float @llvm.fabs.f32(float %arg0)\n"1793      "  %fneg.fabs.arg0 = fneg float %fabs.arg0\n"1794      "  br label %ret\n"1795      "bb1:\n"1796      "  %fabs.arg1 = call float @llvm.fabs.f32(float %arg1)\n"1797      "  %fneg.fabs.arg1 = fneg float %fabs.arg1\n"1798      "  br label %ret\n"1799      "ret:\n"1800      "  %A = phi float [ %fneg.fabs.arg0, %bb0 ],  [ %fneg.fabs.arg1, %bb1 ]\n"1801      "  ret float %A\n"1802      "}\n");1803  expectKnownFPClass(fcNegative | fcNan, true);1804}1805 1806TEST_F(ComputeKnownFPClassTest, UnreachablePhi) {1807  parseAssembly(1808      "define float @test(float %arg) {\n"1809      "entry:\n"1810      "  ret float 0.0\n"1811      "unreachable:\n"1812      "  %A = phi float\n"1813      "  ret float %A\n"1814      "}\n");1815  expectKnownFPClass(fcAllFlags, std::nullopt);1816}1817 1818TEST_F(ComputeKnownFPClassTest, SelfPhiOnly) {1819  parseAssembly(1820      "define float @test(float %arg) {\n"1821      "entry:\n"1822      "  ret float 0.0\n"1823      "loop:\n"1824      "  %A = phi float [ %A, %loop ]\n"1825      "  br label %loop\n"1826      "}\n");1827  expectKnownFPClass(fcAllFlags, std::nullopt);1828}1829 1830TEST_F(ComputeKnownFPClassTest, SelfPhiFirstArg) {1831  parseAssembly(1832      "define float @test(i1 %cond, float nofpclass(inf) %arg) {\n"1833      "entry:\n"1834      "  br i1 %cond, label %loop, label %ret\n"1835      "loop:\n"1836      "  %A = phi float [ %arg, %entry ], [ %A, %loop ]\n"1837      "  br label %loop\n"1838      "ret:\n"1839      "  ret float %A"1840      "}\n");1841  expectKnownFPClass(~fcInf, std::nullopt);1842}1843 1844TEST_F(ComputeKnownFPClassTest, SelfPhiSecondArg) {1845  parseAssembly(1846      "define float @test(i1 %cond, float nofpclass(inf) %arg) {\n"1847      "entry:\n"1848      "  br i1 %cond, label %loop, label %ret\n"1849      "loop:\n"1850      "  %A = phi float [ %A, %loop ], [ %arg, %entry ]\n"1851      "  br label %loop\n"1852      "ret:\n"1853      "  ret float %A"1854      "}\n");1855  expectKnownFPClass(~fcInf, std::nullopt);1856}1857 1858TEST_F(ComputeKnownFPClassTest, CannotBeOrderedLessThanZero) {1859  parseAssembly("define float @test(float %arg) {\n"1860                "  %A = fmul float %arg, %arg"1861                "  ret float %A\n"1862                "}\n");1863 1864  Type *FPTy = Type::getDoubleTy(M->getContext());1865  const DataLayout &DL = M->getDataLayout();1866 1867  EXPECT_TRUE(1868      computeKnownFPClass(ConstantFP::getZero(FPTy, /*Negative=*/false), DL)1869          .cannotBeOrderedLessThanZero());1870  EXPECT_TRUE(1871      computeKnownFPClass(ConstantFP::getZero(FPTy, /*Negative=*/true), DL)1872          .cannotBeOrderedLessThanZero());1873 1874  EXPECT_TRUE(computeKnownFPClass(ConstantFP::getInfinity(FPTy, false), DL)1875                  .cannotBeOrderedLessThanZero());1876  EXPECT_FALSE(computeKnownFPClass(ConstantFP::getInfinity(FPTy, true), DL)1877                   .cannotBeOrderedLessThanZero());1878 1879  EXPECT_TRUE(computeKnownFPClass(ConstantFP::get(FPTy, 1.0), DL)1880                  .cannotBeOrderedLessThanZero());1881  EXPECT_FALSE(computeKnownFPClass(ConstantFP::get(FPTy, -1.0), DL)1882                   .cannotBeOrderedLessThanZero());1883 1884  EXPECT_TRUE(1885      computeKnownFPClass(1886          ConstantFP::get(FPTy, APFloat::getSmallest(FPTy->getFltSemantics(),1887                                                     /*Negative=*/false)),1888          DL)1889          .cannotBeOrderedLessThanZero());1890  EXPECT_FALSE(1891      computeKnownFPClass(1892          ConstantFP::get(FPTy, APFloat::getSmallest(FPTy->getFltSemantics(),1893                                                     /*Negative=*/true)),1894          DL)1895          .cannotBeOrderedLessThanZero());1896 1897  EXPECT_TRUE(1898      computeKnownFPClass(ConstantFP::getQNaN(FPTy, /*Negative=*/false), DL)1899          .cannotBeOrderedLessThanZero());1900  EXPECT_TRUE(1901      computeKnownFPClass(ConstantFP::getQNaN(FPTy, /*Negative=*/true), DL)1902          .cannotBeOrderedLessThanZero());1903  EXPECT_TRUE(1904      computeKnownFPClass(ConstantFP::getSNaN(FPTy, /*Negative=*/false), DL)1905          .cannotBeOrderedLessThanZero());1906  EXPECT_TRUE(1907      computeKnownFPClass(ConstantFP::getSNaN(FPTy, /*Negative=*/true), DL)1908          .cannotBeOrderedLessThanZero());1909}1910 1911TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_OrdNan) {1912  parseAssembly("define i1 @test(double %arg) {\n"1913                "  %A = fcmp ord double %arg, 0x7FF8000000000000"1914                "  %A2 = fcmp uno double %arg, 0x7FF8000000000000"1915                "  %A3 = fcmp oeq double %arg, 0x7FF8000000000000"1916                "  %A4 = fcmp ueq double %arg, 0x7FF8000000000000"1917                "  ret i1 %A\n"1918                "}\n");1919 1920  auto [OrdVal, OrdClass] = fcmpToClassTest(1921      CmpInst::FCMP_ORD, *A->getFunction(), A->getOperand(0), A->getOperand(1));1922  EXPECT_EQ(A->getOperand(0), OrdVal);1923  EXPECT_EQ(fcNone, OrdClass);1924 1925  auto [UnordVal, UnordClass] =1926      fcmpToClassTest(CmpInst::FCMP_UNO, *A2->getFunction(), A2->getOperand(0),1927                      A2->getOperand(1));1928  EXPECT_EQ(A2->getOperand(0), UnordVal);1929  EXPECT_EQ(fcAllFlags, UnordClass);1930 1931  auto [OeqVal, OeqClass] =1932      fcmpToClassTest(CmpInst::FCMP_OEQ, *A3->getFunction(), A3->getOperand(0),1933                      A3->getOperand(1));1934  EXPECT_EQ(A3->getOperand(0), OeqVal);1935  EXPECT_EQ(fcNone, OeqClass);1936 1937  auto [UeqVal, UeqClass] =1938      fcmpToClassTest(CmpInst::FCMP_UEQ, *A3->getFunction(), A3->getOperand(0),1939                      A3->getOperand(1));1940  EXPECT_EQ(A3->getOperand(0), UeqVal);1941  EXPECT_EQ(fcAllFlags, UeqClass);1942}1943 1944TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_NInf) {1945  parseAssembly("define i1 @test(double %arg) {\n"1946                "  %A = fcmp olt double %arg, 0xFFF0000000000000"1947                "  %A2 = fcmp uge double %arg, 0xFFF0000000000000"1948                "  %A3 = fcmp ogt double %arg, 0xFFF0000000000000"1949                "  %A4 = fcmp ule double %arg, 0xFFF0000000000000"1950                "  %A5 = fcmp oge double %arg, 0xFFF0000000000000"1951                "  %A6 = fcmp ult double %arg, 0xFFF0000000000000"1952                "  ret i1 %A\n"1953                "}\n");1954 1955  auto [OltVal, OltClass] = fcmpToClassTest(1956      CmpInst::FCMP_OLT, *A->getFunction(), A->getOperand(0), A->getOperand(1));1957  EXPECT_EQ(A->getOperand(0), OltVal);1958  EXPECT_EQ(fcNone, OltClass);1959 1960  auto [UgeVal, UgeClass] =1961      fcmpToClassTest(CmpInst::FCMP_UGE, *A2->getFunction(), A2->getOperand(0),1962                      A2->getOperand(1));1963  EXPECT_EQ(A2->getOperand(0), UgeVal);1964  EXPECT_EQ(fcAllFlags, UgeClass);1965 1966  auto [OgtVal, OgtClass] =1967      fcmpToClassTest(CmpInst::FCMP_OGT, *A3->getFunction(), A3->getOperand(0),1968                      A3->getOperand(1));1969  EXPECT_EQ(A3->getOperand(0), OgtVal);1970  EXPECT_EQ(~(fcNegInf | fcNan), OgtClass);1971 1972  auto [UleVal, UleClass] =1973      fcmpToClassTest(CmpInst::FCMP_ULE, *A4->getFunction(), A4->getOperand(0),1974                      A4->getOperand(1));1975  EXPECT_EQ(A4->getOperand(0), UleVal);1976  EXPECT_EQ(fcNegInf | fcNan, UleClass);1977 1978  auto [OgeVal, OgeClass] =1979      fcmpToClassTest(CmpInst::FCMP_OGE, *A5->getFunction(), A5->getOperand(0),1980                      A5->getOperand(1));1981  EXPECT_EQ(A5->getOperand(0), OgeVal);1982  EXPECT_EQ(~fcNan, OgeClass);1983 1984  auto [UltVal, UltClass] =1985      fcmpToClassTest(CmpInst::FCMP_ULT, *A6->getFunction(), A6->getOperand(0),1986                      A6->getOperand(1));1987  EXPECT_EQ(A6->getOperand(0), UltVal);1988  EXPECT_EQ(fcNan, UltClass);1989}1990 1991TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_FabsNInf) {1992  parseAssembly("declare double @llvm.fabs.f64(double)\n"1993                "define i1 @test(double %arg) {\n"1994                "  %fabs.arg = call double @llvm.fabs.f64(double %arg)\n"1995                "  %A = fcmp olt double %fabs.arg, 0xFFF0000000000000"1996                "  %A2 = fcmp uge double %fabs.arg, 0xFFF0000000000000"1997                "  %A3 = fcmp ogt double %fabs.arg, 0xFFF0000000000000"1998                "  %A4 = fcmp ule double %fabs.arg, 0xFFF0000000000000"1999                "  %A5 = fcmp oge double %fabs.arg, 0xFFF0000000000000"2000                "  %A6 = fcmp ult double %fabs.arg, 0xFFF0000000000000"2001                "  ret i1 %A\n"2002                "}\n");2003 2004  Value *ArgVal = F->getArg(0);2005 2006  auto [OltVal, OltClass] = fcmpToClassTest(2007      CmpInst::FCMP_OLT, *A->getFunction(), A->getOperand(0), A->getOperand(1));2008  EXPECT_EQ(ArgVal, OltVal);2009  EXPECT_EQ(fcNone, OltClass);2010 2011  auto [UgeVal, UgeClass] =2012      fcmpToClassTest(CmpInst::FCMP_UGE, *A2->getFunction(), A2->getOperand(0),2013                      A2->getOperand(1));2014  EXPECT_EQ(ArgVal, UgeVal);2015  EXPECT_EQ(fcAllFlags, UgeClass);2016 2017  auto [OgtVal, OgtClass] =2018      fcmpToClassTest(CmpInst::FCMP_OGT, *A3->getFunction(), A3->getOperand(0),2019                      A3->getOperand(1));2020  EXPECT_EQ(ArgVal, OgtVal);2021  EXPECT_EQ(~fcNan, OgtClass);2022 2023  auto [UleVal, UleClass] =2024      fcmpToClassTest(CmpInst::FCMP_ULE, *A4->getFunction(), A4->getOperand(0),2025                      A4->getOperand(1));2026  EXPECT_EQ(ArgVal, UleVal);2027  EXPECT_EQ(fcNan, UleClass);2028 2029  auto [OgeVal, OgeClass] =2030      fcmpToClassTest(CmpInst::FCMP_OGE, *A5->getFunction(), A5->getOperand(0),2031                      A5->getOperand(1));2032  EXPECT_EQ(ArgVal, OgeVal);2033  EXPECT_EQ(~fcNan, OgeClass);2034 2035  auto [UltVal, UltClass] =2036      fcmpToClassTest(CmpInst::FCMP_ULT, *A6->getFunction(), A6->getOperand(0),2037                      A6->getOperand(1));2038  EXPECT_EQ(ArgVal, UltVal);2039  EXPECT_EQ(fcNan, UltClass);2040}2041 2042TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_PInf) {2043  parseAssembly("define i1 @test(double %arg) {\n"2044                "  %A = fcmp ogt double %arg, 0x7FF0000000000000"2045                "  %A2 = fcmp ule double %arg, 0x7FF0000000000000"2046                "  %A3 = fcmp ole double %arg, 0x7FF0000000000000"2047                "  %A4 = fcmp ugt double %arg, 0x7FF0000000000000"2048                "  ret i1 %A\n"2049                "}\n");2050 2051  auto [OgtVal, OgtClass] = fcmpToClassTest(2052      CmpInst::FCMP_OGT, *A->getFunction(), A->getOperand(0), A->getOperand(1));2053  EXPECT_EQ(A->getOperand(0), OgtVal);2054  EXPECT_EQ(fcNone, OgtClass);2055 2056  auto [UleVal, UleClass] =2057      fcmpToClassTest(CmpInst::FCMP_ULE, *A2->getFunction(), A2->getOperand(0),2058                      A2->getOperand(1));2059  EXPECT_EQ(A2->getOperand(0), UleVal);2060  EXPECT_EQ(fcAllFlags, UleClass);2061 2062  auto [OleVal, OleClass] =2063      fcmpToClassTest(CmpInst::FCMP_OLE, *A3->getFunction(), A3->getOperand(0),2064                      A3->getOperand(1));2065  EXPECT_EQ(A->getOperand(0), OleVal);2066  EXPECT_EQ(~fcNan, OleClass);2067 2068  auto [UgtVal, UgtClass] =2069      fcmpToClassTest(CmpInst::FCMP_UGT, *A4->getFunction(), A4->getOperand(0),2070                      A4->getOperand(1));2071  EXPECT_EQ(A4->getOperand(0), UgtVal);2072  EXPECT_EQ(fcNan, UgtClass);2073}2074 2075TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) {2076  parseAssembly(2077      "declare float @llvm.sqrt.f32(float)\n"2078      "define float @test(float %arg, float nofpclass(nan) %arg.nnan) {\n"2079      "  %A = call float @llvm.sqrt.f32(float %arg)\n"2080      "  %A2 = call nsz float @llvm.sqrt.f32(float %arg)\n"2081      "  %A3 = call float @llvm.sqrt.f32(float %arg.nnan)\n"2082      "  %A4 = call nsz float @llvm.sqrt.f32(float %arg.nnan)\n"2083      "  ret float %A\n"2084      "}\n");2085 2086  const FPClassTest SqrtMask = fcPositive | fcNegZero | fcNan;2087  const FPClassTest NszSqrtMask = fcPositive | fcNan;2088 2089  {2090    KnownFPClass UseInstrInfo =2091        computeKnownFPClass(A, M->getDataLayout(), fcAllFlags, nullptr, nullptr,2092                            nullptr, nullptr, /*UseInstrInfo=*/true);2093    EXPECT_EQ(SqrtMask, UseInstrInfo.KnownFPClasses);2094    EXPECT_EQ(std::nullopt, UseInstrInfo.SignBit);2095 2096    KnownFPClass NoUseInstrInfo =2097        computeKnownFPClass(A, M->getDataLayout(), fcAllFlags, nullptr, nullptr,2098                            nullptr, nullptr, /*UseInstrInfo=*/false);2099    EXPECT_EQ(SqrtMask, NoUseInstrInfo.KnownFPClasses);2100    EXPECT_EQ(std::nullopt, NoUseInstrInfo.SignBit);2101  }2102 2103  {2104    KnownFPClass UseInstrInfoNSZ =2105        computeKnownFPClass(A2, M->getDataLayout(), fcAllFlags, nullptr,2106                            nullptr, nullptr, nullptr, /*UseInstrInfo=*/true);2107    EXPECT_EQ(NszSqrtMask, UseInstrInfoNSZ.KnownFPClasses);2108    EXPECT_EQ(std::nullopt, UseInstrInfoNSZ.SignBit);2109 2110    KnownFPClass NoUseInstrInfoNSZ =2111        computeKnownFPClass(A2, M->getDataLayout(), fcAllFlags, nullptr,2112                            nullptr, nullptr, nullptr, /*UseInstrInfo=*/false);2113    EXPECT_EQ(SqrtMask, NoUseInstrInfoNSZ.KnownFPClasses);2114    EXPECT_EQ(std::nullopt, NoUseInstrInfoNSZ.SignBit);2115  }2116 2117  {2118    KnownFPClass UseInstrInfoNoNan =2119        computeKnownFPClass(A3, M->getDataLayout(), fcAllFlags, nullptr,2120                            nullptr, nullptr, nullptr, /*UseInstrInfo=*/true);2121    EXPECT_EQ(fcPositive | fcNegZero | fcQNan,2122              UseInstrInfoNoNan.KnownFPClasses);2123    EXPECT_EQ(std::nullopt, UseInstrInfoNoNan.SignBit);2124 2125    KnownFPClass NoUseInstrInfoNoNan =2126        computeKnownFPClass(A3, M->getDataLayout(), fcAllFlags, nullptr,2127                            nullptr, nullptr, nullptr, /*UseInstrInfo=*/false);2128    EXPECT_EQ(fcPositive | fcNegZero | fcQNan,2129              NoUseInstrInfoNoNan.KnownFPClasses);2130    EXPECT_EQ(std::nullopt, NoUseInstrInfoNoNan.SignBit);2131  }2132 2133  {2134    KnownFPClass UseInstrInfoNSZNoNan =2135        computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, nullptr,2136                            nullptr, nullptr, nullptr, /*UseInstrInfo=*/true);2137    EXPECT_EQ(fcPositive | fcQNan, UseInstrInfoNSZNoNan.KnownFPClasses);2138    EXPECT_EQ(std::nullopt, UseInstrInfoNSZNoNan.SignBit);2139 2140    KnownFPClass NoUseInstrInfoNSZNoNan =2141        computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, nullptr,2142                            nullptr, nullptr, nullptr, /*UseInstrInfo=*/false);2143    EXPECT_EQ(fcPositive | fcNegZero | fcQNan,2144              NoUseInstrInfoNSZNoNan.KnownFPClasses);2145    EXPECT_EQ(std::nullopt, NoUseInstrInfoNSZNoNan.SignBit);2146  }2147}2148 2149TEST_F(ComputeKnownFPClassTest, Constants) {2150  parseAssembly("declare float @func()\n"2151                "define float @test() {\n"2152                "  %A = call float @func()\n"2153                "  ret float %A\n"2154                "}\n");2155 2156  Type *F32 = Type::getFloatTy(Context);2157  Type *V4F32 = FixedVectorType::get(F32, 4);2158 2159  {2160    KnownFPClass ConstAggZero = computeKnownFPClass(2161        ConstantAggregateZero::get(V4F32), M->getDataLayout(), fcAllFlags);2162 2163    EXPECT_EQ(fcPosZero, ConstAggZero.KnownFPClasses);2164    ASSERT_TRUE(ConstAggZero.SignBit);2165    EXPECT_FALSE(*ConstAggZero.SignBit);2166  }2167 2168  {2169    KnownFPClass Undef = computeKnownFPClass(UndefValue::get(F32),2170                                             M->getDataLayout(), fcAllFlags);2171    EXPECT_EQ(fcAllFlags, Undef.KnownFPClasses);2172    EXPECT_FALSE(Undef.SignBit);2173  }2174 2175  {2176    KnownFPClass Poison = computeKnownFPClass(PoisonValue::get(F32),2177                                              M->getDataLayout(), fcAllFlags);2178    EXPECT_EQ(fcNone, Poison.KnownFPClasses);2179    ASSERT_TRUE(Poison.SignBit);2180    EXPECT_FALSE(*Poison.SignBit);2181  }2182 2183  {2184    // Assume the poison element should be 0.2185    Constant *ZeroF32 = ConstantFP::getZero(F32);2186    Constant *PoisonF32 = PoisonValue::get(F32);2187 2188    KnownFPClass PartiallyPoison =2189        computeKnownFPClass(ConstantVector::get({ZeroF32, PoisonF32}),2190                            M->getDataLayout(), fcAllFlags);2191    EXPECT_EQ(fcPosZero, PartiallyPoison.KnownFPClasses);2192    ASSERT_TRUE(PartiallyPoison.SignBit);2193    EXPECT_FALSE(*PartiallyPoison.SignBit);2194  }2195 2196  {2197    // Assume the poison element should be 1.2198    Constant *NegZeroF32 = ConstantFP::getZero(F32, true);2199    Constant *PoisonF32 = PoisonValue::get(F32);2200 2201    KnownFPClass PartiallyPoison =2202        computeKnownFPClass(ConstantVector::get({NegZeroF32, PoisonF32}),2203                            M->getDataLayout(), fcAllFlags);2204    EXPECT_EQ(fcNegZero, PartiallyPoison.KnownFPClasses);2205    ASSERT_TRUE(PartiallyPoison.SignBit);2206    EXPECT_TRUE(*PartiallyPoison.SignBit);2207  }2208 2209  {2210    // Assume the poison element should be 1.2211    Constant *NegZeroF32 = ConstantFP::getZero(F32, true);2212    Constant *PoisonF32 = PoisonValue::get(F32);2213 2214    KnownFPClass PartiallyPoison =2215        computeKnownFPClass(ConstantVector::get({PoisonF32, NegZeroF32}),2216                            M->getDataLayout(), fcAllFlags);2217    EXPECT_EQ(fcNegZero, PartiallyPoison.KnownFPClasses);2218    EXPECT_TRUE(PartiallyPoison.SignBit);2219  }2220}2221 2222TEST_F(ComputeKnownFPClassTest, fcmpImpliesClass_fabs_zero) {2223  parseAssembly("define float @test(float %x) {\n"2224                "  %A = call float @llvm.fabs.f32(float %x)\n"2225                "  ret float %A\n"2226                "}\n");2227  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OEQ, *F, A, fcZero)),2228            fcZero);2229  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UEQ, *F, A, fcZero)),2230            fcZero | fcNan);2231  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UNE, *F, A, fcZero)),2232            ~fcZero);2233  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ONE, *F, A, fcZero)),2234            ~fcNan & ~fcZero);2235  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ORD, *F, A, fcZero)),2236            ~fcNan);2237  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UNO, *F, A, fcZero)),2238            fcNan);2239  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OGT, *F, A, fcZero)),2240            fcSubnormal | fcNormal | fcInf);2241  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UGT, *F, A, fcZero)),2242            fcSubnormal | fcNormal | fcInf | fcNan);2243  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OGE, *F, A, fcZero)),2244            ~fcNan);2245  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UGE, *F, A, fcZero)),2246            fcAllFlags);2247  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OLT, *F, A, fcZero)),2248            fcNone);2249  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ULT, *F, A, fcZero)),2250            fcNan);2251  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OLE, *F, A, fcZero)),2252            fcZero);2253  EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ULE, *F, A, fcZero)),2254            fcZero | fcNan);2255}2256 2257TEST_F(ValueTrackingTest, isNonZeroRecurrence) {2258  parseAssembly(R"(2259    define i1 @test(i8 %n, i8 %r) {2260    entry:2261      br label %loop2262    loop:2263      %p = phi i8 [ -1, %entry ], [ %next, %loop ]2264      %next = add nsw i8 %p, -12265      %cmp1 = icmp eq i8 %p, %n2266      br i1 %cmp1, label %exit, label %loop2267    exit:2268      %A = or i8 %p, %r2269      %CxtI = icmp eq i8 %A, 02270      ret i1 %CxtI2271    }2272  )");2273  const DataLayout &DL = M->getDataLayout();2274  AssumptionCache AC(*F);2275  EXPECT_TRUE(isKnownNonZero(A, SimplifyQuery(DL, /*DT=*/nullptr, &AC, CxtI)));2276}2277 2278TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond) {2279  parseAssembly(R"(2280    declare ptr @f_i8()2281    define void @test(i1 %c) {2282      %A = call ptr @f_i8()2283      %B = call ptr @f_i8()2284      %c1 = icmp ne ptr %A, null2285      %cond = and i1 %c1, %c2286      br i1 %cond, label %T, label %Q2287    T:2288      %CxtI = add i32 0, 02289      ret void2290    Q:2291      %CxtI2 = add i32 0, 02292      ret void2293    }2294  )");2295  AssumptionCache AC(*F);2296  DominatorTree DT(*F);2297  const DataLayout &DL = M->getDataLayout();2298  const SimplifyQuery SQ(DL, &DT, &AC);2299  EXPECT_EQ(isKnownNonZero(A, SQ.getWithInstruction(CxtI)), true);2300  EXPECT_EQ(isKnownNonZero(A, SQ.getWithInstruction(CxtI2)), false);2301}2302 2303TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond2) {2304  parseAssembly(R"(2305    declare ptr @f_i8()2306    define void @test(i1 %c) {2307      %A = call ptr @f_i8()2308      %B = call ptr @f_i8()2309      %c1 = icmp ne ptr %A, null2310      %cond = select i1 %c, i1 %c1, i1 false2311      br i1 %cond, label %T, label %Q2312    T:2313      %CxtI = add i32 0, 02314      ret void2315    Q:2316      %CxtI2 = add i32 0, 02317      ret void2318    }2319  )");2320  AssumptionCache AC(*F);2321  DominatorTree DT(*F);2322  const DataLayout &DL = M->getDataLayout();2323  const SimplifyQuery SQ(DL, &DT, &AC);2324  EXPECT_EQ(isKnownNonZero(A, SQ.getWithInstruction(CxtI)), true);2325  EXPECT_EQ(isKnownNonZero(A, SQ.getWithInstruction(CxtI2)), false);2326}2327 2328TEST_F(ValueTrackingTest, IsImpliedConditionAnd) {2329  parseAssembly(R"(2330    define void @test(i32 %x, i32 %y) {2331      %c1 = icmp ult i32 %x, 102332      %c2 = icmp ult i32 %y, 152333      %A = and i1 %c1, %c22334      ; x < 10 /\ y < 152335      %A2 = icmp ult i32 %x, 202336      %A3 = icmp uge i32 %y, 202337      %A4 = icmp ult i32 %x, 52338      ret void2339    }2340  )");2341  const DataLayout &DL = M->getDataLayout();2342  EXPECT_EQ(isImpliedCondition(A, A2, DL), true);2343  EXPECT_EQ(isImpliedCondition(A, A3, DL), false);2344  EXPECT_EQ(isImpliedCondition(A, A4, DL), std::nullopt);2345}2346 2347TEST_F(ValueTrackingTest, IsImpliedConditionAnd2) {2348  parseAssembly(R"(2349    define void @test(i32 %x, i32 %y) {2350      %c1 = icmp ult i32 %x, 102351      %c2 = icmp ult i32 %y, 152352      %A = select i1 %c1, i1 %c2, i1 false2353      ; x < 10 /\ y < 152354      %A2 = icmp ult i32 %x, 202355      %A3 = icmp uge i32 %y, 202356      %A4 = icmp ult i32 %x, 52357      ret void2358    }2359  )");2360  const DataLayout &DL = M->getDataLayout();2361  EXPECT_EQ(isImpliedCondition(A, A2, DL), true);2362  EXPECT_EQ(isImpliedCondition(A, A3, DL), false);2363  EXPECT_EQ(isImpliedCondition(A, A4, DL), std::nullopt);2364}2365 2366TEST_F(ValueTrackingTest, IsImpliedConditionAndVec) {2367  parseAssembly(R"(2368    define void @test(<2 x i8> %x, <2 x i8> %y) {2369      %A = icmp ult <2 x i8> %x, %y2370      %A2 = icmp ule <2 x i8> %x, %y2371      ret void2372    }2373  )");2374  const DataLayout &DL = M->getDataLayout();2375  EXPECT_EQ(isImpliedCondition(A, A2, DL), true);2376}2377 2378TEST_F(ValueTrackingTest, IsImpliedConditionOr) {2379  parseAssembly(R"(2380    define void @test(i32 %x, i32 %y) {2381      %c1 = icmp ult i32 %x, 102382      %c2 = icmp ult i32 %y, 152383      %A = or i1 %c1, %c2 ; negated2384      ; x >= 10 /\ y >= 152385      %A2 = icmp ult i32 %x, 52386      %A3 = icmp uge i32 %y, 102387      %A4 = icmp ult i32 %x, 152388      ret void2389    }2390  )");2391  const DataLayout &DL = M->getDataLayout();2392  EXPECT_EQ(isImpliedCondition(A, A2, DL, false), false);2393  EXPECT_EQ(isImpliedCondition(A, A3, DL, false), true);2394  EXPECT_EQ(isImpliedCondition(A, A4, DL, false), std::nullopt);2395}2396 2397TEST_F(ValueTrackingTest, IsImpliedConditionOr2) {2398  parseAssembly(R"(2399    define void @test(i32 %x, i32 %y) {2400      %c1 = icmp ult i32 %x, 102401      %c2 = icmp ult i32 %y, 152402      %A = select i1 %c1, i1 true, i1 %c2 ; negated2403      ; x >= 10 /\ y >= 152404      %A2 = icmp ult i32 %x, 52405      %A3 = icmp uge i32 %y, 102406      %A4 = icmp ult i32 %x, 152407      ret void2408    }2409  )");2410  const DataLayout &DL = M->getDataLayout();2411  EXPECT_EQ(isImpliedCondition(A, A2, DL, false), false);2412  EXPECT_EQ(isImpliedCondition(A, A3, DL, false), true);2413  EXPECT_EQ(isImpliedCondition(A, A4, DL, false), std::nullopt);2414}2415 2416TEST_F(ComputeKnownBitsTest, KnownNonZeroShift) {2417  // %q is known nonzero without known bits.2418  // Because %q is nonzero, %A[0] is known to be zero.2419  parseAssembly(2420      "define i8 @test(i8 %p, ptr %pq) {\n"2421      "  %q = load i8, ptr %pq, !range !0\n"2422      "  %A = shl i8 %p, %q\n"2423      "  ret i8 %A\n"2424      "}\n"2425      "!0 = !{ i8 1, i8 5 }\n");2426  expectKnownBits(/*zero*/ 1u, /*one*/ 0u);2427}2428 2429TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) {2430  // fshl(....1111....0000, 00..1111........, 6)2431  // = 11....000000..112432  parseAssembly(2433      "define i16 @test(i16 %a, i16 %b) {\n"2434      "  %aa = shl i16 %a, 4\n"2435      "  %bb = lshr i16 %b, 2\n"2436      "  %aaa = or i16 %aa, 3840\n"2437      "  %bbb = or i16 %bb, 3840\n"2438      "  %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n"2439      "  ret i16 %A\n"2440      "}\n"2441      "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");2442  expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);2443}2444 2445TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) {2446  // fshr(....1111....0000, 00..1111........, 26)2447  // = 11....000000..112448  parseAssembly(2449      "define i16 @test(i16 %a, i16 %b) {\n"2450      "  %aa = shl i16 %a, 4\n"2451      "  %bb = lshr i16 %b, 2\n"2452      "  %aaa = or i16 %aa, 3840\n"2453      "  %bbb = or i16 %bb, 3840\n"2454      "  %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n"2455      "  ret i16 %A\n"2456      "}\n"2457      "declare i16 @llvm.fshr.i16(i16, i16, i16)\n");2458  expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);2459}2460 2461TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) {2462  // fshl(....1111....0000, 00..1111........, 0)2463  // = ....1111....00002464  parseAssembly(2465      "define i16 @test(i16 %a, i16 %b) {\n"2466      "  %aa = shl i16 %a, 4\n"2467      "  %bb = lshr i16 %b, 2\n"2468      "  %aaa = or i16 %aa, 3840\n"2469      "  %bbb = or i16 %bb, 3840\n"2470      "  %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n"2471      "  ret i16 %A\n"2472      "}\n"2473      "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");2474  expectKnownBits(/*zero*/ 15u, /*one*/ 3840u);2475}2476 2477TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) {2478  // uadd.sat(1111...1, ........)2479  // = 1111....2480  parseAssembly(2481      "define i8 @test(i8 %a, i8 %b) {\n"2482      "  %aa = or i8 %a, 241\n"2483      "  %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n"2484      "  ret i8 %A\n"2485      "}\n"2486      "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");2487  expectKnownBits(/*zero*/ 0u, /*one*/ 240u);2488}2489 2490TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) {2491  // uadd.sat(00...011, .1...110)2492  // = .......12493  parseAssembly(2494      "define i8 @test(i8 %a, i8 %b) {\n"2495      "  %aa = or i8 %a, 3\n"2496      "  %aaa = and i8 %aa, 59\n"2497      "  %bb = or i8 %b, 70\n"2498      "  %bbb = and i8 %bb, 254\n"2499      "  %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n"2500      "  ret i8 %A\n"2501      "}\n"2502      "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");2503  expectKnownBits(/*zero*/ 0u, /*one*/ 1u);2504}2505 2506TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) {2507  // usub.sat(0000...0, ........)2508  // = 0000....2509  parseAssembly(2510      "define i8 @test(i8 %a, i8 %b) {\n"2511      "  %aa = and i8 %a, 14\n"2512      "  %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n"2513      "  ret i8 %A\n"2514      "}\n"2515      "declare i8 @llvm.usub.sat.i8(i8, i8)\n");2516  expectKnownBits(/*zero*/ 240u, /*one*/ 0u);2517}2518 2519TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) {2520  // usub.sat(........, 1111...1)2521  // = 0000....2522  parseAssembly(2523      "define i8 @test(i8 %a, i8 %b) {\n"2524      "  %bb = or i8 %a, 241\n"2525      "  %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n"2526      "  ret i8 %A\n"2527      "}\n"2528      "declare i8 @llvm.usub.sat.i8(i8, i8)\n");2529  expectKnownBits(/*zero*/ 240u, /*one*/ 0u);2530}2531 2532TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) {2533  // usub.sat(11...011, .1...110)2534  // = ......0.2535  parseAssembly(2536      "define i8 @test(i8 %a, i8 %b) {\n"2537      "  %aa = or i8 %a, 195\n"2538      "  %aaa = and i8 %aa, 251\n"2539      "  %bb = or i8 %b, 70\n"2540      "  %bbb = and i8 %bb, 254\n"2541      "  %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n"2542      "  ret i8 %A\n"2543      "}\n"2544      "declare i8 @llvm.usub.sat.i8(i8, i8)\n");2545  expectKnownBits(/*zero*/ 2u, /*one*/ 0u);2546}2547 2548TEST_F(ComputeKnownBitsTest, ComputeKnownBitsPtrToIntTrunc) {2549  // ptrtoint truncates the pointer type. Make sure we don't crash.2550  parseAssembly(2551      "define void @test(ptr %p) {\n"2552      "  %A = load ptr, ptr %p\n"2553      "  %i = ptrtoint ptr %A to i32\n"2554      "  %m = and i32 %i, 31\n"2555      "  %c = icmp eq i32 %m, 0\n"2556      "  call void @llvm.assume(i1 %c)\n"2557      "  ret void\n"2558      "}\n"2559      "declare void @llvm.assume(i1)\n");2560  AssumptionCache AC(*F);2561  KnownBits Known =2562      computeKnownBits(A, M->getDataLayout(), &AC, F->front().getTerminator());2563  EXPECT_TRUE(Known.isUnknown());2564}2565 2566TEST_F(ComputeKnownBitsTest, ComputeKnownBitsPtrToIntZext) {2567  // ptrtoint zero extends the pointer type. Make sure we don't crash.2568  parseAssembly(2569      "define void @test(ptr %p) {\n"2570      "  %A = load ptr, ptr %p\n"2571      "  %i = ptrtoint ptr %A to i128\n"2572      "  %m = and i128 %i, 31\n"2573      "  %c = icmp eq i128 %m, 0\n"2574      "  call void @llvm.assume(i1 %c)\n"2575      "  ret void\n"2576      "}\n"2577      "declare void @llvm.assume(i1)\n");2578  AssumptionCache AC(*F);2579  KnownBits Known =2580      computeKnownBits(A, M->getDataLayout(), &AC, F->front().getTerminator());2581  EXPECT_TRUE(Known.isUnknown());2582}2583 2584TEST_F(ComputeKnownBitsTest, ComputeKnownBitsFreeze) {2585  parseAssembly("define void @test() {\n"2586                "  %m = call i32 @any_num()\n"2587                "  %A = freeze i32 %m\n"2588                "  %n = and i32 %m, 31\n"2589                "  %c = icmp eq i32 %n, 0\n"2590                "  call void @llvm.assume(i1 %c)\n"2591                "  ret void\n"2592                "}\n"2593                "declare void @llvm.assume(i1)\n"2594                "declare i32 @any_num()\n");2595  AssumptionCache AC(*F);2596  KnownBits Known =2597      computeKnownBits(A, M->getDataLayout(), &AC, F->front().getTerminator());2598  EXPECT_EQ(Known.Zero.getZExtValue(), 31u);2599  EXPECT_EQ(Known.One.getZExtValue(), 0u);2600}2601 2602TEST_F(ComputeKnownBitsTest, ComputeKnownBitsReturnedRangeConflict) {2603  parseAssembly(2604      "declare i16 @foo(i16 returned)\n"2605      "\n"2606      "define i16 @test() {\n"2607      "  %A = call i16 @foo(i16 4095), !range !{i16 32, i16 33}\n"2608      "  ret i16 %A\n"2609      "}\n");2610  // The call returns 32 according to range metadata, but 4095 according to the2611  // returned arg operand. Given the conflicting information we expect that the2612  // known bits information simply is cleared.2613  expectKnownBits(/*zero*/ 0u, /*one*/ 0u);2614}2615 2616TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAddWithRange) {2617  parseAssembly("define void @test(ptr %p) {\n"2618                "  %A = load i64, ptr %p, !range !{i64 64, i64 65536}\n"2619                "  %APlus512 = add i64 %A, 512\n"2620                "  %c = icmp ugt i64 %APlus512, 523\n"2621                "  call void @llvm.assume(i1 %c)\n"2622                "  ret void\n"2623                "}\n"2624                "declare void @llvm.assume(i1)\n");2625  AssumptionCache AC(*F);2626  KnownBits Known =2627      computeKnownBits(A, M->getDataLayout(), &AC, F->front().getTerminator());2628  EXPECT_EQ(Known.Zero.getZExtValue(), ~(65536llu - 1));2629  EXPECT_EQ(Known.One.getZExtValue(), 0u);2630  Instruction &APlus512 = findInstructionByName(F, "APlus512");2631  Known = computeKnownBits(&APlus512, M->getDataLayout(), &AC,2632                           F->front().getTerminator());2633  // We know of one less zero because 512 may have produced a 1 that2634  // got carried all the way to the first trailing zero.2635  EXPECT_EQ(Known.Zero.getZExtValue(), (~(65536llu - 1)) << 1);2636  EXPECT_EQ(Known.One.getZExtValue(), 0u);2637  // The known range is not precise given computeKnownBits works2638  // with the masks of zeros and ones, not the ranges.2639  EXPECT_EQ(Known.getMinValue(), 0u);2640  EXPECT_EQ(Known.getMaxValue(), 131071);2641}2642 2643TEST_F(ComputeKnownBitsTest, ComputeKnownBitsUnknownVScale) {2644  Module M("", Context);2645  IRBuilder<> Builder(Context);2646  Function *TheFn = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::vscale,2647                                                      {Builder.getInt32Ty()});2648  CallInst *CI = Builder.CreateCall(TheFn, {}, {}, "");2649 2650  KnownBits Known = computeKnownBits(CI, M.getDataLayout());2651  // There is no parent function so we cannot look up the vscale_range2652  // attribute to determine the number of bits.2653  EXPECT_EQ(Known.One.getZExtValue(), 0u);2654  EXPECT_EQ(Known.Zero.getZExtValue(), 0u);2655 2656  BasicBlock *BB = BasicBlock::Create(Context);2657  CI->insertInto(BB, BB->end());2658  Known = computeKnownBits(CI, M.getDataLayout());2659  // There is no parent function so we cannot look up the vscale_range2660  // attribute to determine the number of bits.2661  EXPECT_EQ(Known.One.getZExtValue(), 0u);2662  EXPECT_EQ(Known.Zero.getZExtValue(), 0u);2663 2664  CI->removeFromParent();2665  delete CI;2666  delete BB;2667}2668 2669// 512 + [32, 64) doesn't produce overlapping bits.2670// Make sure we get all the individual bits properly.2671TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAddWithRangeNoOverlap) {2672  parseAssembly("define void @test(ptr %p) {\n"2673                "  %A = load i64, ptr %p, !range !{i64 32, i64 64}\n"2674                "  %APlus512 = add i64 %A, 512\n"2675                "  %c = icmp ugt i64 %APlus512, 523\n"2676                "  call void @llvm.assume(i1 %c)\n"2677                "  ret void\n"2678                "}\n"2679                "declare void @llvm.assume(i1)\n");2680  AssumptionCache AC(*F);2681  KnownBits Known =2682      computeKnownBits(A, M->getDataLayout(), &AC, F->front().getTerminator());2683  EXPECT_EQ(Known.Zero.getZExtValue(), ~(64llu - 1));2684  EXPECT_EQ(Known.One.getZExtValue(), 32u);2685  Instruction &APlus512 = findInstructionByName(F, "APlus512");2686  Known = computeKnownBits(&APlus512, M->getDataLayout(), &AC,2687                           F->front().getTerminator());2688  EXPECT_EQ(Known.Zero.getZExtValue(), ~512llu & ~(64llu - 1));2689  EXPECT_EQ(Known.One.getZExtValue(), 512u | 32u);2690  // The known range is not precise given computeKnownBits works2691  // with the masks of zeros and ones, not the ranges.2692  EXPECT_EQ(Known.getMinValue(), 544);2693  EXPECT_EQ(Known.getMaxValue(), 575);2694}2695 2696TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPWithRange) {2697  parseAssembly(2698      "define void @test(ptr %p) {\n"2699      "  %A = load i64, ptr %p, !range !{i64 64, i64 65536}\n"2700      "  %APtr = inttoptr i64 %A to ptr"2701      "  %APtrPlus512 = getelementptr float, ptr %APtr, i32 128\n"2702      "  %c = icmp ugt ptr %APtrPlus512, inttoptr (i32 523 to ptr)\n"2703      "  call void @llvm.assume(i1 %c)\n"2704      "  ret void\n"2705      "}\n"2706      "declare void @llvm.assume(i1)\n");2707  AssumptionCache AC(*F);2708  KnownBits Known =2709      computeKnownBits(A, M->getDataLayout(), &AC, F->front().getTerminator());2710  EXPECT_EQ(Known.Zero.getZExtValue(), ~(65536llu - 1));2711  EXPECT_EQ(Known.One.getZExtValue(), 0u);2712  Instruction &APtrPlus512 = findInstructionByName(F, "APtrPlus512");2713  Known = computeKnownBits(&APtrPlus512, M->getDataLayout(), &AC,2714                           F->front().getTerminator());2715  // We know of one less zero because 512 may have produced a 1 that2716  // got carried all the way to the first trailing zero.2717  EXPECT_EQ(Known.Zero.getZExtValue(), ~(65536llu - 1) << 1);2718  EXPECT_EQ(Known.One.getZExtValue(), 0u);2719  // The known range is not precise given computeKnownBits works2720  // with the masks of zeros and ones, not the ranges.2721  EXPECT_EQ(Known.getMinValue(), 0u);2722  EXPECT_EQ(Known.getMaxValue(), 131071);2723}2724 2725// 4*128 + [32, 64) doesn't produce overlapping bits.2726// Make sure we get all the individual bits properly.2727// This test is useful to check that we account for the scaling factor2728// in the gep. Indeed, gep float, [32,64), 128 is not 128 + [32,64).2729TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPWithRangeNoOverlap) {2730  parseAssembly(2731      "define void @test(ptr %p) {\n"2732      "  %A = load i64, ptr %p, !range !{i64 32, i64 64}\n"2733      "  %APtr = inttoptr i64 %A to ptr"2734      "  %APtrPlus512 = getelementptr float, ptr %APtr, i32 128\n"2735      "  %c = icmp ugt ptr %APtrPlus512, inttoptr (i32 523 to ptr)\n"2736      "  call void @llvm.assume(i1 %c)\n"2737      "  ret void\n"2738      "}\n"2739      "declare void @llvm.assume(i1)\n");2740  AssumptionCache AC(*F);2741  KnownBits Known =2742      computeKnownBits(A, M->getDataLayout(), &AC, F->front().getTerminator());2743  EXPECT_EQ(Known.Zero.getZExtValue(), ~(64llu - 1));2744  EXPECT_EQ(Known.One.getZExtValue(), 32u);2745  Instruction &APtrPlus512 = findInstructionByName(F, "APtrPlus512");2746  Known = computeKnownBits(&APtrPlus512, M->getDataLayout(), &AC,2747                           F->front().getTerminator());2748  EXPECT_EQ(Known.Zero.getZExtValue(), ~512llu & ~(64llu - 1));2749  EXPECT_EQ(Known.One.getZExtValue(), 512u | 32u);2750  // The known range is not precise given computeKnownBits works2751  // with the masks of zeros and ones, not the ranges.2752  EXPECT_EQ(Known.getMinValue(), 544);2753  EXPECT_EQ(Known.getMaxValue(), 575);2754}2755 2756TEST_F(ComputeKnownBitsTest, ComputeKnownBitsAbsoluteSymbol) {2757  auto M = parseModule(R"(2758    @absolute_0_255 = external global [128 x i32], align 1, !absolute_symbol !02759    @absolute_0_256 = external global [128 x i32], align 1, !absolute_symbol !12760    @absolute_256_512 = external global [128 x i32], align 1, !absolute_symbol !22761    @absolute_0_neg1 = external global [128 x i32], align 1, !absolute_symbol !32762    @absolute_neg32_32 = external global [128 x i32], align 1, !absolute_symbol !42763    @absolute_neg32_33 = external global [128 x i32], align 1, !absolute_symbol !52764    @absolute_neg64_neg32 = external global [128 x i32], align 1, !absolute_symbol !62765    @absolute_0_256_align8 = external global [128 x i32], align 8, !absolute_symbol !12766 2767    !0 = !{i64 0, i64 255}2768    !1 = !{i64 0, i64 256}2769    !2 = !{i64 256, i64 512}2770    !3 = !{i64 0, i64 -1}2771    !4 = !{i64 -32, i64 32}2772    !5 = !{i64 -32, i64 33}2773    !6 = !{i64 -64, i64 -32}2774  )");2775 2776  GlobalValue *Absolute_0_255 = M->getNamedValue("absolute_0_255");2777  GlobalValue *Absolute_0_256 = M->getNamedValue("absolute_0_256");2778  GlobalValue *Absolute_256_512 = M->getNamedValue("absolute_256_512");2779  GlobalValue *Absolute_0_Neg1 = M->getNamedValue("absolute_0_neg1");2780  GlobalValue *Absolute_Neg32_32 = M->getNamedValue("absolute_neg32_32");2781  GlobalValue *Absolute_Neg32_33 = M->getNamedValue("absolute_neg32_33");2782  GlobalValue *Absolute_Neg64_Neg32 = M->getNamedValue("absolute_neg64_neg32");2783  GlobalValue *Absolute_0_256_Align8 =2784      M->getNamedValue("absolute_0_256_align8");2785 2786  KnownBits Known_0_255 = computeKnownBits(Absolute_0_255, M->getDataLayout());2787  EXPECT_EQ(64u - 8u, Known_0_255.countMinLeadingZeros());2788  EXPECT_EQ(0u, Known_0_255.countMinTrailingZeros());2789  EXPECT_EQ(0u, Known_0_255.countMinLeadingOnes());2790  EXPECT_EQ(0u, Known_0_255.countMinTrailingOnes());2791 2792  KnownBits Known_0_256 = computeKnownBits(Absolute_0_256, M->getDataLayout());2793  EXPECT_EQ(64u - 8u, Known_0_256.countMinLeadingZeros());2794  EXPECT_EQ(0u, Known_0_256.countMinTrailingZeros());2795  EXPECT_EQ(0u, Known_0_256.countMinLeadingOnes());2796  EXPECT_EQ(0u, Known_0_256.countMinTrailingOnes());2797 2798  KnownBits Known_256_512 =2799      computeKnownBits(Absolute_256_512, M->getDataLayout());2800  EXPECT_EQ(64u - 8u, Known_0_255.countMinLeadingZeros());2801  EXPECT_EQ(0u, Known_0_255.countMinTrailingZeros());2802  EXPECT_EQ(0u, Known_0_255.countMinLeadingOnes());2803  EXPECT_EQ(0u, Known_0_255.countMinTrailingOnes());2804 2805  KnownBits Known_0_Neg1 =2806      computeKnownBits(Absolute_0_Neg1, M->getDataLayout());2807  EXPECT_EQ(0u, Known_0_Neg1.countMinLeadingZeros());2808  EXPECT_EQ(0u, Known_0_Neg1.countMinTrailingZeros());2809  EXPECT_EQ(0u, Known_0_Neg1.countMinLeadingOnes());2810  EXPECT_EQ(0u, Known_0_Neg1.countMinTrailingOnes());2811 2812  KnownBits Known_Neg32_32 =2813      computeKnownBits(Absolute_Neg32_32, M->getDataLayout());2814  EXPECT_EQ(0u, Known_Neg32_32.countMinLeadingZeros());2815  EXPECT_EQ(0u, Known_Neg32_32.countMinTrailingZeros());2816  EXPECT_EQ(0u, Known_Neg32_32.countMinLeadingOnes());2817  EXPECT_EQ(0u, Known_Neg32_32.countMinTrailingOnes());2818  EXPECT_EQ(1u, Known_Neg32_32.countMinSignBits());2819 2820  KnownBits Known_Neg32_33 =2821      computeKnownBits(Absolute_Neg32_33, M->getDataLayout());2822  EXPECT_EQ(0u, Known_Neg32_33.countMinLeadingZeros());2823  EXPECT_EQ(0u, Known_Neg32_33.countMinTrailingZeros());2824  EXPECT_EQ(0u, Known_Neg32_33.countMinLeadingOnes());2825  EXPECT_EQ(0u, Known_Neg32_33.countMinTrailingOnes());2826  EXPECT_EQ(1u, Known_Neg32_33.countMinSignBits());2827 2828  KnownBits Known_Neg32_Neg32 =2829      computeKnownBits(Absolute_Neg64_Neg32, M->getDataLayout());2830  EXPECT_EQ(0u, Known_Neg32_Neg32.countMinLeadingZeros());2831  EXPECT_EQ(0u, Known_Neg32_Neg32.countMinTrailingZeros());2832  EXPECT_EQ(58u, Known_Neg32_Neg32.countMinLeadingOnes());2833  EXPECT_EQ(0u, Known_Neg32_Neg32.countMinTrailingOnes());2834  EXPECT_EQ(58u, Known_Neg32_Neg32.countMinSignBits());2835 2836  KnownBits Known_0_256_Align8 =2837      computeKnownBits(Absolute_0_256_Align8, M->getDataLayout());2838  EXPECT_EQ(64u - 8u, Known_0_256_Align8.countMinLeadingZeros());2839  EXPECT_EQ(3u, Known_0_256_Align8.countMinTrailingZeros());2840  EXPECT_EQ(0u, Known_0_256_Align8.countMinLeadingOnes());2841  EXPECT_EQ(0u, Known_0_256_Align8.countMinTrailingOnes());2842}2843 2844TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPExtendBeforeMul) {2845  // The index should be extended before multiplying with the scale.2846  parseAssembly(R"(2847    target datalayout = "p:16:16:16"2848 2849    define void @test(i16 %arg) {2850      %and = and i16 %arg, u0x80002851      %base = inttoptr i16 %and to ptr2852      %A = getelementptr i32, ptr %base, i8 802853      ret void2854    }2855    )");2856  KnownBits Known = computeKnownBits(A, M->getDataLayout());2857  EXPECT_EQ(~320 & 0x7fff, Known.Zero);2858  EXPECT_EQ(320, Known.One);2859}2860 2861TEST_F(ComputeKnownBitsTest, ComputeKnownBitsGEPOnlyIndexBits) {2862  // GEP should only affect the index width.2863  parseAssembly(R"(2864    target datalayout = "p:16:16:16:8"2865 2866    define void @test(i16 %arg) {2867      %and = and i16 %arg, u0x80002868      %or = or i16 %and, u0x00ff2869      %base = inttoptr i16 %or to ptr2870      %A = getelementptr i8, ptr %base, i8 12871      ret void2872    }2873    )");2874  KnownBits Known = computeKnownBits(A, M->getDataLayout());2875  EXPECT_EQ(0x7fff, Known.Zero);2876  EXPECT_EQ(0, Known.One);2877}2878 2879TEST_F(ValueTrackingTest, HaveNoCommonBitsSet) {2880  {2881    // Check for an inverted mask: (X & ~M) op (Y & M).2882    auto M = parseModule(R"(2883  define i32 @test(i32 %X, i32 %Y, i32 noundef %M) {2884    %1 = xor i32 %M, -12885    %LHS = and i32 %1, %X2886    %RHS = and i32 %Y, %M2887    %Ret = add i32 %LHS, %RHS2888    ret i32 %Ret2889  })");2890 2891    auto *F = M->getFunction("test");2892    auto *LHS = findInstructionByNameOrNull(F, "LHS");2893    auto *RHS = findInstructionByNameOrNull(F, "RHS");2894 2895    const DataLayout &DL = M->getDataLayout();2896    EXPECT_TRUE(haveNoCommonBitsSet(LHS, RHS, DL));2897    EXPECT_TRUE(haveNoCommonBitsSet(RHS, LHS, DL));2898  }2899  {2900    // Check for (A & B) and ~(A | B)2901    auto M = parseModule(R"(2902  define void @test(i32 noundef %A, i32 noundef %B) {2903    %LHS = and i32 %A, %B2904    %or = or i32 %A, %B2905    %RHS = xor i32 %or, -12906 2907    %LHS2 = and i32 %B, %A2908    %or2 = or i32 %A, %B2909    %RHS2 = xor i32 %or2, -12910 2911    ret void2912  })");2913 2914    auto *F = M->getFunction("test");2915    const DataLayout &DL = M->getDataLayout();2916 2917    auto *LHS = findInstructionByNameOrNull(F, "LHS");2918    auto *RHS = findInstructionByNameOrNull(F, "RHS");2919    EXPECT_TRUE(haveNoCommonBitsSet(LHS, RHS, DL));2920    EXPECT_TRUE(haveNoCommonBitsSet(RHS, LHS, DL));2921 2922    auto *LHS2 = findInstructionByNameOrNull(F, "LHS2");2923    auto *RHS2 = findInstructionByNameOrNull(F, "RHS2");2924    EXPECT_TRUE(haveNoCommonBitsSet(LHS2, RHS2, DL));2925    EXPECT_TRUE(haveNoCommonBitsSet(RHS2, LHS2, DL));2926  }2927  {2928    // Check for (A & B) and ~(A | B) in vector version2929    auto M = parseModule(R"(2930  define void @test(<2 x i32> noundef %A, <2 x i32> noundef %B) {2931    %LHS = and <2 x i32> %A, %B2932    %or = or <2 x i32> %A, %B2933    %RHS = xor <2 x i32> %or, <i32 -1, i32 -1>2934 2935    %LHS2 = and <2 x i32> %B, %A2936    %or2 = or <2 x i32> %A, %B2937    %RHS2 = xor <2 x i32> %or2, <i32 -1, i32 -1>2938 2939    ret void2940  })");2941 2942    auto *F = M->getFunction("test");2943    const DataLayout &DL = M->getDataLayout();2944 2945    auto *LHS = findInstructionByNameOrNull(F, "LHS");2946    auto *RHS = findInstructionByNameOrNull(F, "RHS");2947    EXPECT_TRUE(haveNoCommonBitsSet(LHS, RHS, DL));2948    EXPECT_TRUE(haveNoCommonBitsSet(RHS, LHS, DL));2949 2950    auto *LHS2 = findInstructionByNameOrNull(F, "LHS2");2951    auto *RHS2 = findInstructionByNameOrNull(F, "RHS2");2952    EXPECT_TRUE(haveNoCommonBitsSet(LHS2, RHS2, DL));2953    EXPECT_TRUE(haveNoCommonBitsSet(RHS2, LHS2, DL));2954  }2955}2956 2957class IsBytewiseValueTest : public ValueTrackingTest,2958                            public ::testing::WithParamInterface<2959                                std::pair<const char *, const char *>> {2960protected:2961};2962 2963const std::pair<const char *, const char *> IsBytewiseValueTests[] = {2964    {2965        "i8 0",2966        "ptr null",2967    },2968    {2969        "i8 undef",2970        "ptr undef",2971    },2972    {2973        "i8 0",2974        "i8 zeroinitializer",2975    },2976    {2977        "i8 0",2978        "i8 0",2979    },2980    {2981        "i8 -86",2982        "i8 -86",2983    },2984    {2985        "i8 -1",2986        "i8 -1",2987    },2988    {2989        "i8 undef",2990        "i16 undef",2991    },2992    {2993        "i8 0",2994        "i16 0",2995    },2996    {2997        "",2998        "i16 7",2999    },3000    {3001        "i8 -86",3002        "i16 -21846",3003    },3004    {3005        "i8 -1",3006        "i16 -1",3007    },3008    {3009        "i8 0",3010        "i48 0",3011    },3012    {3013        "i8 -1",3014        "i48 -1",3015    },3016    {3017        "i8 0",3018        "i49 0",3019    },3020    {3021        "",3022        "i49 -1",3023    },3024    {3025        "i8 0",3026        "half 0xH0000",3027    },3028    {3029        "i8 -85",3030        "half 0xHABAB",3031    },3032    {3033        "i8 0",3034        "float 0.0",3035    },3036    {3037        "i8 -1",3038        "float 0xFFFFFFFFE0000000",3039    },3040    {3041        "i8 0",3042        "double 0.0",3043    },3044    {3045        "i8 -15",3046        "double 0xF1F1F1F1F1F1F1F1",3047    },3048    {3049        "i8 0",3050        "ptr inttoptr (i64 0 to ptr)",3051    },3052    {3053        "i8 -1",3054        "ptr inttoptr (i64 -1 to ptr)",3055    },3056    {3057        "i8 -86",3058        "ptr inttoptr (i64 -6148914691236517206 to ptr)",3059    },3060    {3061        "",3062        "ptr inttoptr (i48 -1 to ptr)",3063    },3064    {3065        "i8 -1",3066        "ptr inttoptr (i96 -1 to ptr)",3067    },3068    {3069        "i8 poison",3070        "[0 x i8] zeroinitializer",3071    },3072    {3073        "i8 undef",3074        "[0 x i8] undef",3075    },3076    {3077        "i8 poison",3078        "[5 x [0 x i8]] zeroinitializer",3079    },3080    {3081        "i8 undef",3082        "[5 x [0 x i8]] undef",3083    },3084    {3085        "i8 0",3086        "[6 x i8] zeroinitializer",3087    },3088    {3089        "i8 undef",3090        "[6 x i8] undef",3091    },3092    {3093        "i8 1",3094        "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]",3095    },3096    {3097        "",3098        "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]",3099    },3100    {3101        "i8 -1",3102        "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]",3103    },3104    {3105        "",3106        "[4 x i8] [i8 1, i8 2, i8 1, i8 1]",3107    },3108    {3109        "i8 1",3110        "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]",3111    },3112    {3113        "i8 0",3114        "<6 x i8> zeroinitializer",3115    },3116    {3117        "i8 undef",3118        "<6 x i8> undef",3119    },3120    {3121        "i8 1",3122        "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>",3123    },3124    {3125        "",3126        "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>",3127    },3128    {3129        "i8 -1",3130        "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>",3131    },3132    {3133        "",3134        "<4 x i8> <i8 1, i8 1, i8 2, i8 1>",3135    },3136    {3137        "i8 5",3138        "<2 x i8> < i8 5, i8 undef >",3139    },3140    {3141        "i8 0",3142        "[2 x [2 x i16]] zeroinitializer",3143    },3144    {3145        "i8 undef",3146        "[2 x [2 x i16]] undef",3147    },3148    {3149        "i8 -86",3150        "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], "3151        "[2 x i16] [i16 -21846, i16 -21846]]",3152    },3153    {3154        "",3155        "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], "3156        "[2 x i16] [i16 -21836, i16 -21846]]",3157    },3158    {3159        "i8 poison",3160        "{ } zeroinitializer",3161    },3162    {3163        "i8 undef",3164        "{ } undef",3165    },3166    {3167        "i8 poison",3168        "{ {}, {} } zeroinitializer",3169    },3170    {3171        "i8 undef",3172        "{ {}, {} } undef",3173    },3174    {3175        "i8 0",3176        "{i8, i64, ptr} zeroinitializer",3177    },3178    {3179        "i8 undef",3180        "{i8, i64, ptr} undef",3181    },3182    {3183        "i8 -86",3184        "{i8, i64, ptr} {i8 -86, i64 -6148914691236517206, ptr undef}",3185    },3186    {3187        "",3188        "{i8, i64, ptr} {i8 86, i64 -6148914691236517206, ptr undef}",3189    },3190};3191 3192INSTANTIATE_TEST_SUITE_P(IsBytewiseValueParamTests, IsBytewiseValueTest,3193                         ::testing::ValuesIn(IsBytewiseValueTests));3194 3195TEST_P(IsBytewiseValueTest, IsBytewiseValue) {3196  auto M = parseModule(std::string("@test = global ") + GetParam().second);3197  GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test"));3198  Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout());3199  std::string Buff;3200  raw_string_ostream S(Buff);3201  if (Actual)3202    S << *Actual;3203  EXPECT_EQ(GetParam().first, Buff);3204}3205 3206TEST_F(ValueTrackingTest, ComputeConstantRange) {3207  {3208    // Assumptions:3209    //  * stride >= 53210    //  * stride < 103211    //3212    // stride = [5, 10)3213    auto M = parseModule(R"(3214  declare void @llvm.assume(i1)3215 3216  define i32 @test(i32 %stride) {3217    %gt = icmp uge i32 %stride, 53218    call void @llvm.assume(i1 %gt)3219    %lt = icmp ult i32 %stride, 103220    call void @llvm.assume(i1 %lt)3221    %stride.plus.one = add nsw nuw i32 %stride, 13222    ret i32 %stride.plus.one3223  })");3224    Function *F = M->getFunction("test");3225 3226    AssumptionCache AC(*F);3227    Value *Stride = &*F->arg_begin();3228    ConstantRange CR1 = computeConstantRange(Stride, false, true, &AC, nullptr);3229    EXPECT_TRUE(CR1.isFullSet());3230 3231    Instruction *I = &findInstructionByName(F, "stride.plus.one");3232    ConstantRange CR2 = computeConstantRange(Stride, false, true, &AC, I);3233    EXPECT_EQ(5, CR2.getLower());3234    EXPECT_EQ(10, CR2.getUpper());3235  }3236 3237  {3238    // Assumptions:3239    //  * stride >= 53240    //  * stride < 2003241    //  * stride == 993242    //3243    // stride = [99, 100)3244    auto M = parseModule(R"(3245  declare void @llvm.assume(i1)3246 3247  define i32 @test(i32 %stride) {3248    %gt = icmp uge i32 %stride, 53249    call void @llvm.assume(i1 %gt)3250    %lt = icmp ult i32 %stride, 2003251    call void @llvm.assume(i1 %lt)3252    %eq = icmp eq i32 %stride, 993253    call void @llvm.assume(i1 %eq)3254    %stride.plus.one = add nsw nuw i32 %stride, 13255    ret i32 %stride.plus.one3256  })");3257    Function *F = M->getFunction("test");3258 3259    AssumptionCache AC(*F);3260    Value *Stride = &*F->arg_begin();3261    Instruction *I = &findInstructionByName(F, "stride.plus.one");3262    ConstantRange CR = computeConstantRange(Stride, false, true, &AC, I);3263    EXPECT_EQ(99, *CR.getSingleElement());3264  }3265 3266  {3267    // Assumptions:3268    //  * stride >= 53269    //  * stride >= 503270    //  * stride < 1003271    //  * stride < 2003272    //3273    // stride = [50, 100)3274    auto M = parseModule(R"(3275  declare void @llvm.assume(i1)3276 3277  define i32 @test(i32 %stride, i1 %cond) {3278    %gt = icmp uge i32 %stride, 53279    call void @llvm.assume(i1 %gt)3280    %gt.2 = icmp uge i32 %stride, 503281    call void @llvm.assume(i1 %gt.2)3282    br i1 %cond, label %bb1, label %bb23283 3284  bb1:3285    %lt = icmp ult i32 %stride, 2003286    call void @llvm.assume(i1 %lt)3287    %lt.2 = icmp ult i32 %stride, 1003288    call void @llvm.assume(i1 %lt.2)3289    %stride.plus.one = add nsw nuw i32 %stride, 13290    ret i32 %stride.plus.one3291 3292  bb2:3293    ret i32 03294  })");3295    Function *F = M->getFunction("test");3296 3297    AssumptionCache AC(*F);3298    Value *Stride = &*F->arg_begin();3299    Instruction *GT2 = &findInstructionByName(F, "gt.2");3300    ConstantRange CR = computeConstantRange(Stride, false, true, &AC, GT2);3301    EXPECT_EQ(5, CR.getLower());3302    EXPECT_EQ(0, CR.getUpper());3303 3304    Instruction *I = &findInstructionByName(F, "stride.plus.one");3305    ConstantRange CR2 = computeConstantRange(Stride, false, true, &AC, I);3306    EXPECT_EQ(50, CR2.getLower());3307    EXPECT_EQ(100, CR2.getUpper());3308  }3309 3310  {3311    // Assumptions:3312    //  * stride > 53313    //  * stride < 53314    //3315    // stride = empty range, as the assumptions contradict each other.3316    auto M = parseModule(R"(3317  declare void @llvm.assume(i1)3318 3319  define i32 @test(i32 %stride, i1 %cond) {3320    %gt = icmp ugt i32 %stride, 53321    call void @llvm.assume(i1 %gt)3322    %lt = icmp ult i32 %stride, 53323    call void @llvm.assume(i1 %lt)3324    %stride.plus.one = add nsw nuw i32 %stride, 13325    ret i32 %stride.plus.one3326  })");3327    Function *F = M->getFunction("test");3328 3329    AssumptionCache AC(*F);3330    Value *Stride = &*F->arg_begin();3331 3332    Instruction *I = &findInstructionByName(F, "stride.plus.one");3333    ConstantRange CR = computeConstantRange(Stride, false, true, &AC, I);3334    EXPECT_TRUE(CR.isEmptySet());3335  }3336 3337  {3338    // Assumptions:3339    //  * x.1 >= 53340    //  * x.2 < x.13341    //3342    // stride = [0, -1)3343    auto M = parseModule(R"(3344  declare void @llvm.assume(i1)3345 3346  define i32 @test(i32 %x.1, i32 %x.2) {3347    %gt = icmp uge i32 %x.1, 53348    call void @llvm.assume(i1 %gt)3349    %lt = icmp ult i32 %x.2, %x.13350    call void @llvm.assume(i1 %lt)3351    %stride.plus.one = add nsw nuw i32 %x.1, 13352    ret i32 %stride.plus.one3353  })");3354    Function *F = M->getFunction("test");3355 3356    AssumptionCache AC(*F);3357    Value *X1 = &*(F->arg_begin());3358    Value *X2 = &*std::next(F->arg_begin());3359 3360    Instruction *I = &findInstructionByName(F, "stride.plus.one");3361    ConstantRange CR1 = computeConstantRange(X1, false, true, &AC, I);3362    ConstantRange CR2 = computeConstantRange(X2, false, true, &AC, I);3363 3364    EXPECT_EQ(5, CR1.getLower());3365    EXPECT_EQ(0, CR1.getUpper());3366 3367    EXPECT_EQ(0, CR2.getLower());3368    EXPECT_EQ(0xffffffff, CR2.getUpper());3369 3370    // Check the depth cutoff results in a conservative result (full set) by3371    // passing Depth == MaxDepth == 6.3372    ConstantRange CR3 = computeConstantRange(X2, false, true, &AC, I, nullptr, 6);3373    EXPECT_TRUE(CR3.isFullSet());3374  }3375  {3376    // Assumptions:3377    //  * x.2 <= x.13378    auto M = parseModule(R"(3379  declare void @llvm.assume(i1)3380 3381  define i32 @test(i32 %x.1, i32 %x.2) {3382    %lt = icmp ule i32 %x.2, %x.13383    call void @llvm.assume(i1 %lt)3384    %stride.plus.one = add nsw nuw i32 %x.1, 13385    ret i32 %stride.plus.one3386  })");3387    Function *F = M->getFunction("test");3388 3389    AssumptionCache AC(*F);3390    Value *X2 = &*std::next(F->arg_begin());3391 3392    Instruction *I = &findInstructionByName(F, "stride.plus.one");3393    ConstantRange CR1 = computeConstantRange(X2, false, true, &AC, I);3394    // If we don't know the value of x.2, we don't know the value of x.1.3395    EXPECT_TRUE(CR1.isFullSet());3396  }3397}3398 3399struct FindAllocaForValueTestParams {3400  const char *IR;3401  bool AnyOffsetResult;3402  bool ZeroOffsetResult;3403};3404 3405class FindAllocaForValueTest3406    : public ValueTrackingTest,3407      public ::testing::WithParamInterface<FindAllocaForValueTestParams> {3408protected:3409};3410 3411const FindAllocaForValueTestParams FindAllocaForValueTests[] = {3412    {R"(3413      define void @test() {3414        %a = alloca i643415        %r = bitcast ptr %a to ptr3416        ret void3417      })",3418     true, true},3419 3420    {R"(3421      define void @test() {3422        %a = alloca i323423        %r = getelementptr i32, ptr %a, i32 13424        ret void3425      })",3426     true, false},3427 3428    {R"(3429      define void @test() {3430        %a = alloca i323431        %r = getelementptr i32, ptr %a, i32 03432        ret void3433      })",3434     true, true},3435 3436    {R"(3437      define void @test(i1 %cond) {3438      entry:3439        %a = alloca i323440        br label %bb13441 3442      bb1:3443        %r = phi ptr [ %a, %entry ], [ %r, %bb1 ]3444        br i1 %cond, label %bb1, label %exit3445 3446      exit:3447        ret void3448      })",3449     true, true},3450 3451    {R"(3452      define void @test(i1 %cond) {3453        %a = alloca i323454        %r = select i1 %cond, ptr %a, ptr %a3455        ret void3456      })",3457     true, true},3458 3459    {R"(3460      define void @test(i1 %cond) {3461        %a = alloca i323462        %b = alloca i323463        %r = select i1 %cond, ptr %a, ptr %b3464        ret void3465      })",3466     false, false},3467 3468    {R"(3469      define void @test(i1 %cond) {3470      entry:3471        %a = alloca i643472        %a32 = bitcast ptr %a to ptr3473        br label %bb13474 3475      bb1:3476        %x = phi ptr [ %a32, %entry ], [ %x, %bb1 ]3477        %r = getelementptr i32, ptr %x, i32 13478        br i1 %cond, label %bb1, label %exit3479 3480      exit:3481        ret void3482      })",3483     true, false},3484 3485    {R"(3486      define void @test(i1 %cond) {3487      entry:3488        %a = alloca i643489        %a32 = bitcast ptr %a to ptr3490        br label %bb13491 3492      bb1:3493        %x = phi ptr [ %a32, %entry ], [ %r, %bb1 ]3494        %r = getelementptr i32, ptr %x, i32 13495        br i1 %cond, label %bb1, label %exit3496 3497      exit:3498        ret void3499      })",3500     true, false},3501 3502    {R"(3503      define void @test(i1 %cond, ptr %a) {3504      entry:3505        %r = bitcast ptr %a to ptr3506        ret void3507      })",3508     false, false},3509 3510    {R"(3511      define void @test(i1 %cond) {3512      entry:3513        %a = alloca i323514        %b = alloca i323515        br label %bb13516 3517      bb1:3518        %r = phi ptr [ %a, %entry ], [ %b, %bb1 ]3519        br i1 %cond, label %bb1, label %exit3520 3521      exit:3522        ret void3523      })",3524     false, false},3525    {R"(3526      declare ptr @retptr(ptr returned)3527      define void @test(i1 %cond) {3528        %a = alloca i323529        %r = call ptr @retptr(ptr %a)3530        ret void3531      })",3532     true, true},3533    {R"(3534      declare ptr @fun(ptr)3535      define void @test(i1 %cond) {3536        %a = alloca i323537        %r = call ptr @fun(ptr %a)3538        ret void3539      })",3540     false, false},3541};3542 3543TEST_P(FindAllocaForValueTest, findAllocaForValue) {3544  auto M = parseModule(GetParam().IR);3545  Function *F = M->getFunction("test");3546  Instruction *I = &findInstructionByName(F, "r");3547  const AllocaInst *AI = findAllocaForValue(I);3548  EXPECT_EQ(!!AI, GetParam().AnyOffsetResult);3549}3550 3551TEST_P(FindAllocaForValueTest, findAllocaForValueZeroOffset) {3552  auto M = parseModule(GetParam().IR);3553  Function *F = M->getFunction("test");3554  Instruction *I = &findInstructionByName(F, "r");3555  const AllocaInst *AI = findAllocaForValue(I, true);3556  EXPECT_EQ(!!AI, GetParam().ZeroOffsetResult);3557}3558 3559INSTANTIATE_TEST_SUITE_P(FindAllocaForValueTest, FindAllocaForValueTest,3560                         ::testing::ValuesIn(FindAllocaForValueTests));3561