================
@@ -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