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);
!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);
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
+}