[llvm-commits] [llvm] r61915 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/copy-aggregate.ll
Bill Wendling
isanbard at gmail.com
Wed Jan 7 23:34:39 PST 2009
Hi Chris,
This test is failing with this check in. It might need to be updated:
Running /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore/test/
FrontendC++/dg.exp ...
FAIL: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvmCore/test/
FrontendC++/2008-02-13-sret.cpp
Failed with exit(1) at line 1
while running: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/
llvmgcc42.roots/llvmgcc42~dst/Developer/usr/bin/llvm-gcc-4.2 -fstrict-
aliasing -Wstrict-aliasing -I/usr/include/c++/4.0.0/i686-apple-darwin9
-I/usr/include/c++/4.0.0 -emit-llvm -w -S -O1 -m32 -emit-llvm /Volumes/
Sandbox/Buildbot/llvm/full-llvm/build/llvmCore/test/FrontendC++/
2008-02-13-sret.cpp -o - | /usr/bin/grep {store i32} | count 1
count: expected 1 lines and got 0.
child process exited abnormally
-bw
On Jan 7, 2009, at 9:42 PM, Chris Lattner wrote:
> Author: lattner
> Date: Wed Jan 7 23:42:05 2009
> New Revision: 61915
>
> URL: http://llvm.org/viewvc/llvm-project?rev=61915&view=rev
> Log:
> This implements the second half of the fix for PR3290, handling
> loads from allocas that cover the entire aggregate. This handles
> some memcpy/byval cases that are produced by llvm-gcc. This triggers
> a few times in kc++ (with std::pair<std::_Rb_tree_const_iterator
> <kc::impl_abstract_phylum*>,bool>) and once in 176.gcc (with
> %struct..0anon).
>
>
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
> llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=61915&r1=61914&r2=61915&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
> (original)
> +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed
> Jan 7 23:42:05 2009
> @@ -122,6 +122,8 @@
> SmallVector<AllocaInst*, 32>
> &NewElts);
> void RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocationInst
> *AI,
> SmallVector<AllocaInst*, 32>
> &NewElts);
> + void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocationInst
> *AI,
> + SmallVector<AllocaInst*, 32>
> &NewElts);
>
> const Type *CanConvertToScalar(Value *V, bool &IsNotTrivial);
> void ConvertToScalar(AllocationInst *AI, const Type *Ty);
> @@ -599,6 +601,18 @@
> continue;
> }
> return MarkUnsafe(Info);
> + } else if (LoadInst *LI = dyn_cast<LoadInst>(UI)) {
> + // If loading the entire alloca in one chunk through a
> bitcasted pointer
> + // to integer, we can transform it. This happens (for
> example) when you
> + // cast a {i32,i32}* to i64* and load through it. This is
> similar to the
> + // memcpy case and occurs in various "byval" cases and
> emulated memcpys.
> + if (isa<IntegerType>(LI->getType()) &&
> + TD->getABITypeSize(LI->getType()) ==
> + TD->getABITypeSize(AI->getType()->getElementType())) {
> + Info.isMemCpySrc = true;
> + continue;
> + }
> + return MarkUnsafe(Info);
> } else {
> return MarkUnsafe(Info);
> }
> @@ -628,15 +642,21 @@
> }
>
> if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
> - // This must be a store of the entire alloca from an integer.
> + // If this is a store of the entire alloca from an integer,
> rewrite it.
> RewriteStoreUserOfWholeAlloca(SI, AI, NewElts);
> continue;
> }
> +
> + if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
> + // If this is a load of the entire alloca to an integer,
> rewrite it.
> + RewriteLoadUserOfWholeAlloca(LI, AI, NewElts);
> + continue;
> + }
>
> // Otherwise it must be some other user of a gep of the first
> pointer. Just
> // leave these alone.
> continue;
> - }
> + }
> }
>
> /// RewriteMemIntrinUserOfAlloca - MI is a memcpy/memset/memmove
> from or to AI.
> @@ -902,6 +922,83 @@
> SI->eraseFromParent();
> }
>
> +/// RewriteLoadUserOfWholeAlloca - We found an load of the entire
> allocation to
> +/// an integer. Load the individual pieces to form the aggregate
> value.
> +void SROA::RewriteLoadUserOfWholeAlloca(LoadInst *LI,
> AllocationInst *AI,
> + SmallVector<AllocaInst*,
> 32> &NewElts) {
> + // Extract each element out of the NewElts according to its
> structure offset
> + // and form the result value.
> + const Type *AllocaEltTy = AI->getType()->getElementType();
> + uint64_t AllocaSizeBits = TD->getABITypeSizeInBits(AllocaEltTy);
> +
> + // If this isn't a load of the whole alloca to an integer, it may
> be a load
> + // of the first element. Just ignore the load in this case and
> normal SROA
> + // will handle it.
> + if (!isa<IntegerType>(LI->getType()) ||
> + TD->getABITypeSizeInBits(LI->getType()) != AllocaSizeBits)
> + return;
> +
> + DOUT << "PROMOTING LOAD OF WHOLE ALLOCA: " << *AI << *LI;
> +
> + // There are two forms here: AI could be an array or struct.
> Both cases
> + // have different ways to compute the element offset.
> + const StructLayout *Layout = 0;
> + uint64_t ArrayEltBitOffset = 0;
> + if (const StructType *EltSTy = dyn_cast<StructType>(AllocaEltTy)) {
> + Layout = TD->getStructLayout(EltSTy);
> + } else {
> + const Type *ArrayEltTy = cast<ArrayType>(AllocaEltTy)-
> >getElementType();
> + ArrayEltBitOffset = TD->getABITypeSizeInBits(ArrayEltTy);
> + }
> +
> + Value *ResultVal = Constant::getNullValue(LI->getType());
> +
> + for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
> + // Load the value from the alloca. If the NewElt is an
> aggregate, cast
> + // the pointer to an integer of the same size before doing the
> load.
> + Value *SrcField = NewElts[i];
> + const Type *FieldTy =
> + cast<PointerType>(SrcField->getType())->getElementType();
> + const IntegerType *FieldIntTy =
> + IntegerType::get(TD->getTypeSizeInBits(FieldTy));
> + if (!isa<IntegerType>(FieldTy) && !FieldTy->isFloatingPoint() &&
> + !isa<VectorType>(FieldTy))
> + SrcField = new BitCastInst(SrcField,
> PointerType::getUnqual(FieldIntTy),
> + "", LI);
> + SrcField = new LoadInst(SrcField, "sroa.load.elt", LI);
> +
> + // If SrcField is a fp or vector of the right size but that
> isn't an
> + // integer type, bitcast to an integer so we can shift it.
> + if (SrcField->getType() != FieldIntTy)
> + SrcField = new BitCastInst(SrcField, FieldIntTy, "", LI);
> +
> + // Zero extend the field to be the same size as the final
> alloca so that
> + // we can shift and insert it.
> + if (SrcField->getType() != ResultVal->getType())
> + SrcField = new ZExtInst(SrcField, ResultVal->getType(), "",
> LI);
> +
> + // Determine the number of bits to shift SrcField.
> + uint64_t Shift;
> + if (Layout) // Struct case.
> + Shift = Layout->getElementOffsetInBits(i);
> + else // Array case.
> + Shift = i*ArrayEltBitOffset;
> +
> + if (TD->isBigEndian())
> + Shift = AllocaSizeBits-Shift-FieldIntTy->getBitWidth();
> +
> + if (Shift) {
> + Value *ShiftVal = ConstantInt::get(SrcField->getType(), Shift);
> + SrcField = BinaryOperator::CreateShl(SrcField, ShiftVal, "",
> LI);
> + }
> +
> + ResultVal = BinaryOperator::CreateOr(SrcField, ResultVal, "",
> LI);
> + }
> +
> + LI->replaceAllUsesWith(ResultVal);
> + LI->eraseFromParent();
> +}
> +
>
> /// HasPadding - Return true if the specified type has any structure
> or
> /// alignment padding, false otherwise.
>
> Modified: llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll?rev=61915&r1=61914&r2=61915&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll (original)
> +++ llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll Wed Jan
> 7 23:42:05 2009
> @@ -29,3 +29,29 @@
> ret float %c
> }
>
> +;; Load of whole alloca struct as integer
> +define i64 @test3(i32 %a, i32 %b) nounwind {
> + %X = alloca {{i32, i32}}
> +
> + %A = getelementptr {{i32,i32}}* %X, i32 0, i32 0, i32 0
> + %B = getelementptr {{i32,i32}}* %X, i32 0, i32 0, i32 1
> + store i32 %a, i32* %A
> + store i32 %b, i32* %B
> +
> + %Y = bitcast {{i32,i32}}* %X to i64*
> + %Z = load i64* %Y
> + ret i64 %Z
> +}
> +
> +;; load of integer from whole struct/array alloca.
> +define i128 @test4(float %a, float %b) nounwind {
> + %X = alloca {[4 x float]}
> + %A = getelementptr {[4 x float]}* %X, i32 0, i32 0, i32 0
> + %B = getelementptr {[4 x float]}* %X, i32 0, i32 0, i32 3
> + store float %a, float* %A
> + store float %b, float* %B
> +
> + %Y = bitcast {[4 x float]}* %X to i128*
> + %V = load i128* %Y
> + ret i128 %V
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list