diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 7aa7ecbe211d5..50332a7fe181f 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 OutputSemantic; + llvm::DenseMap> + 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,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(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(); auto AttrEnd = Decl->specific_attr_end(); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index f769fee227878..7cf4ed9a4f522 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 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(value.getPointer()); - return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca, - alloca->getAlign()); + auto Alloca = cast(value.Value); + return CGF.Builder.CreateAlignedLoad(value.Type, Alloca, Alloca->getAlign()); } } // end namespace CodeGen