From: Chris Lattner Date: Mon, 21 Sep 2009 17:24:04 +0000 (+0000) Subject: fix PR5016, a crash I introduced in GVN handing first class X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8b2bc3d5746c6094e90c416d72c3646227598ae3;p=oota-llvm.git 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 --- diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 5a7f2ec0867..b549e803177 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(LoadTy) || isa(LoadTy) || + isa(StoredVal->getType()) || + isa(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(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(L->getType()) || isa(L->getType()) || + isa(DepSI->getOperand(0)->getType()) || + isa(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 &toErase) { const TargetData *TD = 0; if (StoredVal->getType() != L->getType() && (TD = getAnalysisIfAvailable())) { - 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 &toErase) { const TargetData *TD = 0; if (DepLI->getType() != L->getType() && (TD = getAnalysisIfAvailable())) { - AvailableVal = CoerceAvailableValueToLoadType(DepLI, L->getType(), L, *TD); + AvailableVal = CoerceAvailableValueToLoadType(DepLI, L->getType(), L,*TD); if (AvailableVal == 0) return false; diff --git a/test/Transforms/GVN/rle.ll b/test/Transforms/GVN/rle.ll index afdcd5daa62..cdd1f4fa4e8 100644 --- a/test/Transforms/GVN/rle.ll +++ b/test/Transforms/GVN/rle.ll @@ -13,6 +13,20 @@ define i32 @test0(i32 %V, i32* %P) { ; CHECK: ret i32 %V } + +;;===----------------------------------------------------------------------===;; +;; Tests for crashers +;;===----------------------------------------------------------------------===;; + +;; PR5016 +define i8 @crash0({i32, i32} %A, {i32, i32}* %P) { + store {i32, i32} %A, {i32, i32}* %P + %X = bitcast {i32, i32}* %P to i8* + %Y = load i8* %X + ret i8 %Y +} + + ;;===----------------------------------------------------------------------===;; ;; Store -> Load and Load -> Load forwarding where src and dst are different ;; types, but where the base pointer is a must alias.