================
@@ -47,6 +50,95 @@ static Value *emitAMDGPUSBufferLoadBuiltin(CodeGenFunction 
&CGF,
                                     CGF.EmitScalarExpr(E->getArg(2))});
 }
 
+constexpr char AMDGPUConstantSectionMarker[] =
+    "__clang_amdgpu_constant_section_marker";
+
+static llvm::GlobalVariable *
+getAMDGPUConstantSectionBoundary(CodeGenModule &CGM, StringRef Name,
+                                 SourceLocation Loc) {
+  llvm::Module &M = CGM.getModule();
+  auto *Int8Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+
+  if (auto *V = M.getNamedValue(Name)) {
+    auto *GV = dyn_cast<llvm::GlobalVariable>(V);
+    if (GV && GV->isDeclaration() && GV->hasExternalLinkage() &&
+        GV->getAddressSpace() == llvm::AMDGPUAS::CONSTANT_ADDRESS &&
+        GV->getValueType() == Int8Ty)
+      return GV;
+
+    std::string Message = "AMDGPU constant section boundary symbol '";
+    Message += Name;
+    Message += "' conflicts with existing symbol";
+    CGM.Error(Loc, Message);
+    return nullptr;
+  }
+
+  return new llvm::GlobalVariable(
+      M, Int8Ty, /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage,
+      /*Initializer=*/nullptr, Name, /*InsertBefore=*/nullptr,
+      llvm::GlobalVariable::NotThreadLocal, llvm::AMDGPUAS::CONSTANT_ADDRESS);
+}
+
+static void ensureAMDGPUConstantSection(CodeGenModule &CGM,
+                                        StringRef ConstantSection) {
+  if (auto *GV = CGM.getModule().getNamedGlobal(AMDGPUConstantSectionMarker))
+    if (GV->getSection() == ConstantSection)
+      return;
+
+  auto *Int8Ty = llvm::Type::getInt8Ty(CGM.getLLVMContext());
+  auto *MarkerTy = llvm::ArrayType::get(Int8Ty, 0);
+  auto *Marker = new llvm::GlobalVariable(
+      CGM.getModule(), MarkerTy, /*isConstant=*/true,
+      llvm::GlobalValue::InternalLinkage,
+      llvm::ConstantAggregateZero::get(MarkerTy), AMDGPUConstantSectionMarker,
+      /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal,
+      llvm::AMDGPUAS::CONSTANT_ADDRESS);
+  Marker->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+  Marker->setSection(ConstantSection);
+  CGM.addCompilerUsedGlobal(Marker);
+}
+
+static std::string getAMDGPUConstantSectionStartSymbol(StringRef Section) {
+  // AMDGPU uses an ELF section name chosen to support GNU-style 
linker-provided
+  // __start_<section> and __stop_<section> range boundary symbols.
+  return ("__start_" + Section).str();
+}
+
+static std::string getAMDGPUConstantSectionStopSymbol(StringRef Section) {
+  return ("__stop_" + Section).str();
+}
+
+static Value *emitAMDGPUIsConstant(CodeGenFunction &CGF, const CallExpr *E) {
+  Value *Ptr = CGF.EmitScalarExpr(E->getArg(0));
+
+  if (!CGF.CGM.getTriple().isAMDGCN())
+    return CGF.Builder.getFalse();
+  std::optional<StringRef> ConstantSection =
+      CGF.CGM.getTarget().getConstantAddressSpaceSectionName();
+  if (!ConstantSection)
+    return CGF.Builder.getFalse();
+
+  ensureAMDGPUConstantSection(CGF.CGM, *ConstantSection);
+
+  Value *PtrInt = CGF.Builder.CreatePtrToInt(Ptr, CGF.IntPtrTy);
+
+  std::string StartName = 
getAMDGPUConstantSectionStartSymbol(*ConstantSection);
+  std::string StopName = getAMDGPUConstantSectionStopSymbol(*ConstantSection);
+  auto *Start =
+      getAMDGPUConstantSectionBoundary(CGF.CGM, StartName, E->getExprLoc());
+  auto *Stop =
+      getAMDGPUConstantSectionBoundary(CGF.CGM, StopName, E->getExprLoc());
+  if (!Start || !Stop)
+    return CGF.Builder.getFalse();
+
+  Value *StartInt = CGF.Builder.CreatePtrToInt(Start, CGF.IntPtrTy);
+  Value *StopInt = CGF.Builder.CreatePtrToInt(Stop, CGF.IntPtrTy);
+
+  Value *Offset = CGF.Builder.CreateSub(PtrInt, StartInt);
+  Value *Size = CGF.Builder.CreateSub(StopInt, StartInt);
+  return CGF.Builder.CreateICmpULT(Offset, Size);
----------------
arsenm wrote:

CreatePtrDiff 

https://github.com/llvm/llvm-project/pull/209679
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to