[llvm] r275345 - [ConstantFolding] Extend FoldReinterpretLoadFromConstPtr to handle negative offsets
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 13 16:33:08 PDT 2016
Author: majnemer
Date: Wed Jul 13 18:33:07 2016
New Revision: 275345
URL: http://llvm.org/viewvc/llvm-project?rev=275345&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/Analysis/ConstantFolding.cpp
llvm/trunk/test/Transforms/InstSimplify/load.ll
Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=275345&r1=275344&r2=275345&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Jul 13 18:33:07 2016
@@ -442,8 +442,8 @@ Constant *FoldReinterpretLoadFromConstPt
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 *FoldReinterpretLoadFromConstPt
!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);
Modified: llvm/trunk/test/Transforms/InstSimplify/load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/load.ll?rev=275345&r1=275344&r2=275345&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/load.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/load.ll Wed Jul 13 18:33:07 2016
@@ -20,3 +20,11 @@ define i32 @crash_on_undef() {
ret i32 %load
}
+ at GV = private constant [8 x i32] [i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49]
+
+define <8 x i32> @partial_load() {
+; CHECK-LABEL: @partial_load(
+; CHECK: ret <8 x i32> <i32 0, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48>
+ %load = load <8 x i32>, <8 x i32>* bitcast (i32* getelementptr ([8 x i32], [8 x i32]* @GV, i64 0, i64 -1) to <8 x i32>*)
+ ret <8 x i32> %load
+}
More information about the llvm-commits
mailing list