Home | History | Annotate | Download | only in Analysis
      1 //===- ValueTrackingTest.cpp - ValueTracking tests ------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/Analysis/ValueTracking.h"
     11 #include "llvm/AsmParser/Parser.h"
     12 #include "llvm/IR/Function.h"
     13 #include "llvm/IR/InstIterator.h"
     14 #include "llvm/IR/LLVMContext.h"
     15 #include "llvm/IR/Module.h"
     16 #include "llvm/Support/ErrorHandling.h"
     17 #include "llvm/Support/SourceMgr.h"
     18 #include "llvm/Support/KnownBits.h"
     19 #include "gtest/gtest.h"
     20 
     21 using namespace llvm;
     22 
     23 namespace {
     24 
     25 class MatchSelectPatternTest : public testing::Test {
     26 protected:
     27   void parseAssembly(const char *Assembly) {
     28     SMDiagnostic Error;
     29     M = parseAssemblyString(Assembly, Error, Context);
     30 
     31     std::string errMsg;
     32     raw_string_ostream os(errMsg);
     33     Error.print("", os);
     34 
     35     // A failure here means that the test itself is buggy.
     36     if (!M)
     37       report_fatal_error(os.str());
     38 
     39     Function *F = M->getFunction("test");
     40     if (F == nullptr)
     41       report_fatal_error("Test must have a function named @test");
     42 
     43     A = nullptr;
     44     for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
     45       if (I->hasName()) {
     46         if (I->getName() == "A")
     47           A = &*I;
     48       }
     49     }
     50     if (A == nullptr)
     51       report_fatal_error("@test must have an instruction %A");
     52   }
     53 
     54   void expectPattern(const SelectPatternResult &P) {
     55     Value *LHS, *RHS;
     56     Instruction::CastOps CastOp;
     57     SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp);
     58     EXPECT_EQ(P.Flavor, R.Flavor);
     59     EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);
     60     EXPECT_EQ(P.Ordered, R.Ordered);
     61   }
     62 
     63   LLVMContext Context;
     64   std::unique_ptr<Module> M;
     65   Instruction *A, *B;
     66 };
     67 
     68 }
     69 
     70 TEST_F(MatchSelectPatternTest, SimpleFMin) {
     71   parseAssembly(
     72       "define float @test(float %a) {\n"
     73       "  %1 = fcmp ult float %a, 5.0\n"
     74       "  %A = select i1 %1, float %a, float 5.0\n"
     75       "  ret float %A\n"
     76       "}\n");
     77   expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
     78 }
     79 
     80 TEST_F(MatchSelectPatternTest, SimpleFMax) {
     81   parseAssembly(
     82       "define float @test(float %a) {\n"
     83       "  %1 = fcmp ogt float %a, 5.0\n"
     84       "  %A = select i1 %1, float %a, float 5.0\n"
     85       "  ret float %A\n"
     86       "}\n");
     87   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
     88 }
     89 
     90 TEST_F(MatchSelectPatternTest, SwappedFMax) {
     91   parseAssembly(
     92       "define float @test(float %a) {\n"
     93       "  %1 = fcmp olt float 5.0, %a\n"
     94       "  %A = select i1 %1, float %a, float 5.0\n"
     95       "  ret float %A\n"
     96       "}\n");
     97   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
     98 }
     99 
    100 TEST_F(MatchSelectPatternTest, SwappedFMax2) {
    101   parseAssembly(
    102       "define float @test(float %a) {\n"
    103       "  %1 = fcmp olt float %a, 5.0\n"
    104       "  %A = select i1 %1, float 5.0, float %a\n"
    105       "  ret float %A\n"
    106       "}\n");
    107   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
    108 }
    109 
    110 TEST_F(MatchSelectPatternTest, SwappedFMax3) {
    111   parseAssembly(
    112       "define float @test(float %a) {\n"
    113       "  %1 = fcmp ult float %a, 5.0\n"
    114       "  %A = select i1 %1, float 5.0, float %a\n"
    115       "  ret float %A\n"
    116       "}\n");
    117   expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
    118 }
    119 
    120 TEST_F(MatchSelectPatternTest, FastFMin) {
    121   parseAssembly(
    122       "define float @test(float %a) {\n"
    123       "  %1 = fcmp nnan olt float %a, 5.0\n"
    124       "  %A = select i1 %1, float %a, float 5.0\n"
    125       "  ret float %A\n"
    126       "}\n");
    127   expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
    128 }
    129 
    130 TEST_F(MatchSelectPatternTest, FMinConstantZero) {
    131   parseAssembly(
    132       "define float @test(float %a) {\n"
    133       "  %1 = fcmp ole float %a, 0.0\n"
    134       "  %A = select i1 %1, float %a, float 0.0\n"
    135       "  ret float %A\n"
    136       "}\n");
    137   // This shouldn't be matched, as %a could be -0.0.
    138   expectPattern({SPF_UNKNOWN, SPNB_NA, false});
    139 }
    140 
    141 TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) {
    142   parseAssembly(
    143       "define float @test(float %a) {\n"
    144       "  %1 = fcmp nsz ole float %a, 0.0\n"
    145       "  %A = select i1 %1, float %a, float 0.0\n"
    146       "  ret float %A\n"
    147       "}\n");
    148   // But this should be, because we've ignored signed zeroes.
    149   expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
    150 }
    151 
    152 TEST_F(MatchSelectPatternTest, DoubleCastU) {
    153   parseAssembly(
    154       "define i32 @test(i8 %a, i8 %b) {\n"
    155       "  %1 = icmp ult i8 %a, %b\n"
    156       "  %2 = zext i8 %a to i32\n"
    157       "  %3 = zext i8 %b to i32\n"
    158       "  %A = select i1 %1, i32 %2, i32 %3\n"
    159       "  ret i32 %A\n"
    160       "}\n");
    161   // We should be able to look through the situation where we cast both operands
    162   // to the select.
    163   expectPattern({SPF_UMIN, SPNB_NA, false});
    164 }
    165 
    166 TEST_F(MatchSelectPatternTest, DoubleCastS) {
    167   parseAssembly(
    168       "define i32 @test(i8 %a, i8 %b) {\n"
    169       "  %1 = icmp slt i8 %a, %b\n"
    170       "  %2 = sext i8 %a to i32\n"
    171       "  %3 = sext i8 %b to i32\n"
    172       "  %A = select i1 %1, i32 %2, i32 %3\n"
    173       "  ret i32 %A\n"
    174       "}\n");
    175   // We should be able to look through the situation where we cast both operands
    176   // to the select.
    177   expectPattern({SPF_SMIN, SPNB_NA, false});
    178 }
    179 
    180 TEST_F(MatchSelectPatternTest, DoubleCastBad) {
    181   parseAssembly(
    182       "define i32 @test(i8 %a, i8 %b) {\n"
    183       "  %1 = icmp ult i8 %a, %b\n"
    184       "  %2 = zext i8 %a to i32\n"
    185       "  %3 = sext i8 %b to i32\n"
    186       "  %A = select i1 %1, i32 %2, i32 %3\n"
    187       "  ret i32 %A\n"
    188       "}\n");
    189   // The cast types here aren't the same, so we cannot match an UMIN.
    190   expectPattern({SPF_UNKNOWN, SPNB_NA, false});
    191 }
    192 
    193 TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {
    194   StringRef Assembly =
    195       "declare void @nounwind_readonly(i32*) nounwind readonly "
    196       "declare void @nounwind_argmemonly(i32*) nounwind argmemonly "
    197       "declare void @throws_but_readonly(i32*) readonly "
    198       "declare void @throws_but_argmemonly(i32*) argmemonly "
    199       " "
    200       "declare void @unknown(i32*) "
    201       " "
    202       "define void @f(i32* %p) { "
    203       "  call void @nounwind_readonly(i32* %p) "
    204       "  call void @nounwind_argmemonly(i32* %p) "
    205       "  call void @throws_but_readonly(i32* %p) "
    206       "  call void @throws_but_argmemonly(i32* %p) "
    207       "  call void @unknown(i32* %p) nounwind readonly "
    208       "  call void @unknown(i32* %p) nounwind argmemonly "
    209       "  call void @unknown(i32* %p) readonly "
    210       "  call void @unknown(i32* %p) argmemonly "
    211       "  ret void "
    212       "} ";
    213 
    214   LLVMContext Context;
    215   SMDiagnostic Error;
    216   auto M = parseAssemblyString(Assembly, Error, Context);
    217   assert(M && "Bad assembly?");
    218 
    219   auto *F = M->getFunction("f");
    220   assert(F && "Bad assembly?");
    221 
    222   auto &BB = F->getEntryBlock();
    223   bool ExpectedAnswers[] = {
    224       true,  // call void @nounwind_readonly(i32* %p)
    225       true,  // call void @nounwind_argmemonly(i32* %p)
    226       false, // call void @throws_but_readonly(i32* %p)
    227       false, // call void @throws_but_argmemonly(i32* %p)
    228       true,  // call void @unknown(i32* %p) nounwind readonly
    229       true,  // call void @unknown(i32* %p) nounwind argmemonly
    230       false, // call void @unknown(i32* %p) readonly
    231       false, // call void @unknown(i32* %p) argmemonly
    232       false, // ret void
    233   };
    234 
    235   int Index = 0;
    236   for (auto &I : BB) {
    237     EXPECT_EQ(isGuaranteedToTransferExecutionToSuccessor(&I),
    238               ExpectedAnswers[Index])
    239         << "Incorrect answer at instruction " << Index << " = " << I;
    240     Index++;
    241   }
    242 }
    243 
    244 TEST(ValueTracking, ComputeNumSignBits_PR32045) {
    245   StringRef Assembly = "define i32 @f(i32 %a) { "
    246                        "  %val = ashr i32 %a, -1 "
    247                        "  ret i32 %val "
    248                        "} ";
    249 
    250   LLVMContext Context;
    251   SMDiagnostic Error;
    252   auto M = parseAssemblyString(Assembly, Error, Context);
    253   assert(M && "Bad assembly?");
    254 
    255   auto *F = M->getFunction("f");
    256   assert(F && "Bad assembly?");
    257 
    258   auto *RVal =
    259       cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
    260   EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
    261 }
    262 
    263 TEST(ValueTracking, ComputeKnownBits) {
    264   StringRef Assembly = "define i32 @f(i32 %a, i32 %b) { "
    265                        "  %ash = mul i32 %a, 8 "
    266                        "  %aad = add i32 %ash, 7 "
    267                        "  %aan = and i32 %aad, 4095 "
    268                        "  %bsh = shl i32 %b, 4 "
    269                        "  %bad = or i32 %bsh, 6 "
    270                        "  %ban = and i32 %bad, 4095 "
    271                        "  %mul = mul i32 %aan, %ban "
    272                        "  ret i32 %mul "
    273                        "} ";
    274 
    275   LLVMContext Context;
    276   SMDiagnostic Error;
    277   auto M = parseAssemblyString(Assembly, Error, Context);
    278   assert(M && "Bad assembly?");
    279 
    280   auto *F = M->getFunction("f");
    281   assert(F && "Bad assembly?");
    282 
    283   auto *RVal =
    284       cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
    285   auto Known = computeKnownBits(RVal, M->getDataLayout());
    286   ASSERT_FALSE(Known.hasConflict());
    287   EXPECT_EQ(Known.One.getZExtValue(), 10u);
    288   EXPECT_EQ(Known.Zero.getZExtValue(), 4278190085u);
    289 }
    290 
    291 TEST(ValueTracking, ComputeKnownMulBits) {
    292   StringRef Assembly = "define i32 @f(i32 %a, i32 %b) { "
    293                        "  %aa = shl i32 %a, 5 "
    294                        "  %bb = shl i32 %b, 5 "
    295                        "  %aaa = or i32 %aa, 24 "
    296                        "  %bbb = or i32 %bb, 28 "
    297                        "  %mul = mul i32 %aaa, %bbb "
    298                        "  ret i32 %mul "
    299                        "} ";
    300 
    301   LLVMContext Context;
    302   SMDiagnostic Error;
    303   auto M = parseAssemblyString(Assembly, Error, Context);
    304   assert(M && "Bad assembly?");
    305 
    306   auto *F = M->getFunction("f");
    307   assert(F && "Bad assembly?");
    308 
    309   auto *RVal =
    310       cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
    311   auto Known = computeKnownBits(RVal, M->getDataLayout());
    312   ASSERT_FALSE(Known.hasConflict());
    313   EXPECT_EQ(Known.One.getZExtValue(), 32u);
    314   EXPECT_EQ(Known.Zero.getZExtValue(), 95u);
    315 }
    316