- // 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);