1 //===- llvm/unittest/IR/ConstantsTest.cpp - Constants unit tests ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/IR/Constants.h" 10 #include "llvm-c/Core.h" 11 #include "llvm/AsmParser/Parser.h" 12 #include "llvm/IR/ConstantFold.h" 13 #include "llvm/IR/DerivedTypes.h" 14 #include "llvm/IR/InstrTypes.h" 15 #include "llvm/IR/Instruction.h" 16 #include "llvm/IR/LLVMContext.h" 17 #include "llvm/IR/Module.h" 18 #include "llvm/Support/SourceMgr.h" 19 #include "gtest/gtest.h" 20 21 namespace llvm { 22 namespace { 23 24 TEST(ConstantsTest, Integer_i1) { 25 LLVMContext Context; 26 IntegerType *Int1 = IntegerType::get(Context, 1); 27 Constant *One = ConstantInt::get(Int1, 1, true); 28 Constant *Zero = ConstantInt::get(Int1, 0); 29 Constant *NegOne = ConstantInt::get(Int1, static_cast<uint64_t>(-1), true); 30 EXPECT_EQ(NegOne, ConstantInt::getSigned(Int1, -1)); 31 Constant *Poison = PoisonValue::get(Int1); 32 33 // Input: @b = constant i1 add(i1 1 , i1 1) 34 // Output: @b = constant i1 false 35 EXPECT_EQ(Zero, ConstantExpr::getAdd(One, One)); 36 37 // @c = constant i1 add(i1 -1, i1 1) 38 // @c = constant i1 false 39 EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, One)); 40 41 // @d = constant i1 add(i1 -1, i1 -1) 42 // @d = constant i1 false 43 EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, NegOne)); 44 45 // @e = constant i1 sub(i1 -1, i1 1) 46 // @e = constant i1 false 47 EXPECT_EQ(Zero, ConstantExpr::getSub(NegOne, One)); 48 49 // @f = constant i1 sub(i1 1 , i1 -1) 50 // @f = constant i1 false 51 EXPECT_EQ(Zero, ConstantExpr::getSub(One, NegOne)); 52 53 // @g = constant i1 sub(i1 1 , i1 1) 54 // @g = constant i1 false 55 EXPECT_EQ(Zero, ConstantExpr::getSub(One, One)); 56 57 // @h = constant i1 shl(i1 1 , i1 1) ; poison 58 // @h = constant i1 poison 59 EXPECT_EQ(Poison, ConstantExpr::getShl(One, One)); 60 61 // @i = constant i1 shl(i1 1 , i1 0) 62 // @i = constant i1 true 63 EXPECT_EQ(One, ConstantExpr::getShl(One, Zero)); 64 65 // @n = constant i1 mul(i1 -1, i1 1) 66 // @n = constant i1 true 67 EXPECT_EQ(One, ConstantExpr::getMul(NegOne, One)); 68 69 // @o = constant i1 sdiv(i1 -1, i1 1) ; overflow 70 // @o = constant i1 true 71 EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::SDiv, NegOne, One)); 72 73 // @p = constant i1 sdiv(i1 1 , i1 -1); overflow 74 // @p = constant i1 true 75 EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::SDiv, One, NegOne)); 76 77 // @q = constant i1 udiv(i1 -1, i1 1) 78 // @q = constant i1 true 79 EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::UDiv, NegOne, One)); 80 81 // @r = constant i1 udiv(i1 1, i1 -1) 82 // @r = constant i1 true 83 EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::UDiv, One, NegOne)); 84 85 // @s = constant i1 srem(i1 -1, i1 1) ; overflow 86 // @s = constant i1 false 87 EXPECT_EQ(Zero, 88 ConstantFoldBinaryInstruction(Instruction::SRem, NegOne, One)); 89 90 // @u = constant i1 srem(i1 1, i1 -1) ; overflow 91 // @u = constant i1 false 92 EXPECT_EQ(Zero, 93 ConstantFoldBinaryInstruction(Instruction::SRem, One, NegOne)); 94 } 95 96 TEST(ConstantsTest, IntSigns) { 97 LLVMContext Context; 98 IntegerType *Int8Ty = Type::getInt8Ty(Context); 99 EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, false)->getSExtValue()); 100 EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, true)->getSExtValue()); 101 EXPECT_EQ(100, ConstantInt::getSigned(Int8Ty, 100)->getSExtValue()); 102 EXPECT_EQ(-50, ConstantInt::get(Int8Ty, 206)->getSExtValue()); 103 EXPECT_EQ(-50, ConstantInt::getSigned(Int8Ty, -50)->getSExtValue()); 104 EXPECT_EQ(206U, ConstantInt::getSigned(Int8Ty, -50)->getZExtValue()); 105 106 // Overflow is handled by truncation. 107 EXPECT_EQ(0x3b, ConstantInt::get(Int8Ty, 0x13b)->getSExtValue()); 108 } 109 110 TEST(ConstantsTest, PointerCast) { 111 LLVMContext C; 112 Type *PtrTy = PointerType::get(C, 0); 113 Type *Int64Ty = Type::getInt64Ty(C); 114 VectorType *PtrVecTy = FixedVectorType::get(PtrTy, 4); 115 VectorType *Int64VecTy = FixedVectorType::get(Int64Ty, 4); 116 VectorType *PtrScalableVecTy = ScalableVectorType::get(PtrTy, 4); 117 VectorType *Int64ScalableVecTy = ScalableVectorType::get(Int64Ty, 4); 118 119 // ptrtoint ptr to i64 120 EXPECT_EQ( 121 Constant::getNullValue(Int64Ty), 122 ConstantExpr::getPointerCast(Constant::getNullValue(PtrTy), Int64Ty)); 123 124 // bitcast ptr to ptr 125 EXPECT_EQ(Constant::getNullValue(PtrTy), 126 ConstantExpr::getPointerCast(Constant::getNullValue(PtrTy), PtrTy)); 127 128 // ptrtoint <4 x ptr> to <4 x i64> 129 EXPECT_EQ(Constant::getNullValue(Int64VecTy), 130 ConstantExpr::getPointerCast(Constant::getNullValue(PtrVecTy), 131 Int64VecTy)); 132 133 // ptrtoint <vscale x 4 x ptr> to <vscale x 4 x i64> 134 EXPECT_EQ(Constant::getNullValue(Int64ScalableVecTy), 135 ConstantExpr::getPointerCast( 136 Constant::getNullValue(PtrScalableVecTy), Int64ScalableVecTy)); 137 138 // bitcast <4 x ptr> to <4 x ptr> 139 EXPECT_EQ( 140 Constant::getNullValue(PtrVecTy), 141 ConstantExpr::getPointerCast(Constant::getNullValue(PtrVecTy), PtrVecTy)); 142 143 // bitcast <vscale x 4 x ptr> to <vscale x 4 x ptr> 144 EXPECT_EQ(Constant::getNullValue(PtrScalableVecTy), 145 ConstantExpr::getPointerCast( 146 Constant::getNullValue(PtrScalableVecTy), PtrScalableVecTy)); 147 148 Type *Ptr1Ty = PointerType::get(C, 1); 149 ConstantInt *K = ConstantInt::get(Type::getInt64Ty(C), 1234); 150 151 // Make sure that addrspacecast of inttoptr is not folded away. 152 EXPECT_NE(K, ConstantExpr::getAddrSpaceCast( 153 ConstantExpr::getIntToPtr(K, PtrTy), Ptr1Ty)); 154 EXPECT_NE(K, ConstantExpr::getAddrSpaceCast( 155 ConstantExpr::getIntToPtr(K, Ptr1Ty), PtrTy)); 156 157 Constant *NullPtr0 = Constant::getNullValue(PtrTy); 158 Constant *NullPtr1 = Constant::getNullValue(Ptr1Ty); 159 160 // Make sure that addrspacecast of null is not folded away. 161 EXPECT_NE(Constant::getNullValue(PtrTy), 162 ConstantExpr::getAddrSpaceCast(NullPtr0, Ptr1Ty)); 163 164 EXPECT_NE(Constant::getNullValue(Ptr1Ty), 165 ConstantExpr::getAddrSpaceCast(NullPtr1, PtrTy)); 166 } 167 168 #define CHECK(x, y) \ 169 { \ 170 std::string __s; \ 171 raw_string_ostream __o(__s); \ 172 Instruction *__I = cast<ConstantExpr>(x)->getAsInstruction(); \ 173 __I->print(__o); \ 174 __I->deleteValue(); \ 175 __o.flush(); \ 176 EXPECT_EQ(std::string(" <badref> = " y), __s); \ 177 } 178 179 TEST(ConstantsTest, AsInstructionsTest) { 180 LLVMContext Context; 181 std::unique_ptr<Module> M(new Module("MyModule", Context)); 182 183 Type *Int64Ty = Type::getInt64Ty(Context); 184 Type *Int32Ty = Type::getInt32Ty(Context); 185 Type *Int16Ty = Type::getInt16Ty(Context); 186 187 Constant *Global = 188 M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty)); 189 Constant *Global2 = 190 M->getOrInsertGlobal("dummy2", PointerType::getUnqual(Int32Ty)); 191 192 Constant *P0 = ConstantExpr::getPtrToInt(Global, Int32Ty); 193 Constant *P4 = ConstantExpr::getPtrToInt(Global2, Int32Ty); 194 Constant *P6 = ConstantExpr::getBitCast(P4, FixedVectorType::get(Int16Ty, 2)); 195 196 Constant *One = ConstantInt::get(Int32Ty, 1); 197 Constant *Two = ConstantInt::get(Int64Ty, 2); 198 Constant *Big = ConstantInt::get(Context, APInt{256, uint64_t(-1), true}); 199 Constant *Elt = ConstantInt::get(Int16Ty, 2015); 200 Constant *Poison16 = PoisonValue::get(Int16Ty); 201 Constant *Undef64 = UndefValue::get(Int64Ty); 202 Constant *PoisonV16 = PoisonValue::get(P6->getType()); 203 204 #define P0STR "ptrtoint (ptr @dummy to i32)" 205 #define P3STR "ptrtoint (ptr @dummy to i1)" 206 #define P4STR "ptrtoint (ptr @dummy2 to i32)" 207 #define P6STR "bitcast (i32 ptrtoint (ptr @dummy2 to i32) to <2 x i16>)" 208 209 CHECK(ConstantExpr::getNeg(P0), "sub i32 0, " P0STR); 210 CHECK(ConstantExpr::getNot(P0), "xor i32 " P0STR ", -1"); 211 CHECK(ConstantExpr::getAdd(P0, P0), "add i32 " P0STR ", " P0STR); 212 CHECK(ConstantExpr::getAdd(P0, P0, false, true), 213 "add nsw i32 " P0STR ", " P0STR); 214 CHECK(ConstantExpr::getAdd(P0, P0, true, true), 215 "add nuw nsw i32 " P0STR ", " P0STR); 216 CHECK(ConstantExpr::getSub(P0, P0), "sub i32 " P0STR ", " P0STR); 217 CHECK(ConstantExpr::getMul(P0, P0), "mul i32 " P0STR ", " P0STR); 218 CHECK(ConstantExpr::getXor(P0, P0), "xor i32 " P0STR ", " P0STR); 219 CHECK(ConstantExpr::getShl(P0, P0), "shl i32 " P0STR ", " P0STR); 220 CHECK(ConstantExpr::getShl(P0, P0, true), "shl nuw i32 " P0STR ", " P0STR); 221 CHECK(ConstantExpr::getShl(P0, P0, false, true), 222 "shl nsw i32 " P0STR ", " P0STR); 223 224 CHECK(ConstantExpr::getICmp(CmpInst::ICMP_EQ, P0, P4), 225 "icmp eq i32 " P0STR ", " P4STR); 226 227 std::vector<Constant *> V; 228 V.push_back(One); 229 // FIXME: getGetElementPtr() actually creates an inbounds ConstantGEP, 230 // not a normal one! 231 // CHECK(ConstantExpr::getGetElementPtr(Global, V, false), 232 // "getelementptr i32*, i32** @dummy, i32 1"); 233 CHECK(ConstantExpr::getInBoundsGetElementPtr(PointerType::getUnqual(Int32Ty), 234 Global, V), 235 "getelementptr inbounds ptr, ptr @dummy, i32 1"); 236 237 CHECK(ConstantExpr::getExtractElement(P6, One), 238 "extractelement <2 x i16> " P6STR ", i32 1"); 239 240 EXPECT_EQ(Poison16, ConstantExpr::getExtractElement(P6, Two)); 241 EXPECT_EQ(Poison16, ConstantExpr::getExtractElement(P6, Big)); 242 EXPECT_EQ(Poison16, ConstantExpr::getExtractElement(P6, Undef64)); 243 244 EXPECT_EQ(Elt, ConstantExpr::getExtractElement( 245 ConstantExpr::getInsertElement(P6, Elt, One), One)); 246 EXPECT_EQ(PoisonV16, ConstantExpr::getInsertElement(P6, Elt, Two)); 247 EXPECT_EQ(PoisonV16, ConstantExpr::getInsertElement(P6, Elt, Big)); 248 EXPECT_EQ(PoisonV16, ConstantExpr::getInsertElement(P6, Elt, Undef64)); 249 } 250 251 #ifdef GTEST_HAS_DEATH_TEST 252 #ifndef NDEBUG 253 TEST(ConstantsTest, ReplaceWithConstantTest) { 254 LLVMContext Context; 255 std::unique_ptr<Module> M(new Module("MyModule", Context)); 256 257 Type *Int32Ty = Type::getInt32Ty(Context); 258 Constant *One = ConstantInt::get(Int32Ty, 1); 259 260 Constant *Global = 261 M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty)); 262 Constant *GEP = ConstantExpr::getGetElementPtr( 263 PointerType::getUnqual(Int32Ty), Global, One); 264 EXPECT_DEATH(Global->replaceAllUsesWith(GEP), 265 "this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!"); 266 } 267 268 #endif 269 #endif 270 271 #undef CHECK 272 273 TEST(ConstantsTest, ConstantArrayReplaceWithConstant) { 274 LLVMContext Context; 275 std::unique_ptr<Module> M(new Module("MyModule", Context)); 276 277 Type *IntTy = Type::getInt8Ty(Context); 278 ArrayType *ArrayTy = ArrayType::get(IntTy, 2); 279 Constant *A01Vals[2] = {ConstantInt::get(IntTy, 0), 280 ConstantInt::get(IntTy, 1)}; 281 Constant *A01 = ConstantArray::get(ArrayTy, A01Vals); 282 283 Constant *Global = new GlobalVariable(*M, IntTy, false, 284 GlobalValue::ExternalLinkage, nullptr); 285 Constant *GlobalInt = ConstantExpr::getPtrToInt(Global, IntTy); 286 Constant *A0GVals[2] = {ConstantInt::get(IntTy, 0), GlobalInt}; 287 Constant *A0G = ConstantArray::get(ArrayTy, A0GVals); 288 ASSERT_NE(A01, A0G); 289 290 GlobalVariable *RefArray = 291 new GlobalVariable(*M, ArrayTy, false, GlobalValue::ExternalLinkage, A0G); 292 ASSERT_EQ(A0G, RefArray->getInitializer()); 293 294 GlobalInt->replaceAllUsesWith(ConstantInt::get(IntTy, 1)); 295 ASSERT_EQ(A01, RefArray->getInitializer()); 296 } 297 298 TEST(ConstantsTest, ConstantExprReplaceWithConstant) { 299 LLVMContext Context; 300 std::unique_ptr<Module> M(new Module("MyModule", Context)); 301 302 Type *IntTy = Type::getInt8Ty(Context); 303 Constant *G1 = new GlobalVariable(*M, IntTy, false, 304 GlobalValue::ExternalLinkage, nullptr); 305 Constant *G2 = new GlobalVariable(*M, IntTy, false, 306 GlobalValue::ExternalLinkage, nullptr); 307 ASSERT_NE(G1, G2); 308 309 Constant *Int1 = ConstantExpr::getPtrToInt(G1, IntTy); 310 Constant *Int2 = ConstantExpr::getPtrToInt(G2, IntTy); 311 ASSERT_NE(Int1, Int2); 312 313 GlobalVariable *Ref = 314 new GlobalVariable(*M, IntTy, false, GlobalValue::ExternalLinkage, Int1); 315 ASSERT_EQ(Int1, Ref->getInitializer()); 316 317 G1->replaceAllUsesWith(G2); 318 ASSERT_EQ(Int2, Ref->getInitializer()); 319 } 320 321 TEST(ConstantsTest, GEPReplaceWithConstant) { 322 LLVMContext Context; 323 std::unique_ptr<Module> M(new Module("MyModule", Context)); 324 325 Type *IntTy = Type::getInt32Ty(Context); 326 Type *PtrTy = PointerType::get(IntTy, 0); 327 auto *C1 = ConstantInt::get(IntTy, 1); 328 auto *Placeholder = new GlobalVariable( 329 *M, IntTy, false, GlobalValue::ExternalWeakLinkage, nullptr); 330 auto *GEP = ConstantExpr::getGetElementPtr(IntTy, Placeholder, C1); 331 ASSERT_EQ(GEP->getOperand(0), Placeholder); 332 333 auto *Ref = 334 new GlobalVariable(*M, PtrTy, false, GlobalValue::ExternalLinkage, GEP); 335 ASSERT_EQ(GEP, Ref->getInitializer()); 336 337 auto *Global = new GlobalVariable(*M, IntTy, false, 338 GlobalValue::ExternalLinkage, nullptr); 339 auto *Alias = GlobalAlias::create(IntTy, 0, GlobalValue::ExternalLinkage, 340 "alias", Global, M.get()); 341 Placeholder->replaceAllUsesWith(Alias); 342 ASSERT_EQ(GEP, Ref->getInitializer()); 343 ASSERT_EQ(GEP->getOperand(0), Alias); 344 } 345 346 TEST(ConstantsTest, AliasCAPI) { 347 LLVMContext Context; 348 SMDiagnostic Error; 349 std::unique_ptr<Module> M = 350 parseAssemblyString("@g = global i32 42", Error, Context); 351 GlobalVariable *G = M->getGlobalVariable("g"); 352 Type *I16Ty = Type::getInt16Ty(Context); 353 Type *I16PTy = PointerType::get(I16Ty, 0); 354 Constant *Aliasee = ConstantExpr::getBitCast(G, I16PTy); 355 LLVMValueRef AliasRef = 356 LLVMAddAlias2(wrap(M.get()), wrap(I16Ty), 0, wrap(Aliasee), "a"); 357 ASSERT_EQ(unwrap<GlobalAlias>(AliasRef)->getAliasee(), Aliasee); 358 } 359 360 static std::string getNameOfType(Type *T) { 361 std::string S; 362 raw_string_ostream RSOS(S); 363 T->print(RSOS); 364 return S; 365 } 366 367 TEST(ConstantsTest, BuildConstantDataArrays) { 368 LLVMContext Context; 369 370 for (Type *T : {Type::getInt8Ty(Context), Type::getInt16Ty(Context), 371 Type::getInt32Ty(Context), Type::getInt64Ty(Context)}) { 372 ArrayType *ArrayTy = ArrayType::get(T, 2); 373 Constant *Vals[] = {ConstantInt::get(T, 0), ConstantInt::get(T, 1)}; 374 Constant *CA = ConstantArray::get(ArrayTy, Vals); 375 ASSERT_TRUE(isa<ConstantDataArray>(CA)) << " T = " << getNameOfType(T); 376 auto *CDA = cast<ConstantDataArray>(CA); 377 Constant *CA2 = ConstantDataArray::getRaw( 378 CDA->getRawDataValues(), CDA->getNumElements(), CDA->getElementType()); 379 ASSERT_TRUE(CA == CA2) << " T = " << getNameOfType(T); 380 } 381 382 for (Type *T : {Type::getHalfTy(Context), Type::getBFloatTy(Context), 383 Type::getFloatTy(Context), Type::getDoubleTy(Context)}) { 384 ArrayType *ArrayTy = ArrayType::get(T, 2); 385 Constant *Vals[] = {ConstantFP::get(T, 0), ConstantFP::get(T, 1)}; 386 Constant *CA = ConstantArray::get(ArrayTy, Vals); 387 ASSERT_TRUE(isa<ConstantDataArray>(CA)) << " T = " << getNameOfType(T); 388 auto *CDA = cast<ConstantDataArray>(CA); 389 Constant *CA2 = ConstantDataArray::getRaw( 390 CDA->getRawDataValues(), CDA->getNumElements(), CDA->getElementType()); 391 ASSERT_TRUE(CA == CA2) << " T = " << getNameOfType(T); 392 } 393 } 394 395 TEST(ConstantsTest, BuildConstantDataVectors) { 396 LLVMContext Context; 397 398 for (Type *T : {Type::getInt8Ty(Context), Type::getInt16Ty(Context), 399 Type::getInt32Ty(Context), Type::getInt64Ty(Context)}) { 400 Constant *Vals[] = {ConstantInt::get(T, 0), ConstantInt::get(T, 1)}; 401 Constant *CV = ConstantVector::get(Vals); 402 ASSERT_TRUE(isa<ConstantDataVector>(CV)) << " T = " << getNameOfType(T); 403 auto *CDV = cast<ConstantDataVector>(CV); 404 Constant *CV2 = ConstantDataVector::getRaw( 405 CDV->getRawDataValues(), CDV->getNumElements(), CDV->getElementType()); 406 ASSERT_TRUE(CV == CV2) << " T = " << getNameOfType(T); 407 } 408 409 for (Type *T : {Type::getHalfTy(Context), Type::getBFloatTy(Context), 410 Type::getFloatTy(Context), Type::getDoubleTy(Context)}) { 411 Constant *Vals[] = {ConstantFP::get(T, 0), ConstantFP::get(T, 1)}; 412 Constant *CV = ConstantVector::get(Vals); 413 ASSERT_TRUE(isa<ConstantDataVector>(CV)) << " T = " << getNameOfType(T); 414 auto *CDV = cast<ConstantDataVector>(CV); 415 Constant *CV2 = ConstantDataVector::getRaw( 416 CDV->getRawDataValues(), CDV->getNumElements(), CDV->getElementType()); 417 ASSERT_TRUE(CV == CV2) << " T = " << getNameOfType(T); 418 } 419 } 420 421 TEST(ConstantsTest, BitcastToGEP) { 422 LLVMContext Context; 423 std::unique_ptr<Module> M(new Module("MyModule", Context)); 424 425 auto *i32 = Type::getInt32Ty(Context); 426 auto *U = StructType::create(Context, "Unsized"); 427 Type *EltTys[] = {i32, U}; 428 auto *S = StructType::create(EltTys); 429 430 auto *G = 431 new GlobalVariable(*M, S, false, GlobalValue::ExternalLinkage, nullptr); 432 auto *PtrTy = PointerType::get(i32, 0); 433 auto *C = ConstantExpr::getBitCast(G, PtrTy); 434 /* With opaque pointers, no cast is necessary. */ 435 EXPECT_EQ(C, G); 436 } 437 438 bool foldFuncPtrAndConstToNull(LLVMContext &Context, Module *TheModule, 439 uint64_t AndValue, 440 MaybeAlign FunctionAlign = std::nullopt) { 441 Type *VoidType(Type::getVoidTy(Context)); 442 FunctionType *FuncType(FunctionType::get(VoidType, false)); 443 Function *Func( 444 Function::Create(FuncType, GlobalValue::ExternalLinkage, "", TheModule)); 445 446 if (FunctionAlign) 447 Func->setAlignment(*FunctionAlign); 448 449 IntegerType *ConstantIntType(Type::getInt32Ty(Context)); 450 ConstantInt *TheConstant(ConstantInt::get(ConstantIntType, AndValue)); 451 452 Constant *TheConstantExpr(ConstantExpr::getPtrToInt(Func, ConstantIntType)); 453 454 Constant *C = ConstantFoldBinaryInstruction(Instruction::And, TheConstantExpr, 455 TheConstant); 456 bool Result = C && C->isNullValue(); 457 458 if (!TheModule) { 459 // If the Module exists then it will delete the Function. 460 delete Func; 461 } 462 463 return Result; 464 } 465 466 TEST(ConstantsTest, FoldFunctionPtrAlignUnknownAnd2) { 467 LLVMContext Context; 468 Module TheModule("TestModule", Context); 469 // When the DataLayout doesn't specify a function pointer alignment we 470 // assume in this case that it is 4 byte aligned. This is a bug but we can't 471 // fix it directly because it causes a code size regression on X86. 472 // FIXME: This test should be changed once existing targets have 473 // appropriate defaults. See associated FIXME in ConstantFoldBinaryInstruction 474 ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2)); 475 } 476 477 TEST(ConstantsTest, DontFoldFunctionPtrAlignUnknownAnd4) { 478 LLVMContext Context; 479 Module TheModule("TestModule", Context); 480 ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 4)); 481 } 482 483 TEST(ConstantsTest, FoldFunctionPtrAlign4) { 484 LLVMContext Context; 485 Module TheModule("TestModule", Context); 486 const char *AlignmentStrings[] = {"Fi32", "Fn32"}; 487 488 for (unsigned AndValue = 1; AndValue <= 2; ++AndValue) { 489 for (const char *AlignmentString : AlignmentStrings) { 490 TheModule.setDataLayout(AlignmentString); 491 ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, AndValue)); 492 } 493 } 494 } 495 496 TEST(ConstantsTest, DontFoldFunctionPtrAlign1) { 497 LLVMContext Context; 498 Module TheModule("TestModule", Context); 499 const char *AlignmentStrings[] = {"Fi8", "Fn8"}; 500 501 for (const char *AlignmentString : AlignmentStrings) { 502 TheModule.setDataLayout(AlignmentString); 503 ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2)); 504 } 505 } 506 507 TEST(ConstantsTest, FoldFunctionAlign4PtrAlignMultiple) { 508 LLVMContext Context; 509 Module TheModule("TestModule", Context); 510 TheModule.setDataLayout("Fn8"); 511 ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, Align(4))); 512 } 513 514 TEST(ConstantsTest, DontFoldFunctionAlign4PtrAlignIndependent) { 515 LLVMContext Context; 516 Module TheModule("TestModule", Context); 517 TheModule.setDataLayout("Fi8"); 518 ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, Align(4))); 519 } 520 521 TEST(ConstantsTest, DontFoldFunctionPtrIfNoModule) { 522 LLVMContext Context; 523 // Even though the function is explicitly 4 byte aligned, in the absence of a 524 // DataLayout we can't assume that the function pointer is aligned. 525 ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, nullptr, 2, Align(4))); 526 } 527 528 TEST(ConstantsTest, FoldGlobalVariablePtr) { 529 LLVMContext Context; 530 531 IntegerType *IntType(Type::getInt32Ty(Context)); 532 533 std::unique_ptr<GlobalVariable> Global( 534 new GlobalVariable(IntType, true, GlobalValue::ExternalLinkage)); 535 536 Global->setAlignment(Align(4)); 537 538 ConstantInt *TheConstant(ConstantInt::get(IntType, 2)); 539 540 Constant *TheConstantExpr(ConstantExpr::getPtrToInt(Global.get(), IntType)); 541 542 ASSERT_TRUE(ConstantFoldBinaryInstruction(Instruction::And, TheConstantExpr, 543 TheConstant) 544 ->isNullValue()); 545 } 546 547 // Check that containsUndefOrPoisonElement and containsPoisonElement is working 548 // great 549 550 TEST(ConstantsTest, containsUndefElemTest) { 551 LLVMContext Context; 552 553 Type *Int32Ty = Type::getInt32Ty(Context); 554 Constant *CU = UndefValue::get(Int32Ty); 555 Constant *CP = PoisonValue::get(Int32Ty); 556 Constant *C1 = ConstantInt::get(Int32Ty, 1); 557 Constant *C2 = ConstantInt::get(Int32Ty, 2); 558 559 { 560 Constant *V1 = ConstantVector::get({C1, C2}); 561 EXPECT_FALSE(V1->containsUndefOrPoisonElement()); 562 EXPECT_FALSE(V1->containsPoisonElement()); 563 } 564 565 { 566 Constant *V2 = ConstantVector::get({C1, CU}); 567 EXPECT_TRUE(V2->containsUndefOrPoisonElement()); 568 EXPECT_FALSE(V2->containsPoisonElement()); 569 } 570 571 { 572 Constant *V3 = ConstantVector::get({C1, CP}); 573 EXPECT_TRUE(V3->containsUndefOrPoisonElement()); 574 EXPECT_TRUE(V3->containsPoisonElement()); 575 } 576 577 { 578 Constant *V4 = ConstantVector::get({CU, CP}); 579 EXPECT_TRUE(V4->containsUndefOrPoisonElement()); 580 EXPECT_TRUE(V4->containsPoisonElement()); 581 } 582 } 583 584 // Check that undefined elements in vector constants are matched 585 // correctly for both integer and floating-point types. Just don't 586 // crash on vectors of pointers (could be handled?). 587 588 TEST(ConstantsTest, isElementWiseEqual) { 589 LLVMContext Context; 590 591 Type *Int32Ty = Type::getInt32Ty(Context); 592 Constant *CU = UndefValue::get(Int32Ty); 593 Constant *C1 = ConstantInt::get(Int32Ty, 1); 594 Constant *C2 = ConstantInt::get(Int32Ty, 2); 595 596 Constant *C1211 = ConstantVector::get({C1, C2, C1, C1}); 597 Constant *C12U1 = ConstantVector::get({C1, C2, CU, C1}); 598 Constant *C12U2 = ConstantVector::get({C1, C2, CU, C2}); 599 Constant *C12U21 = ConstantVector::get({C1, C2, CU, C2, C1}); 600 601 EXPECT_TRUE(C1211->isElementWiseEqual(C12U1)); 602 EXPECT_TRUE(C12U1->isElementWiseEqual(C1211)); 603 EXPECT_FALSE(C12U2->isElementWiseEqual(C12U1)); 604 EXPECT_FALSE(C12U1->isElementWiseEqual(C12U2)); 605 EXPECT_FALSE(C12U21->isElementWiseEqual(C12U2)); 606 607 Type *FltTy = Type::getFloatTy(Context); 608 Constant *CFU = UndefValue::get(FltTy); 609 Constant *CF1 = ConstantFP::get(FltTy, 1.0); 610 Constant *CF2 = ConstantFP::get(FltTy, 2.0); 611 612 Constant *CF1211 = ConstantVector::get({CF1, CF2, CF1, CF1}); 613 Constant *CF12U1 = ConstantVector::get({CF1, CF2, CFU, CF1}); 614 Constant *CF12U2 = ConstantVector::get({CF1, CF2, CFU, CF2}); 615 Constant *CFUU1U = ConstantVector::get({CFU, CFU, CF1, CFU}); 616 617 EXPECT_TRUE(CF1211->isElementWiseEqual(CF12U1)); 618 EXPECT_TRUE(CF12U1->isElementWiseEqual(CF1211)); 619 EXPECT_TRUE(CFUU1U->isElementWiseEqual(CF12U1)); 620 EXPECT_FALSE(CF12U2->isElementWiseEqual(CF12U1)); 621 EXPECT_FALSE(CF12U1->isElementWiseEqual(CF12U2)); 622 623 PointerType *PtrTy = PointerType::get(Context, 0); 624 Constant *CPU = UndefValue::get(PtrTy); 625 Constant *CP0 = ConstantPointerNull::get(PtrTy); 626 627 Constant *CP0000 = ConstantVector::get({CP0, CP0, CP0, CP0}); 628 Constant *CP00U0 = ConstantVector::get({CP0, CP0, CPU, CP0}); 629 Constant *CP00U = ConstantVector::get({CP0, CP0, CPU}); 630 631 EXPECT_FALSE(CP0000->isElementWiseEqual(CP00U0)); 632 EXPECT_FALSE(CP00U0->isElementWiseEqual(CP0000)); 633 EXPECT_FALSE(CP0000->isElementWiseEqual(CP00U)); 634 EXPECT_FALSE(CP00U->isElementWiseEqual(CP00U0)); 635 } 636 637 // Check that vector/aggregate constants correctly store undef and poison 638 // elements. 639 640 TEST(ConstantsTest, CheckElementWiseUndefPoison) { 641 LLVMContext Context; 642 643 Type *Int32Ty = Type::getInt32Ty(Context); 644 StructType *STy = StructType::get(Int32Ty, Int32Ty); 645 ArrayType *ATy = ArrayType::get(Int32Ty, 2); 646 Constant *CU = UndefValue::get(Int32Ty); 647 Constant *CP = PoisonValue::get(Int32Ty); 648 649 { 650 Constant *CUU = ConstantVector::get({CU, CU}); 651 Constant *CPP = ConstantVector::get({CP, CP}); 652 Constant *CUP = ConstantVector::get({CU, CP}); 653 Constant *CPU = ConstantVector::get({CP, CU}); 654 EXPECT_EQ(CUU, UndefValue::get(CUU->getType())); 655 EXPECT_EQ(CPP, PoisonValue::get(CPP->getType())); 656 EXPECT_NE(CUP, UndefValue::get(CUP->getType())); 657 EXPECT_NE(CPU, UndefValue::get(CPU->getType())); 658 } 659 660 { 661 Constant *CUU = ConstantStruct::get(STy, {CU, CU}); 662 Constant *CPP = ConstantStruct::get(STy, {CP, CP}); 663 Constant *CUP = ConstantStruct::get(STy, {CU, CP}); 664 Constant *CPU = ConstantStruct::get(STy, {CP, CU}); 665 EXPECT_EQ(CUU, UndefValue::get(CUU->getType())); 666 EXPECT_EQ(CPP, PoisonValue::get(CPP->getType())); 667 EXPECT_NE(CUP, UndefValue::get(CUP->getType())); 668 EXPECT_NE(CPU, UndefValue::get(CPU->getType())); 669 } 670 671 { 672 Constant *CUU = ConstantArray::get(ATy, {CU, CU}); 673 Constant *CPP = ConstantArray::get(ATy, {CP, CP}); 674 Constant *CUP = ConstantArray::get(ATy, {CU, CP}); 675 Constant *CPU = ConstantArray::get(ATy, {CP, CU}); 676 EXPECT_EQ(CUU, UndefValue::get(CUU->getType())); 677 EXPECT_EQ(CPP, PoisonValue::get(CPP->getType())); 678 EXPECT_NE(CUP, UndefValue::get(CUP->getType())); 679 EXPECT_NE(CPU, UndefValue::get(CPU->getType())); 680 } 681 } 682 683 TEST(ConstantsTest, GetSplatValueRoundTrip) { 684 LLVMContext Context; 685 686 Type *FloatTy = Type::getFloatTy(Context); 687 Type *Int32Ty = Type::getInt32Ty(Context); 688 Type *Int8Ty = Type::getInt8Ty(Context); 689 690 for (unsigned Min : {1, 2, 8}) { 691 auto ScalableEC = ElementCount::getScalable(Min); 692 auto FixedEC = ElementCount::getFixed(Min); 693 694 for (auto EC : {ScalableEC, FixedEC}) { 695 for (auto *Ty : {FloatTy, Int32Ty, Int8Ty}) { 696 Constant *Zero = Constant::getNullValue(Ty); 697 Constant *One = Constant::getAllOnesValue(Ty); 698 699 for (auto *C : {Zero, One}) { 700 Constant *Splat = ConstantVector::getSplat(EC, C); 701 ASSERT_NE(nullptr, Splat); 702 703 Constant *SplatVal = Splat->getSplatValue(); 704 EXPECT_NE(nullptr, SplatVal); 705 EXPECT_EQ(SplatVal, C); 706 } 707 } 708 } 709 } 710 } 711 712 TEST(ConstantsTest, ComdatUserTracking) { 713 LLVMContext Context; 714 Module M("MyModule", Context); 715 716 Comdat *C = M.getOrInsertComdat("comdat"); 717 const SmallPtrSetImpl<GlobalObject *> &Users = C->getUsers(); 718 EXPECT_TRUE(Users.size() == 0); 719 720 Type *Ty = Type::getInt8Ty(Context); 721 GlobalVariable *GV1 = cast<GlobalVariable>(M.getOrInsertGlobal("gv1", Ty)); 722 GV1->setComdat(C); 723 EXPECT_TRUE(Users.size() == 1); 724 EXPECT_TRUE(Users.contains(GV1)); 725 726 GlobalVariable *GV2 = cast<GlobalVariable>(M.getOrInsertGlobal("gv2", Ty)); 727 GV2->setComdat(C); 728 EXPECT_TRUE(Users.size() == 2); 729 EXPECT_TRUE(Users.contains(GV2)); 730 731 GV1->eraseFromParent(); 732 EXPECT_TRUE(Users.size() == 1); 733 EXPECT_TRUE(Users.contains(GV2)); 734 735 GV2->eraseFromParent(); 736 EXPECT_TRUE(Users.size() == 0); 737 } 738 739 } // end anonymous namespace 740 } // end namespace llvm 741