Author: Jameson Nash
Date: 2026-03-09T21:34:57-04:00
New Revision: 29cb6f0147f9039edcb98246e85ff6fc51bea3a5

URL: 
https://github.com/llvm/llvm-project/commit/29cb6f0147f9039edcb98246e85ff6fc51bea3a5
DIFF: 
https://github.com/llvm/llvm-project/commit/29cb6f0147f9039edcb98246e85ff6fc51bea3a5.diff

LOG: [Clang] Track alloca element types to avoid getAllocatedType() calls 
(#181740)

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.

Co-authored-by: Claude Sonnet 4.5 <[email protected]>

Added: 
    

Modified: 
    clang/lib/CodeGen/CGHLSLRuntime.cpp
    clang/lib/CodeGen/CodeGenFunction.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index c1329ede7430f..7ce722c857409 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -951,7 +951,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()) {
@@ -959,7 +960,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;
     }
@@ -995,12 +996,14 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl 
*FD,
   CI->setCallingConv(Fn->getCallingConv());
 
   if (Fn->getReturnType() != CGM.VoidTy)
-    OutputSemantic.try_emplace(FD, CI);
+    // Element type is unused, so set to dummy value (NULL).
+    OutputSemantic.try_emplace(FD, std::make_pair(CI, 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 c3d470b179dcf..9771b89b55aae 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) {
@@ -5600,28 +5610,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 Alloca = cast<llvm::AllocaInst>(value.Value);
+  return CGF.Builder.CreateAlignedLoad(value.Type, Alloca, Alloca->getAlign());
 }
 
 } // end namespace CodeGen


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

Reply via email to