[llvm] r365468 - OpaquePtr: add Type parameter to Loads analysis API.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 9 04:35:35 PDT 2019
Author: tnorthover
Date: Tue Jul 9 04:35:35 2019
New Revision: 365468
URL: http://llvm.org/viewvc/llvm-project?rev=365468&view=rev
Log:
OpaquePtr: add Type parameter to Loads analysis API.
This makes the functions in Loads.h require a type to be specified
independently of the pointer Value so that when pointers have no structure
other than address-space, it can still do its job.
Most callers had an obvious memory operation handy to provide this type, but a
SROA and ArgumentPromotion were doing more complicated analysis. They get
updated to merge the properties of the various instructions they were
considering.
Modified:
llvm/trunk/include/llvm/Analysis/Loads.h
llvm/trunk/lib/Analysis/Loads.cpp
llvm/trunk/lib/Analysis/MemDerefPrinter.cpp
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
llvm/trunk/lib/Transforms/Scalar/LICM.cpp
llvm/trunk/lib/Transforms/Scalar/MergeICmps.cpp
llvm/trunk/lib/Transforms/Scalar/SROA.cpp
llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
Modified: llvm/trunk/include/llvm/Analysis/Loads.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Loads.h?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/Loads.h (original)
+++ llvm/trunk/include/llvm/Analysis/Loads.h Tue Jul 9 04:35:35 2019
@@ -25,7 +25,8 @@ class MDNode;
/// Return true if this is always a dereferenceable pointer. If the context
/// instruction is specified perform context-sensitive analysis and return true
/// if the pointer is dereferenceable at the specified instruction.
-bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
+bool isDereferenceablePointer(const Value *V, Type *Ty,
+ const DataLayout &DL,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
@@ -33,8 +34,8 @@ bool isDereferenceablePointer(const Valu
/// greater or equal than requested. If the context instruction is specified
/// performs context-sensitive analysis and returns true if the pointer is
/// dereferenceable at the specified instruction.
-bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
- const DataLayout &DL,
+bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty,
+ unsigned Align, const DataLayout &DL,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
@@ -55,7 +56,20 @@ bool isDereferenceableAndAlignedPointer(
/// If it is not obviously safe to load from the specified pointer, we do a
/// quick local scan of the basic block containing ScanFrom, to determine if
/// the address is already accessed.
-bool isSafeToLoadUnconditionally(Value *V, unsigned Align,
+bool isSafeToLoadUnconditionally(Value *V, unsigned Align, APInt &Size,
+ const DataLayout &DL,
+ Instruction *ScanFrom = nullptr,
+ const DominatorTree *DT = nullptr);
+
+/// Return true if we know that executing a load from this value cannot trap.
+///
+/// If DT and ScanFrom are specified this method performs context-sensitive
+/// analysis and returns true if it is safe to load immediately before ScanFrom.
+///
+/// If it is not obviously safe to load from the specified pointer, we do a
+/// quick local scan of the basic block containing ScanFrom, to determine if
+/// the address is already accessed.
+bool isSafeToLoadUnconditionally(Value *V, Type *Ty, unsigned Align,
const DataLayout &DL,
Instruction *ScanFrom = nullptr,
const DominatorTree *DT = nullptr);
Modified: llvm/trunk/lib/Analysis/Loads.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Loads.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Loads.cpp (original)
+++ llvm/trunk/lib/Analysis/Loads.cpp Tue Jul 9 04:35:35 2019
@@ -125,7 +125,8 @@ bool llvm::isDereferenceableAndAlignedPo
Visited);
}
-bool llvm::isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
+bool llvm::isDereferenceableAndAlignedPointer(const Value *V, Type *Ty,
+ unsigned Align,
const DataLayout &DL,
const Instruction *CtxI,
const DominatorTree *DT) {
@@ -133,8 +134,6 @@ bool llvm::isDereferenceableAndAlignedPo
// attribute, we know exactly how many bytes are dereferenceable. If we can
// determine the exact offset to the attributed variable, we can use that
// information here.
- Type *VTy = V->getType();
- Type *Ty = VTy->getPointerElementType();
// Require ABI alignment for loads without alignment specification
if (Align == 0)
@@ -145,14 +144,16 @@ bool llvm::isDereferenceableAndAlignedPo
SmallPtrSet<const Value *, 32> Visited;
return ::isDereferenceableAndAlignedPointer(
- V, Align, APInt(DL.getIndexTypeSizeInBits(VTy), DL.getTypeStoreSize(Ty)), DL,
- CtxI, DT, Visited);
+ V, Align,
+ APInt(DL.getIndexTypeSizeInBits(V->getType()), DL.getTypeStoreSize(Ty)),
+ DL, CtxI, DT, Visited);
}
-bool llvm::isDereferenceablePointer(const Value *V, const DataLayout &DL,
+bool llvm::isDereferenceablePointer(const Value *V, Type *Ty,
+ const DataLayout &DL,
const Instruction *CtxI,
const DominatorTree *DT) {
- return isDereferenceableAndAlignedPointer(V, 1, DL, CtxI, DT);
+ return isDereferenceableAndAlignedPointer(V, Ty, 1, DL, CtxI, DT);
}
/// Test if A and B will obviously have the same value.
@@ -197,7 +198,7 @@ static bool AreEquivalentAddressValues(c
///
/// This uses the pointee type to determine how many bytes need to be safe to
/// load from the pointer.
-bool llvm::isSafeToLoadUnconditionally(Value *V, unsigned Align,
+bool llvm::isSafeToLoadUnconditionally(Value *V, unsigned Align, APInt &Size,
const DataLayout &DL,
Instruction *ScanFrom,
const DominatorTree *DT) {
@@ -208,7 +209,7 @@ bool llvm::isSafeToLoadUnconditionally(V
// If DT is not specified we can't make context-sensitive query
const Instruction* CtxI = DT ? ScanFrom : nullptr;
- if (isDereferenceableAndAlignedPointer(V, Align, DL, CtxI, DT))
+ if (isDereferenceableAndAlignedPointer(V, Align, Size, DL, CtxI, DT))
return true;
int64_t ByteOffset = 0;
@@ -313,7 +314,15 @@ bool llvm::isSafeToLoadUnconditionally(V
return false;
}
-/// DefMaxInstsToScan - the default number of maximum instructions
+bool llvm::isSafeToLoadUnconditionally(Value *V, Type *Ty, unsigned Align,
+ const DataLayout &DL,
+ Instruction *ScanFrom,
+ const DominatorTree *DT) {
+ APInt Size(DL.getIndexTypeSizeInBits(V->getType()), DL.getTypeStoreSize(Ty));
+ return isSafeToLoadUnconditionally(V, Align, Size, DL, ScanFrom, DT);
+}
+
+ /// DefMaxInstsToScan - the default number of maximum instructions
/// to scan in the block, used by FindAvailableLoadedValue().
/// FindAvailableLoadedValue() was introduced in r60148, to improve jump
/// threading in part by eliminating partially redundant loads.
Modified: llvm/trunk/lib/Analysis/MemDerefPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemDerefPrinter.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemDerefPrinter.cpp (original)
+++ llvm/trunk/lib/Analysis/MemDerefPrinter.cpp Tue Jul 9 04:35:35 2019
@@ -53,9 +53,10 @@ bool MemDerefPrinter::runOnFunction(Func
for (auto &I: instructions(F)) {
if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
Value *PO = LI->getPointerOperand();
- if (isDereferenceablePointer(PO, DL))
+ if (isDereferenceablePointer(PO, LI->getType(), DL))
Deref.push_back(PO);
- if (isDereferenceableAndAlignedPointer(PO, LI->getAlignment(), DL))
+ if (isDereferenceableAndAlignedPointer(PO, LI->getType(),
+ LI->getAlignment(), DL))
DerefAndAligned.insert(PO);
}
}
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Jul 9 04:35:35 2019
@@ -3949,7 +3949,8 @@ bool llvm::isSafeToSpeculativelyExecute(
return false;
const DataLayout &DL = LI->getModule()->getDataLayout();
return isDereferenceableAndAlignedPointer(LI->getPointerOperand(),
- LI->getAlignment(), DL, CtxI, DT);
+ LI->getType(), LI->getAlignment(),
+ DL, CtxI, DT);
}
case Instruction::Call: {
auto *CI = cast<const CallInst>(Inst);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Jul 9 04:35:35 2019
@@ -4004,7 +4004,8 @@ void SelectionDAGBuilder::visitLoad(cons
bool isVolatile = I.isVolatile();
bool isNonTemporal = I.getMetadata(LLVMContext::MD_nontemporal) != nullptr;
bool isInvariant = I.getMetadata(LLVMContext::MD_invariant_load) != nullptr;
- bool isDereferenceable = isDereferenceablePointer(SV, DAG.getDataLayout());
+ bool isDereferenceable =
+ isDereferenceablePointer(SV, I.getType(), DAG.getDataLayout());
unsigned Alignment = I.getAlignment();
AAMDNodes AAInfo;
@@ -4629,7 +4630,8 @@ void SelectionDAGBuilder::visitAtomicLoa
Flags |= MachineMemOperand::MOVolatile;
if (I.getMetadata(LLVMContext::MD_invariant_load) != nullptr)
Flags |= MachineMemOperand::MOInvariant;
- if (isDereferenceablePointer(I.getPointerOperand(), DAG.getDataLayout()))
+ if (isDereferenceablePointer(I.getPointerOperand(), I.getType(),
+ DAG.getDataLayout()))
Flags |= MachineMemOperand::MODereferenceable;
Flags |= TLI.getMMOFlags(I);
Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Tue Jul 9 04:35:35 2019
@@ -479,9 +479,9 @@ doPromotion(Function *F, SmallPtrSetImpl
return NF;
}
-/// AllCallersPassInValidPointerForArgument - Return true if we can prove that
-/// all callees pass in a valid pointer for the specified function argument.
-static bool allCallersPassInValidPointerForArgument(Argument *Arg) {
+/// Return true if we can prove that all callees pass in a valid pointer for the
+/// specified function argument.
+static bool allCallersPassValidPointerForArgument(Argument *Arg, Type *Ty) {
Function *Callee = Arg->getParent();
const DataLayout &DL = Callee->getParent()->getDataLayout();
@@ -493,7 +493,7 @@ static bool allCallersPassInValidPointer
CallSite CS(U);
assert(CS && "Should only have direct calls!");
- if (!isDereferenceablePointer(CS.getArgument(ArgNo), DL))
+ if (!isDereferenceablePointer(CS.getArgument(ArgNo), Ty, DL))
return false;
}
return true;
@@ -566,7 +566,7 @@ static void markIndicesSafe(const Indice
/// This method limits promotion of aggregates to only promote up to three
/// elements of the aggregate in order to avoid exploding the number of
/// arguments passed in.
-static bool isSafeToPromoteArgument(Argument *Arg, bool isByVal, AAResults &AAR,
+static bool isSafeToPromoteArgument(Argument *Arg, Type *ByValTy, AAResults &AAR,
unsigned MaxElements) {
using GEPIndicesSet = std::set<IndicesVector>;
@@ -596,9 +596,28 @@ static bool isSafeToPromoteArgument(Argu
GEPIndicesSet ToPromote;
// If the pointer is always valid, any load with first index 0 is valid.
- if (isByVal || allCallersPassInValidPointerForArgument(Arg))
+
+ if (ByValTy)
SafeToUnconditionallyLoad.insert(IndicesVector(1, 0));
+ // Whenever a new underlying type for the operand is found, make sure it's
+ // consistent with the GEPs and loads we've already seen and, if necessary,
+ // use it to see if all incoming pointers are valid (which implies the 0-index
+ // is safe).
+ Type *BaseTy = ByValTy;
+ auto UpdateBaseTy = [&](Type *NewBaseTy) {
+ if (BaseTy)
+ return BaseTy == NewBaseTy;
+
+ BaseTy = NewBaseTy;
+ if (allCallersPassValidPointerForArgument(Arg, BaseTy)) {
+ assert(SafeToUnconditionallyLoad.empty());
+ SafeToUnconditionallyLoad.insert(IndicesVector(1, 0));
+ }
+
+ return true;
+ };
+
// First, iterate the entry block and mark loads of (geps of) arguments as
// safe.
BasicBlock &EntryBlock = Arg->getParent()->front();
@@ -621,6 +640,9 @@ static bool isSafeToPromoteArgument(Argu
// right away, can't promote this argument at all.
return false;
+ if (!UpdateBaseTy(GEP->getSourceElementType()))
+ return false;
+
// Indices checked out, mark them as safe
markIndicesSafe(Indices, SafeToUnconditionallyLoad);
Indices.clear();
@@ -628,6 +650,11 @@ static bool isSafeToPromoteArgument(Argu
} else if (V == Arg) {
// Direct loads are equivalent to a GEP with a single 0 index.
markIndicesSafe(IndicesVector(1, 0), SafeToUnconditionallyLoad);
+
+ if (BaseTy && LI->getType() != BaseTy)
+ return false;
+
+ BaseTy = LI->getType();
}
}
@@ -645,6 +672,9 @@ static bool isSafeToPromoteArgument(Argu
Loads.push_back(LI);
// Direct loads are equivalent to a GEP with a zero index and then a load.
Operands.push_back(0);
+
+ if (!UpdateBaseTy(LI->getType()))
+ return false;
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(UR)) {
if (GEP->use_empty()) {
// Dead GEP's cause trouble later. Just remove them if we run into
@@ -653,9 +683,12 @@ static bool isSafeToPromoteArgument(Argu
// TODO: This runs the above loop over and over again for dead GEPs
// Couldn't we just do increment the UI iterator earlier and erase the
// use?
- return isSafeToPromoteArgument(Arg, isByVal, AAR, MaxElements);
+ return isSafeToPromoteArgument(Arg, ByValTy, AAR, MaxElements);
}
+ if (!UpdateBaseTy(GEP->getSourceElementType()))
+ return false;
+
// Ensure that all of the indices are constants.
for (User::op_iterator i = GEP->idx_begin(), e = GEP->idx_end(); i != e;
++i)
@@ -966,8 +999,9 @@ promoteArguments(Function *F, function_r
}
// Otherwise, see if we can promote the pointer to its value.
- if (isSafeToPromoteArgument(PtrArg, PtrArg->hasByValAttr(), AAR,
- MaxElements))
+ Type *ByValTy =
+ PtrArg->hasByValAttr() ? PtrArg->getParamByValType() : nullptr;
+ if (isSafeToPromoteArgument(PtrArg, ByValTy, AAR, MaxElements))
ArgsToPromote.insert(PtrArg);
}
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Tue Jul 9 04:35:35 2019
@@ -1060,7 +1060,7 @@ Value *InstCombiner::simplifyMaskedLoad(
// If we can unconditionally load from this address, replace with a
// load/select idiom. TODO: use DT for context sensitive query
- if (isDereferenceableAndAlignedPointer(LoadPtr, Alignment,
+ if (isDereferenceableAndAlignedPointer(LoadPtr, II.getType(), Alignment,
II.getModule()->getDataLayout(),
&II, nullptr)) {
Value *LI = Builder.CreateAlignedLoad(II.getType(), LoadPtr, Alignment,
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Tue Jul 9 04:35:35 2019
@@ -1064,8 +1064,10 @@ Instruction *InstCombiner::visitLoadInst
if (SelectInst *SI = dyn_cast<SelectInst>(Op)) {
// load (select (Cond, &V1, &V2)) --> select(Cond, load &V1, load &V2).
unsigned Align = LI.getAlignment();
- if (isSafeToLoadUnconditionally(SI->getOperand(1), Align, DL, SI) &&
- isSafeToLoadUnconditionally(SI->getOperand(2), Align, DL, SI)) {
+ if (isSafeToLoadUnconditionally(SI->getOperand(1), LI.getType(), Align,
+ DL, SI) &&
+ isSafeToLoadUnconditionally(SI->getOperand(2), LI.getType(), Align,
+ DL, SI)) {
LoadInst *V1 =
Builder.CreateLoad(LI.getType(), SI->getOperand(1),
SI->getOperand(1)->getName() + ".val");
Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Tue Jul 9 04:35:35 2019
@@ -2016,8 +2016,8 @@ bool llvm::promoteLoopAccessesToScalars(
// deref info through it.
if (!DereferenceableInPH) {
DereferenceableInPH = isDereferenceableAndAlignedPointer(
- Store->getPointerOperand(), Store->getAlignment(), MDL,
- Preheader->getTerminator(), DT);
+ Store->getPointerOperand(), Store->getValueOperand()->getType(),
+ Store->getAlignment(), MDL, Preheader->getTerminator(), DT);
}
} else
return false; // Not a load or store.
Modified: llvm/trunk/lib/Transforms/Scalar/MergeICmps.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MergeICmps.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/MergeICmps.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/MergeICmps.cpp Tue Jul 9 04:35:35 2019
@@ -162,7 +162,7 @@ BCEAtom visitICmpLoadOperand(Value *cons
return {};
}
const auto &DL = GEP->getModule()->getDataLayout();
- if (!isDereferenceablePointer(GEP, DL)) {
+ if (!isDereferenceablePointer(GEP, LoadI->getType(), DL)) {
LLVM_DEBUG(dbgs() << "not dereferenceable\n");
// We need to make sure that we can do comparison in any order, so we
// require memory to be unconditionnally dereferencable.
Modified: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Tue Jul 9 04:35:35 2019
@@ -1190,12 +1190,16 @@ static Type *findCommonType(AllocaSlices
/// FIXME: This should be hoisted into a generic utility, likely in
/// Transforms/Util/Local.h
static bool isSafePHIToSpeculate(PHINode &PN) {
+ const DataLayout &DL = PN.getModule()->getDataLayout();
+
// For now, we can only do this promotion if the load is in the same block
// as the PHI, and if there are no stores between the phi and load.
// TODO: Allow recursive phi users.
// TODO: Allow stores.
BasicBlock *BB = PN.getParent();
unsigned MaxAlign = 0;
+ uint64_t APWidth = DL.getIndexTypeSizeInBits(PN.getType());
+ APInt MaxSize(APWidth, 0);
bool HaveLoad = false;
for (User *U : PN.users()) {
LoadInst *LI = dyn_cast<LoadInst>(U);
@@ -1214,15 +1218,15 @@ static bool isSafePHIToSpeculate(PHINode
if (BBI->mayWriteToMemory())
return false;
+ uint64_t Size = DL.getTypeStoreSizeInBits(LI->getType());
MaxAlign = std::max(MaxAlign, LI->getAlignment());
+ MaxSize = MaxSize.ult(Size) ? APInt(APWidth, Size) : MaxSize;
HaveLoad = true;
}
if (!HaveLoad)
return false;
- const DataLayout &DL = PN.getModule()->getDataLayout();
-
// We can only transform this if it is safe to push the loads into the
// predecessor blocks. The only thing to watch out for is that we can't put
// a possibly trapping load in the predecessor if it is a critical edge.
@@ -1244,7 +1248,7 @@ static bool isSafePHIToSpeculate(PHINode
// If this pointer is always safe to load, or if we can prove that there
// is already a load in the block, then we can move the load to the pred
// block.
- if (isSafeToLoadUnconditionally(InVal, MaxAlign, DL, TI))
+ if (isSafeToLoadUnconditionally(InVal, MaxAlign, MaxSize, DL, TI))
continue;
return false;
@@ -1334,9 +1338,11 @@ static bool isSafeSelectToSpeculate(Sele
// Both operands to the select need to be dereferenceable, either
// absolutely (e.g. allocas) or at this point because we can see other
// accesses to it.
- if (!isSafeToLoadUnconditionally(TValue, LI->getAlignment(), DL, LI))
+ if (!isSafeToLoadUnconditionally(TValue, LI->getType(), LI->getAlignment(),
+ DL, LI))
return false;
- if (!isSafeToLoadUnconditionally(FValue, LI->getAlignment(), DL, LI))
+ if (!isSafeToLoadUnconditionally(FValue, LI->getType(), LI->getAlignment(),
+ DL, LI))
return false;
}
Modified: llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=365468&r1=365467&r2=365468&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp Tue Jul 9 04:35:35 2019
@@ -340,7 +340,7 @@ static bool canMoveAboveCall(Instruction
// being loaded from.
const DataLayout &DL = L->getModule()->getDataLayout();
if (isModSet(AA->getModRefInfo(CI, MemoryLocation::get(L))) ||
- !isSafeToLoadUnconditionally(L->getPointerOperand(),
+ !isSafeToLoadUnconditionally(L->getPointerOperand(), L->getType(),
L->getAlignment(), DL, L))
return false;
}
More information about the llvm-commits
mailing list