diff options
author | Chris Lattner <sabre@nondot.org> | 2009-09-21 17:24:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-09-21 17:24:04 +0000 |
commit | 8b2bc3d5746c6094e90c416d72c3646227598ae3 (patch) | |
tree | bf9b5c8ec786a3c210a916e95a5ddb9aff4ba7a8 /lib/Transforms/Scalar/GVN.cpp | |
parent | f8349ac8b8534960190d830ee86239a5eade4737 (diff) | |
download | external_llvm-8b2bc3d5746c6094e90c416d72c3646227598ae3.zip external_llvm-8b2bc3d5746c6094e90c416d72c3646227598ae3.tar.gz external_llvm-8b2bc3d5746c6094e90c416d72c3646227598ae3.tar.bz2 |
fix PR5016, a crash I introduced in GVN handing first class
arrays and structs, which cannot be bitcast to integers.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82460 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/GVN.cpp')
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 5a7f2ec..b549e80 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -940,6 +940,27 @@ SpeculationFailure: } +/// CanCoerceMustAliasedValueToLoad - Return true if +/// CoerceAvailableValueToLoadType will succeed. +static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal, + const Type *LoadTy, + const TargetData &TD) { + // If the loaded or stored value is an first class array or struct, don't try + // to transform them. We need to be able to bitcast to integer. + if (isa<StructType>(LoadTy) || isa<ArrayType>(LoadTy) || + isa<StructType>(StoredVal->getType()) || + isa<ArrayType>(StoredVal->getType())) + return false; + + // The store has to be at least as big as the load. + if (TD.getTypeSizeInBits(StoredVal->getType()) < + TD.getTypeSizeInBits(LoadTy)) + return false; + + return true; +} + + /// CoerceAvailableValueToLoadType - If we saw a store of a value to memory, and /// then a load from a must-aliased pointer of a different type, try to coerce /// the stored value. LoadedTy is the type of the load we want to replace and @@ -950,6 +971,9 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, const Type *LoadedTy, Instruction *InsertPt, const TargetData &TD) { + if (!CanCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, TD)) + return 0; + const Type *StoredValTy = StoredVal->getType(); uint64_t StoreSize = TD.getTypeSizeInBits(StoredValTy); @@ -985,8 +1009,7 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, // If the loaded value is smaller than the available value, then we can // extract out a piece from it. If the available value is too small, then we // can't do anything. - if (StoreSize < LoadSize) - return 0; + assert(StoreSize >= LoadSize && "CanCoerceMustAliasedValueToLoad fail"); // Convert source pointers to integers, which can be manipulated. if (isa<PointerType>(StoredValTy)) { @@ -1072,6 +1095,13 @@ static Value *GetBaseWithConstantOffset(Value *Ptr, int64_t &Offset, /// load. static int AnalyzeLoadFromClobberingStore(LoadInst *L, StoreInst *DepSI, const TargetData &TD) { + // If the loaded or stored value is an first class array or struct, don't try + // to transform them. We need to be able to bitcast to integer. + if (isa<StructType>(L->getType()) || isa<ArrayType>(L->getType()) || + isa<StructType>(DepSI->getOperand(0)->getType()) || + isa<ArrayType>(DepSI->getOperand(0)->getType())) + return -1; + int64_t StoreOffset = 0, LoadOffset = 0; Value *StoreBase = GetBaseWithConstantOffset(DepSI->getPointerOperand(), StoreOffset, TD); @@ -1323,9 +1353,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI, // If the stored value is larger or equal to the loaded value, we can // reuse it. - if (TD == 0 || - TD->getTypeSizeInBits(S->getOperand(0)->getType()) < - TD->getTypeSizeInBits(LI->getType())) { + if (TD == 0 || !CanCoerceMustAliasedValueToLoad(S->getOperand(0), + LI->getType(), *TD)) { UnavailableBlocks.push_back(DepBB); continue; } @@ -1344,9 +1373,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI, // If the stored value is larger or equal to the loaded value, we can // reuse it. - if (TD == 0 || - TD->getTypeSizeInBits(LD->getType()) < - TD->getTypeSizeInBits(LI->getType())) { + if (TD == 0 || !CanCoerceMustAliasedValueToLoad(LD, LI->getType(),*TD)){ UnavailableBlocks.push_back(DepBB); continue; } @@ -1627,7 +1654,8 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { const TargetData *TD = 0; if (StoredVal->getType() != L->getType() && (TD = getAnalysisIfAvailable<TargetData>())) { - StoredVal = CoerceAvailableValueToLoadType(StoredVal, L->getType(), L, *TD); + StoredVal = CoerceAvailableValueToLoadType(StoredVal, L->getType(), + L, *TD); if (StoredVal == 0) return false; @@ -1653,7 +1681,7 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { const TargetData *TD = 0; if (DepLI->getType() != L->getType() && (TD = getAnalysisIfAvailable<TargetData>())) { - AvailableVal = CoerceAvailableValueToLoadType(DepLI, L->getType(), L, *TD); + AvailableVal = CoerceAvailableValueToLoadType(DepLI, L->getType(), L,*TD); if (AvailableVal == 0) return false; |