[llvm-commits] [llvm] r47752 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/2008-02-28-SubElementExtractCrash.ll
Chris Lattner
sabre at nondot.org
Thu Feb 28 23:12:06 PST 2008
Author: lattner
Date: Fri Feb 29 01:12:06 2008
New Revision: 47752
URL: http://llvm.org/viewvc/llvm-project?rev=47752&view=rev
Log:
fix a bug Anders ran into where scalarrepl would crash when promoting
a union containing a vector and an array whose elements were smaller than
the vector elements. this means we need to compile the load of the
array elements into an extract element plus a truncate.
Added:
llvm/trunk/test/Transforms/ScalarRepl/2008-02-28-SubElementExtractCrash.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=47752&r1=47751&r2=47752&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Fri Feb 29 01:12:06 2008
@@ -1154,70 +1154,81 @@
// We win, no conversion needed.
return NV;
}
+
+ // If the result type of the 'union' is a pointer, then this must be ptr->ptr
+ // cast. Anything else would result in NV being an integer.
+ if (isa<PointerType>(NV->getType())) {
+ assert(isa<PointerType>(LI->getType()));
+ return new BitCastInst(NV, LI->getType(), LI->getName(), LI);
+ }
- if (const VectorType *PTy = dyn_cast<VectorType>(NV->getType())) {
+ if (const VectorType *VTy = dyn_cast<VectorType>(NV->getType())) {
// If the result alloca is a vector type, this is either an element
// access or a bitcast to another vector type.
- if (isa<VectorType>(LI->getType())) {
- NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
- } else {
- // Must be an element access.
- const TargetData &TD = getAnalysis<TargetData>();
- unsigned Elt = Offset/TD.getABITypeSizeInBits(PTy->getElementType());
- NV = new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt),
- "tmp", LI);
- }
- } else if (isa<PointerType>(NV->getType())) {
- assert(isa<PointerType>(LI->getType()));
- // Must be ptr->ptr cast. Anything else would result in NV being
- // an integer.
- NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
- } else {
- const IntegerType *NTy = cast<IntegerType>(NV->getType());
-
- // If this is a big-endian system and the load is narrower than the
- // full alloca type, we need to do a shift to get the right bits.
- int ShAmt = 0;
+ if (isa<VectorType>(LI->getType()))
+ return new BitCastInst(NV, LI->getType(), LI->getName(), LI);
+
+ // Otherwise it must be an element access.
const TargetData &TD = getAnalysis<TargetData>();
- if (TD.isBigEndian()) {
- // On big-endian machines, the lowest bit is stored at the bit offset
- // from the pointer given by getTypeStoreSizeInBits. This matters for
- // integers with a bitwidth that is not a multiple of 8.
- ShAmt = TD.getTypeStoreSizeInBits(NTy) -
- TD.getTypeStoreSizeInBits(LI->getType()) - Offset;
- } else {
- ShAmt = Offset;
+ unsigned Elt = 0;
+ if (Offset) {
+ unsigned EltSize = TD.getABITypeSizeInBits(VTy->getElementType());
+ Elt = Offset/EltSize;
+ Offset -= EltSize*Elt;
}
+ NV = new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt),
+ "tmp", LI);
- // Note: we support negative bitwidths (with shl) which are not defined.
- // We do this to support (f.e.) loads off the end of a structure where
- // only some bits are used.
- if (ShAmt > 0 && (unsigned)ShAmt < NTy->getBitWidth())
- NV = BinaryOperator::createLShr(NV,
- ConstantInt::get(NV->getType(),ShAmt),
- LI->getName(), LI);
- else if (ShAmt < 0 && (unsigned)-ShAmt < NTy->getBitWidth())
- NV = BinaryOperator::createShl(NV,
- ConstantInt::get(NV->getType(),-ShAmt),
- LI->getName(), LI);
-
- // Finally, unconditionally truncate the integer to the right width.
- unsigned LIBitWidth = TD.getTypeSizeInBits(LI->getType());
- if (LIBitWidth < NTy->getBitWidth())
- NV = new TruncInst(NV, IntegerType::get(LIBitWidth),
- LI->getName(), LI);
-
- // If the result is an integer, this is a trunc or bitcast.
- if (isa<IntegerType>(LI->getType())) {
- assert(NV->getType() == LI->getType() && "Truncate wasn't enough?");
- } else if (LI->getType()->isFloatingPoint()) {
- // Just do a bitcast, we know the sizes match up.
- NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
- } else {
- // Otherwise must be a pointer.
- NV = new IntToPtrInst(NV, LI->getType(), LI->getName(), LI);
- }
+ // If we're done, return this element.
+ if (NV->getType() == LI->getType() && Offset == 0)
+ return NV;
+ }
+
+ const IntegerType *NTy = cast<IntegerType>(NV->getType());
+
+ // If this is a big-endian system and the load is narrower than the
+ // full alloca type, we need to do a shift to get the right bits.
+ int ShAmt = 0;
+ const TargetData &TD = getAnalysis<TargetData>();
+ if (TD.isBigEndian()) {
+ // On big-endian machines, the lowest bit is stored at the bit offset
+ // from the pointer given by getTypeStoreSizeInBits. This matters for
+ // integers with a bitwidth that is not a multiple of 8.
+ ShAmt = TD.getTypeStoreSizeInBits(NTy) -
+ TD.getTypeStoreSizeInBits(LI->getType()) - Offset;
+ } else {
+ ShAmt = Offset;
+ }
+
+ // Note: we support negative bitwidths (with shl) which are not defined.
+ // We do this to support (f.e.) loads off the end of a structure where
+ // only some bits are used.
+ if (ShAmt > 0 && (unsigned)ShAmt < NTy->getBitWidth())
+ NV = BinaryOperator::createLShr(NV,
+ ConstantInt::get(NV->getType(),ShAmt),
+ LI->getName(), LI);
+ else if (ShAmt < 0 && (unsigned)-ShAmt < NTy->getBitWidth())
+ NV = BinaryOperator::createShl(NV,
+ ConstantInt::get(NV->getType(),-ShAmt),
+ LI->getName(), LI);
+
+ // Finally, unconditionally truncate the integer to the right width.
+ unsigned LIBitWidth = TD.getTypeSizeInBits(LI->getType());
+ if (LIBitWidth < NTy->getBitWidth())
+ NV = new TruncInst(NV, IntegerType::get(LIBitWidth),
+ LI->getName(), LI);
+
+ // If the result is an integer, this is a trunc or bitcast.
+ if (isa<IntegerType>(LI->getType())) {
+ // Should be done.
+ } else if (LI->getType()->isFloatingPoint()) {
+ // Just do a bitcast, we know the sizes match up.
+ NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
+ } else {
+ // Otherwise must be a pointer.
+ NV = new IntToPtrInst(NV, LI->getType(), LI->getName(), LI);
}
+ assert(NV->getType() == LI->getType() && "Didn't convert right?");
return NV;
}
Added: llvm/trunk/test/Transforms/ScalarRepl/2008-02-28-SubElementExtractCrash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2008-02-28-SubElementExtractCrash.ll?rev=47752&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ScalarRepl/2008-02-28-SubElementExtractCrash.ll (added)
+++ llvm/trunk/test/Transforms/ScalarRepl/2008-02-28-SubElementExtractCrash.ll Fri Feb 29 01:12:06 2008
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-apple-darwin8"
+ %struct..0anon = type { <1 x i64> }
+
+define i32 @main(i32 %argc, i8** %argv) {
+entry:
+ %c = alloca %struct..0anon ; <%struct..0anon*> [#uses=2]
+ %tmp2 = getelementptr %struct..0anon* %c, i32 0, i32 0 ; <<1 x i64>*> [#uses=1]
+ store <1 x i64> zeroinitializer, <1 x i64>* %tmp2, align 8
+ %tmp7 = getelementptr %struct..0anon* %c, i32 0, i32 0 ; <<1 x i64>*> [#uses=1]
+ %tmp78 = bitcast <1 x i64>* %tmp7 to [2 x i32]* ; <[2 x i32]*> [#uses=1]
+ %tmp9 = getelementptr [2 x i32]* %tmp78, i32 0, i32 0 ; <i32*> [#uses=1]
+ %tmp10 = load i32* %tmp9, align 4 ; <i32> [#uses=0]
+ unreachable
+}
More information about the llvm-commits
mailing list