[IRBuilder] Handle constexpr-bitcast for IRBuilder::CreateThreadLocalAddress
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>
Wed, 3 Aug 2022 03:11:27 +0000 (11:11 +0800)
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>
Wed, 3 Aug 2022 03:13:49 +0000 (11:13 +0800)
In case that opaque pointers not enabled, there may be some constexpr
bitcast uses for thread local variables and the design of llvm allow
people to sink constant arbitrarily. This breaks the assumption of
IRBuilder::CreateThreadLocalAddress. This patch tries to handle the
case.

llvm/lib/IR/IRBuilder.cpp
llvm/unittests/IR/IRBuilderTest.cpp

index 469bd4d..1dcf5fb 100644 (file)
@@ -527,8 +527,19 @@ CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
 }
 
 CallInst *IRBuilderBase::CreateThreadLocalAddress(Value *Ptr) {
-  assert(isa<GlobalValue>(Ptr) && cast<GlobalValue>(Ptr)->isThreadLocal() &&
+#ifndef NDEBUG
+  // Handle specially for constexpr cast. This is possible when
+  // opaque pointers not enabled since constant could be sinked
+  // directly by the design of llvm. This could be eliminated
+  // after we eliminate the abuse of constexpr.
+  auto *V = Ptr;
+  if (auto *CE = dyn_cast<ConstantExpr>(V))
+    if (CE->isCast())
+      V = CE->getOperand(0);
+
+  assert(isa<GlobalValue>(V) && cast<GlobalValue>(V)->isThreadLocal() &&
          "threadlocal_address only applies to thread local variables.");
+#endif
   return CreateIntrinsic(llvm::Intrinsic::threadlocal_address, {Ptr->getType()},
                          {Ptr});
 }
index 4a6c46e..ca08329 100644 (file)
@@ -1009,6 +1009,21 @@ TEST_F(IRBuilderTest, CreateGlobalStringPtr) {
   EXPECT_TRUE(String3->getType()->getPointerAddressSpace() == 2);
 }
 
+TEST_F(IRBuilderTest, CreateThreadLocalAddress) {
+  IRBuilder<> Builder(BB);
+
+  GlobalVariable *G = new GlobalVariable(*M, Builder.getInt64Ty(), /*isConstant*/true,
+                                         GlobalValue::ExternalLinkage, nullptr, "", nullptr,
+                                         GlobalValue::GeneralDynamicTLSModel);
+
+  Constant *CEBC = ConstantExpr::getBitCast(G, Builder.getInt8PtrTy());
+  // Tests that IRBuilder::CreateThreadLocalAddress wouldn't crash if its operand
+  // is BitCast ConstExpr. The case should be eliminated after we eliminate the
+  // abuse of constexpr.
+  CallInst *CI = Builder.CreateThreadLocalAddress(CEBC);
+  EXPECT_NE(CI, nullptr);
+}
+
 TEST_F(IRBuilderTest, DebugLoc) {
   auto CalleeTy = FunctionType::get(Type::getVoidTy(Ctx),
                                     /*isVarArg=*/false);