[llvm-commits] [PATCH] Patch to fix bug14172
Micah Villmow
villmow at gmail.com
Tue Oct 30 15:44:35 PDT 2012
http://llvm.org/bugs/show_bug.cgi?id=14172
Null Pointers to structures that have all the types the same are loosing their address space when going through the constant folder. This patch fixes this specific case. A more robust approach needs to be implemented that allows Constant/ConstantFolder to take into account the address space.
http://llvm-reviews.chandlerc.com/D88
Files:
lib/VMCore/ConstantFold.cpp
lib/VMCore/Constants.cpp
include/llvm/Constants.h
Index: lib/VMCore/ConstantFold.cpp
===================================================================
--- lib/VMCore/ConstantFold.cpp
+++ lib/VMCore/ConstantFold.cpp
@@ -334,10 +334,10 @@
/// bouncing an unfoldable expression back into the top-level folder.
///
static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy,
- bool Folded) {
+ bool Folded, unsigned AS) {
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Constant *N = ConstantInt::get(DestTy, ATy->getNumElements());
- Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+ Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true, AS);
return ConstantExpr::getNUWMul(E, N);
}
@@ -349,11 +349,11 @@
return ConstantExpr::getNullValue(DestTy);
// Check for a struct with all members having the same size.
Constant *MemberSize =
- getFoldedSizeOf(STy->getElementType(0), DestTy, true);
+ getFoldedSizeOf(STy->getElementType(0), DestTy, true, AS);
bool AllSame = true;
for (unsigned i = 1; i != NumElems; ++i)
if (MemberSize !=
- getFoldedSizeOf(STy->getElementType(i), DestTy, true)) {
+ getFoldedSizeOf(STy->getElementType(i), DestTy, true, AS)) {
AllSame = false;
break;
}
@@ -368,9 +368,8 @@
if (PointerType *PTy = dyn_cast<PointerType>(Ty))
if (!PTy->getElementType()->isIntegerTy(1))
return
- getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1),
- PTy->getAddressSpace()),
- DestTy, true);
+ getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1), AS),
+ DestTy, true, AS);
// If there's no interesting folding happening, bail so that we don't create
// a constant that looks like it needs folding but really doesn't.
@@ -378,7 +377,7 @@
return 0;
// Base case: Get a regular sizeof expression.
- Constant *C = ConstantExpr::getSizeOf(Ty);
+ Constant *C = ConstantExpr::getSizeOf(Ty, AS);
C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
DestTy, false),
C, DestTy);
@@ -458,12 +457,12 @@
///
static Constant *getFoldedOffsetOf(Type *Ty, Constant *FieldNo,
Type *DestTy,
- bool Folded) {
+ bool Folded, unsigned AS) {
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo, false,
DestTy, false),
FieldNo, DestTy);
- Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+ Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true, AS);
return ConstantExpr::getNUWMul(E, N);
}
@@ -475,11 +474,11 @@
return 0;
// Check for a struct with all members having the same size.
Constant *MemberSize =
- getFoldedSizeOf(STy->getElementType(0), DestTy, true);
+ getFoldedSizeOf(STy->getElementType(0), DestTy, true, AS);
bool AllSame = true;
for (unsigned i = 1; i != NumElems; ++i)
if (MemberSize !=
- getFoldedSizeOf(STy->getElementType(i), DestTy, true)) {
+ getFoldedSizeOf(STy->getElementType(i), DestTy, true, AS)) {
AllSame = false;
break;
}
@@ -611,11 +610,12 @@
CE->getOperand(0)->isNullValue()) {
Type *Ty =
cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+ unsigned AS = CE->getOperand(0)->getType()->getPointerAddressSpace();
if (CE->getNumOperands() == 2) {
// Handle a sizeof-like expression.
Constant *Idx = CE->getOperand(1);
bool isOne = isa<ConstantInt>(Idx) && cast<ConstantInt>(Idx)->isOne();
- if (Constant *C = getFoldedSizeOf(Ty, DestTy, !isOne)) {
+ if (Constant *C = getFoldedSizeOf(Ty, DestTy, !isOne, AS)) {
Idx = ConstantExpr::getCast(CastInst::getCastOpcode(Idx, true,
DestTy, false),
Idx, DestTy);
@@ -636,7 +636,7 @@
// Handle an offsetof-like expression.
if (Ty->isStructTy() || Ty->isArrayTy()) {
if (Constant *C = getFoldedOffsetOf(Ty, CE->getOperand(2),
- DestTy, false))
+ DestTy, false, AS))
return C;
}
}
Index: lib/VMCore/Constants.cpp
===================================================================
--- lib/VMCore/Constants.cpp
+++ lib/VMCore/Constants.cpp
@@ -1658,12 +1658,12 @@
return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
}
-Constant *ConstantExpr::getSizeOf(Type* Ty) {
- // sizeof is implemented as: (i64) gep (Ty*)null, 1
+Constant *ConstantExpr::getSizeOf(Type* Ty, unsigned AS) {
+ // sizeof is implemented as: (i64) gep (Ty addrspace(AS)*)null, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *GEP = getGetElementPtr(
- Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
+ Constant::getNullValue(PointerType::get(Ty, AS)), GEPIdx);
return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext()));
}
Index: include/llvm/Constants.h
===================================================================
--- include/llvm/Constants.h
+++ include/llvm/Constants.h
@@ -814,7 +814,7 @@
/// address-units, not bits) in a target independent way (Note: the return
/// type is an i64).
///
- static Constant *getSizeOf(Type *Ty);
+ static Constant *getSizeOf(Type *Ty, unsigned AS = 0);
/// getOffsetOf constant expr - computes the offset of a struct field in a
/// target independent way (Note: the return type is an i64).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88.1.patch
Type: text/x-patch
Size: 6276 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121030/24d45e86/attachment.bin>
More information about the llvm-commits
mailing list