[clang] [Clang] Track alloca element types to avoid getAllocatedType() calls (PR #181740)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 16 12:33:06 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Jameson Nash (vtjnash)
<details>
<summary>Changes</summary>
Store alloca element types alongside alloca pointers in Clang's CodeGen, eliminating the need to query getAllocatedType() later.
Changes:
- CodeGenFunction.h: Modified DominatingLLVMValue::saved_type to track type Uses Type==nullptr as sentinel for "not saved" instead of separate bool. Fixes a bug where it previously tried to use the addrspacecasted value constructor and later cast it to an alloca.
- CGHLSLRuntime.cpp: Changed OutputSemantic map to store (Value*, Type*) pairs to trivially remove getAllocatedType calls.
---
Full diff: https://github.com/llvm/llvm-project/pull/181740.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+8-6)
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+24-13)
``````````diff
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 7aa7ecbe211d5..455d536fa40ca 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -948,7 +948,8 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
OB.emplace_back("convergencectrl", bundleArgs);
}
- llvm::DenseMap<const DeclaratorDecl *, llvm::Value *> OutputSemantic;
+ llvm::DenseMap<const DeclaratorDecl *, std::pair<llvm::Value *, llvm::Type *>>
+ OutputSemantic;
unsigned SRetOffset = 0;
for (const auto &Param : Fn->args()) {
@@ -956,7 +957,7 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
SRetOffset = 1;
llvm::Type *VarType = Param.getParamStructRetType();
llvm::Value *Var = B.CreateAlloca(VarType);
- OutputSemantic.try_emplace(FD, Var);
+ OutputSemantic.try_emplace(FD, std::make_pair(Var, VarType));
Args.push_back(Var);
continue;
}
@@ -992,12 +993,13 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
CI->setCallingConv(Fn->getCallingConv());
if (Fn->getReturnType() != CGM.VoidTy)
- OutputSemantic.try_emplace(FD, CI);
+ OutputSemantic.try_emplace(FD, std::make_pair(CI, /*unused*/ nullptr));
- for (auto &[Decl, Source] : OutputSemantic) {
+ for (auto &[Decl, SourcePair] : OutputSemantic) {
+ llvm::Value *Source = SourcePair.first;
+ llvm::Type *ElementType = SourcePair.second;
AllocaInst *AI = dyn_cast<AllocaInst>(Source);
- llvm::Value *SourceValue =
- AI ? B.CreateLoad(AI->getAllocatedType(), Source) : Source;
+ llvm::Value *SourceValue = AI ? B.CreateLoad(ElementType, Source) : Source;
auto AttrBegin = Decl->specific_attr_begin<HLSLAppliedSemanticAttr>();
auto AttrEnd = Decl->specific_attr_end<HLSLAppliedSemanticAttr>();
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index f769fee227878..f832f45bda129 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -119,7 +119,17 @@ enum TypeEvaluationKind {
/// Helper class with most of the code for saving a value for a
/// conditional expression cleanup.
struct DominatingLLVMValue {
- typedef llvm::PointerIntPair<llvm::Value *, 1, bool> saved_type;
+ struct saved_type {
+ llvm::Value *Value; // Original value if not saved, alloca if saved
+ llvm::Type *Type; // nullptr if not saved, element type if saved
+
+ saved_type() : Value(nullptr), Type(nullptr) {}
+ saved_type(llvm::Value *V) : Value(V), Type(nullptr) {}
+ saved_type(llvm::AllocaInst *Alloca, llvm::Type *Ty)
+ : Value(Alloca), Type(Ty) {}
+
+ bool isSaved() const { return Type != nullptr; }
+ };
/// Answer whether the given value needs extra work to be saved.
static bool needsSaving(llvm::Value *value) {
@@ -5590,28 +5600,29 @@ class CodeGenFunction : public CodeGenTypeCache {
inline DominatingLLVMValue::saved_type
DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) {
if (!needsSaving(value))
- return saved_type(value, false);
+ return saved_type(value);
// Otherwise, we need an alloca.
auto align = CharUnits::fromQuantity(
- CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType()));
- Address alloca =
- CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save");
- CGF.Builder.CreateStore(value, alloca);
-
- return saved_type(alloca.emitRawPointer(CGF), true);
+ CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType()))
+ .getAsAlign();
+ llvm::AllocaInst *AI =
+ CGF.CreateTempAlloca(value->getType(), "cond-cleanup.save");
+ AI->setAlignment(align);
+ CGF.Builder.CreateAlignedStore(value, AI, align);
+
+ return saved_type(AI, value->getType());
}
inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF,
saved_type value) {
// If the value says it wasn't saved, trust that it's still dominating.
- if (!value.getInt())
- return value.getPointer();
+ if (!value.isSaved())
+ return value.Value;
// Otherwise, it should be an alloca instruction, as set up in save().
- auto alloca = cast<llvm::AllocaInst>(value.getPointer());
- return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca,
- alloca->getAlign());
+ auto AI = cast<llvm::AllocaInst>(value.Value);
+ return CGF.Builder.CreateAlignedLoad(value.Type, AI, AI->getAlign());
}
} // end namespace CodeGen
``````````
</details>
https://github.com/llvm/llvm-project/pull/181740
More information about the cfe-commits
mailing list