[llvm] r314362 - Check for overflows when calculating the offset in GetGEPCost.
Justin Lebar via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 27 16:16:56 PDT 2017
Author: jlebar
Date: Wed Sep 27 16:16:56 2017
New Revision: 314362
URL: http://llvm.org/viewvc/llvm-project?rev=314362&view=rev
Log:
Check for overflows when calculating the offset in GetGEPCost.
Summary:
This avoids C++ UB if the GEP is weird and the calculation overflows
int64_t, and it's also observable in the cost model's results.
Such GEPs are almost surely not valid pointers, but LLVM nonetheless
generates them sometimes.
Reviewers: sanjoy
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D38337
Modified:
llvm/trunk/include/llvm/Analysis/TargetTransformInfoImpl.h
llvm/trunk/test/Analysis/CostModel/X86/gep.ll
Modified: llvm/trunk/include/llvm/Analysis/TargetTransformInfoImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetTransformInfoImpl.h?rev=314362&r1=314361&r2=314362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/TargetTransformInfoImpl.h (original)
+++ llvm/trunk/include/llvm/Analysis/TargetTransformInfoImpl.h Wed Sep 27 16:16:56 2017
@@ -674,7 +674,9 @@ public:
BaseGV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts());
}
bool HasBaseReg = (BaseGV == nullptr);
- int64_t BaseOffset = 0;
+
+ auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());
+ APInt BaseOffset(PtrSizeBits, 0);
int64_t Scale = 0;
auto GTI = gep_type_begin(PointeeType, Operands);
@@ -700,9 +702,10 @@ public:
BaseOffset += DL.getStructLayout(STy)->getElementOffset(Field);
} else {
int64_t ElementSize = DL.getTypeAllocSize(GTI.getIndexedType());
- if (ConstIdx)
- BaseOffset += ConstIdx->getSExtValue() * ElementSize;
- else {
+ if (ConstIdx) {
+ BaseOffset +=
+ ConstIdx->getValue().sextOrTrunc(PtrSizeBits) * ElementSize;
+ } else {
// Needs scale register.
if (Scale != 0)
// No addressing mode takes two scale registers.
@@ -716,8 +719,9 @@ public:
unsigned AS =
(Ptr == nullptr ? 0 : Ptr->getType()->getPointerAddressSpace());
if (static_cast<T *>(this)->isLegalAddressingMode(
- TargetType, const_cast<GlobalValue *>(BaseGV), BaseOffset,
- HasBaseReg, Scale, AS))
+ TargetType, const_cast<GlobalValue *>(BaseGV),
+ static_cast<int64_t>(BaseOffset.getLimitedValue()), HasBaseReg,
+ Scale, AS))
return TTI::TCC_Free;
return TTI::TCC_Basic;
}
Modified: llvm/trunk/test/Analysis/CostModel/X86/gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/CostModel/X86/gep.ll?rev=314362&r1=314361&r2=314362&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/CostModel/X86/gep.ll (original)
+++ llvm/trunk/test/Analysis/CostModel/X86/gep.ll Wed Sep 27 16:16:56 2017
@@ -35,6 +35,17 @@ define void @test_geps() {
;CHECK: cost of 0 for instruction: {{.*}} getelementptr inbounds <4 x double>, <4 x double>*
%a12 = getelementptr inbounds <4 x double>, <4 x double>* undef, i32 0
+ ; Check that we handle outlandishly large GEPs properly. This is unlikely to
+ ; be a valid pointer, but LLVM still generates GEPs like this sometimes in
+ ; dead code.
+ ;
+ ; This GEP has index INT64_MAX, which is cost 1.
+;CHECK: cost of 1 for instruction: {{.*}} getelementptr inbounds i8, i8*
+ %giant_gep0 = getelementptr inbounds i8, i8* undef, i64 9223372036854775807
+
+ ; This GEP index wraps around to -1, which is cost 0.
+;CHECK: cost of 0 for instruction: {{.*}} getelementptr inbounds i8, i8*
+ %giant_gep1 = getelementptr inbounds i8, i8* undef, i128 295147905179352825855
ret void
}
More information about the llvm-commits
mailing list