diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp --- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -39,6 +39,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" @@ -599,17 +600,38 @@ less_first()); Value *ReplVal; if (I == StoresByIndex.begin()) { - if (StoresByIndex.empty()) - // If there are no stores, the load takes the undef value. - ReplVal = getInitialValueOfAllocation(AI, nullptr, LI->getType()).second; - else + if (StoresByIndex.empty()) { + // If there are no stores, the load may take a poison or freeze poison + // value value. + auto [QueryEnum, QueryReplVal] = + getInitialValueOfAllocation(AI, nullptr, LI->getType(), LI); + switch (QueryEnum) { + case InitializationCategory::Unknown: + return false; + break; + case InitializationCategory::Constant: + ReplVal = QueryReplVal; + break; + case InitializationCategory::FreezePoison: + IRBuilder<> Builder(LI); + ReplVal = + Builder.CreateFreeze(PoisonValue::get(LI->getType()), "freeze"); + break; + } + } else { // There is no store before this load, bail out (load may be affected // by the following stores - see main comment). return false; + } } else { // Otherwise, there was a store before this load, the load takes its // value. ReplVal = std::prev(I)->second->getOperand(0); + if (!loadHasFreezeBits(dyn_cast(ReplVal)) && + loadHasFreezeBits(LI)) { + IRBuilder<> Builder(LI); + ReplVal = Builder.CreateFreeze(ReplVal, "freeze"); + } } convertMetadataToAssumes(LI, ReplVal, DL, AC, &DT); @@ -762,7 +784,7 @@ // been stored yet. In this case, it will get this null value. RenamePassData::ValVector Values(Allocas.size()); for (unsigned i = 0, e = Allocas.size(); i != e; ++i) - Values[i] = UndefValue::get(Allocas[i]->getAllocatedType()); + Values[i] = PoisonValue::get(Allocas[i]->getAllocatedType()); // When handling debug info, treat all incoming values as if they have unknown // locations until proven otherwise. @@ -1078,6 +1100,10 @@ convertMetadataToAssumes(LI, V, SQ.DL, AC, &DT); // Anything using the load now uses the current value. + if (loadHasFreezeBits(LI)) { + IRBuilder<> Builder(LI); + V = Builder.CreateFreeze(V, "freeze.load"); + } LI->replaceAllUsesWith(V); LI->eraseFromParent(); } else if (StoreInst *SI = dyn_cast(I)) {