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