Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1356,14 +1356,16 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) { const CGBitFieldInfo &Info = LV.getBitFieldInfo(); + int64_t Align = Info.StorageAlignment; + if (!LV.getAlignment().isZero()) + Align = std::min(Align, LV.getAlignment().getQuantity()); // Get the output type. llvm::Type *ResLTy = ConvertType(LV.getType()); llvm::Value *Ptr = LV.getBitFieldAddr(); - llvm::Value *Val = Builder.CreateLoad(Ptr, LV.isVolatileQualified(), - "bf.load"); - cast(Val)->setAlignment(Info.StorageAlignment); + llvm::Value *Val = + Builder.CreateAlignedLoad(Ptr, Align, LV.isVolatileQualified(), "bf.load"); if (Info.IsSigned) { assert(static_cast(Info.Offset + Info.Size) <= Info.StorageSize); @@ -1559,6 +1561,9 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result) { const CGBitFieldInfo &Info = Dst.getBitFieldInfo(); + int64_t Align = Info.StorageAlignment; + if (!Dst.getAlignment().isZero()) + Align = std::min(Align, Dst.getAlignment().getQuantity()); llvm::Type *ResLTy = ConvertTypeForMem(Dst.getType()); llvm::Value *Ptr = Dst.getBitFieldAddr(); @@ -1575,9 +1580,9 @@ // and mask together with source before storing. if (Info.StorageSize != Info.Size) { assert(Info.StorageSize > Info.Size && "Invalid bitfield size."); - llvm::Value *Val = Builder.CreateLoad(Ptr, Dst.isVolatileQualified(), - "bf.load"); - cast(Val)->setAlignment(Info.StorageAlignment); + llvm::Value *Val = Builder.CreateAlignedLoad(Ptr, Align, + Dst.isVolatileQualified(), + "bf.load"); // Mask the source value as needed. if (!hasBooleanRepresentation(Dst.getType())) @@ -1603,9 +1608,8 @@ } // Write the new value back out. - llvm::StoreInst *Store = Builder.CreateStore(SrcVal, Ptr, - Dst.isVolatileQualified()); - Store->setAlignment(Info.StorageAlignment); + llvm::StoreInst *Store = + Builder.CreateAlignedStore(SrcVal, Ptr, Align, Dst.isVolatileQualified()); // Return the new value of the bit-field, if requested. if (Result) { Index: test/CodeGen/packed-nest-unpacked.c =================================================================== --- test/CodeGen/packed-nest-unpacked.c +++ test/CodeGen/packed-nest-unpacked.c @@ -60,6 +60,35 @@ unsigned test7() { // CHECK: @test7 - // CHECK: load i32, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 4 + // CHECK: load i32, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 1 return gbitfield.y.b2; } + +void test8(unsigned x) { + // CHECK: @test8 + // CHECK: load i32, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 1 + // CHECK: store i32 {{.*}}, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 1 + gbitfield.y.b2 = x; +} + +struct TBitfield +{ + long a; + char b; + unsigned c:15; +}; +struct TBitfield tbitfield; + +unsigned test9() { + // CHECK: @test9 + // CHECK: load i16, i16* getelementptr inbounds (%struct.TBitfield, %struct.TBitfield* @tbitfield, i32 0, i32 2), align 1 + return tbitfield.c; +} + +void test10(unsigned x) { + // CHECK: @test10 + // CHECK: load i16, i16* getelementptr inbounds (%struct.TBitfield, %struct.TBitfield* @tbitfield, i32 0, i32 2), align 1 + // CHECK: store i16 {{.*}}, i16* getelementptr inbounds (%struct.TBitfield, %struct.TBitfield* @tbitfield, i32 0, i32 2), align 1 + tbitfield.c = x; +} +