forked from OSchip/llvm-project
[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
This commit is contained in:
parent
d77a3b61eb
commit
f89660aba7
|
@ -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.getZExtValue() >=
|
||||
DL.getTypeAllocSize(GV->getInitializer()->getType()))
|
||||
if (Offset + BytesLoaded <= 0)
|
||||
return UndefValue::get(IntType);
|
||||
|
||||
// If we're not accessing anything in this constant, the result is undefined.
|
||||
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);
|
||||
|
|
|
@ -20,3 +20,11 @@ define i32 @crash_on_undef() {
|
|||
ret i32 %load
|
||||
}
|
||||
|
||||
@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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue