Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -2583,8 +2583,9 @@ Value *OldOp = LI.getOperand(0); assert(OldOp == OldPtr); - Type *TargetTy = IsSplit ? Type::getIntNTy(LI.getContext(), SliceSize * 8) - : LI.getType(); + Type *TargetTy = IsSplit ? + Type::getIntNTy(LI.getContext(),DL.getTypeStoreSizeInBits(NewAllocaTy)) + : LI.getType(); bool IsPtrAdjusted = false; Value *V; if (VecTy) { Index: test/Transforms/SROA/big-endian.ll =================================================================== --- test/Transforms/SROA/big-endian.ll +++ test/Transforms/SROA/big-endian.ll @@ -112,3 +112,35 @@ ; CHECK-NEXT: %[[ret:.*]] = zext i56 %[[insert4]] to i64 ; CHECK-NEXT: ret i64 %[[ret]] } + +%struct.S0 = type { i32, i24 } + +@main.l_15 = private unnamed_addr constant { i32, i8, i8, i8 } { i32 8, i8 0, i8 1, i8 -128 }, align 4 + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) + +define i64 @test3() { +; CHECK-LABEL: @test3( +entry: + %l_15 = alloca %struct.S0, align 4 + %r0 = bitcast %struct.S0* %l_15 to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %r0, i8* bitcast ({ i32, i8, i8, i8 }* @main.l_15 to i8*), i64 8, i32 4, i1 false) + %f0 = getelementptr inbounds %struct.S0, %struct.S0* %l_15, i32 0, i32 0 + %r1 = load i32, i32* %f0, align 4 + %r2 = bitcast %struct.S0* %l_15 to i64* + %r3 = load i64, i64* %r2, align 1 + ret i64 %r3 +; CHECK: %[[ld_f0:.*]] = load i32, i32* getelementptr inbounds ({ i32, i8, i8, i8 }, { i32, i8, i8, i8 }* @main.l_15, i64 0, i32 0), align 4 +; CHECK-NEXT: %[[ld_f1:.*]] = load i24, i24* bitcast (i8* getelementptr inbounds ({ i32, i8, i8, i8 }, { i32, i8, i8, i8 }* @main.l_15, i64 0, i32 1) to i24*), align 4 +; CHECK-NEXT: %[[ld:.*]] = load i8, i8* getelementptr inbounds (i8, i8* bitcast ({ i32, i8, i8, i8 }* @main.l_15 to i8*), i64 7), align 1 +; CHECK-NEXT: %[[ext:.*]] = zext i24 %[[ld_f1]] to i64 +; CHECK-NEXT: %[[shift:.*]] = shl i64 %[[ext]], 8 +; CHECK-NEXT: %[[mask:.*]] = and i64 undef, -4294967041 +; CHECK-NEXT: %[[insert:.*]] = or i64 %[[mask]], %[[shift]] +; CHECK-NEXT: %[[ext1:.*]] = zext i32 %[[ld_f0]] to i64 +; CHECK-NEXT: %[[shift1:.*]] = shl i64 %[[ext1]], 32 +; CHECK-NEXT: %[[mask1:.*]] = and i64 %[[insert]], 4294967295 +; CHECK-NEXT: %[[insert1:.*]] = or i64 %[[mask1]], %[[shift1]] +; CHECK-NEXT: ret i64 %[[insert1]] +} +