summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-07-13 23:33:07 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-07-13 23:33:07 +0000
commitf89660aba78401fab81852c23437509796e8b5eb (patch)
tree65ef0ca0862d2520aed5ffdb2b013502344625c4 /llvm/lib
parentd77a3b61eba36bdd4c9585e5dfa3f779194d21c4 (diff)
downloadbcm5719-llvm-f89660aba78401fab81852c23437509796e8b5eb.tar.gz
bcm5719-llvm-f89660aba78401fab81852c23437509796e8b5eb.zip
[ConstantFolding] Extend FoldReinterpretLoadFromConstPtr to handle negative offsets
Treat loads which clip before the start of a global initializer the same way we treat clipping beyond the end of the initializer: use zeros. llvm-svn: 275345
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp30
1 files changed, 20 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 73bdd99fcc9..dcfe700bf94 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -442,8 +442,8 @@ Constant *FoldReinterpretLoadFromConstPtr(Constant *C, Type *LoadTy,
return nullptr;
GlobalValue *GVal;
- APInt Offset;
- if (!IsConstantOffsetFromGlobal(C, GVal, Offset, DL))
+ APInt OffsetAI;
+ if (!IsConstantOffsetFromGlobal(C, GVal, OffsetAI, DL))
return nullptr;
auto *GV = dyn_cast<GlobalVariable>(GVal);
@@ -451,19 +451,29 @@ Constant *FoldReinterpretLoadFromConstPtr(Constant *C, Type *LoadTy,
!GV->getInitializer()->getType()->isSized())
return nullptr;
- // If we're loading off the beginning of the global, some bytes may be valid,
- // but we don't try to handle this.
- if (Offset.isNegative())
- return nullptr;
+ int64_t Offset = OffsetAI.getSExtValue();
+ int64_t InitializerSize = DL.getTypeAllocSize(GV->getInitializer()->getType());
+
+ // If we're not accessing anything in this constant, the result is undefined.
+ if (Offset + BytesLoaded <= 0)
+ return UndefValue::get(IntType);
// If we're not accessing anything in this constant, the result is undefined.
- if (Offset.getZExtValue() >=
- DL.getTypeAllocSize(GV->getInitializer()->getType()))
+ if (Offset >= InitializerSize)
return UndefValue::get(IntType);
unsigned char RawBytes[32] = {0};
- if (!ReadDataFromGlobal(GV->getInitializer(), Offset.getZExtValue(), RawBytes,
- BytesLoaded, DL))
+ unsigned char *CurPtr = RawBytes;
+ unsigned BytesLeft = BytesLoaded;
+
+ // If we're loading off the beginning of the global, some bytes may be valid.
+ if (Offset < 0) {
+ CurPtr += -Offset;
+ BytesLeft += Offset;
+ Offset = 0;
+ }
+
+ if (!ReadDataFromGlobal(GV->getInitializer(), Offset, CurPtr, BytesLeft, DL))
return nullptr;
APInt ResultVal = APInt(IntType->getBitWidth(), 0);
OpenPOWER on IntegriCloud