diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-07-13 23:33:07 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-07-13 23:33:07 +0000 |
| commit | f89660aba78401fab81852c23437509796e8b5eb (patch) | |
| tree | 65ef0ca0862d2520aed5ffdb2b013502344625c4 /llvm/lib | |
| parent | d77a3b61eba36bdd4c9585e5dfa3f779194d21c4 (diff) | |
| download | bcm5719-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.cpp | 30 |
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); |

