Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -1286,7 +1286,8 @@ continue; APInt Offset(TD->getPointerSizeInBits( cast(Arg->getType())->getAddressSpace()), 0); - Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*TD, Offset); + Value *Val = Arg->stripAndAccumulateInBoundsConstantOffsets(*TD, Offset, + /*LookThroughNoAlias*/true); uint64_t Offset2 = Offset.getLimitedValue(); if ((Offset2 & (PrefAlign-1)) != 0) continue; Index: test/CodeGen/ARM/memfunc.ll =================================================================== --- test/CodeGen/ARM/memfunc.ll +++ test/CodeGen/ARM/memfunc.ll @@ -68,6 +68,50 @@ unreachable } +; From @f2 above, but make sure that a noalias call does not prevent the +; optimization. +define void @f2a(i8* %dest, i32 %n) { +entry: + ; CHECK-LABEL: f2a + + ; IOS (ARMv7) should 8-byte align, others should 4-byte align + ; CHECK-IOS: add r1, sp, #32 + ; CHECK-IOS: memmove + ; CHECK-DARWIN: add r1, sp, #28 + ; CHECK-DARWIN: memmove + ; CHECK-EABI: add r1, sp, #28 + ; CHECK-EABI: __aeabi_memmove + %arr0 = alloca [9 x i8], align 1 + %0 = bitcast [9 x i8]* %arr0 to i8* + %q = call i8* @llvm.noalias.p0i8(i8* %0, metadata !1) + call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %q, i32 %n, i32 0, i1 false) + + ; CHECK: add r1, sp, #16 + ; CHECK-IOS: memcpy + ; CHECK-DARWIN: memcpy + ; CHECK-EABI: __aeabi_memcpy + %arr1 = alloca [9 x i8], align 1 + %1 = bitcast [9 x i8]* %arr1 to i8* + %r = call i8* @llvm.noalias.p0i8(i8* %1, metadata !1) + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %r, i32 %n, i32 0, i1 false) + + ; CHECK-IOS: mov r0, sp + ; CHECK-IOS: mov r1, #0 + ; CHECK-IOS: memset + ; CHECK-DARINW: add r0, sp, #4 + ; CHECK-DARWIN: movs r1, #0 + ; CHECK-DARWIN: memset + ; CHECK-EABI: add r0, sp, #4 + ; CHECK-EABI: mov r2, #0 + ; CHECK-EABI: __aeabi_memset + %arr2 = alloca [9 x i8], align 1 + %2 = bitcast [9 x i8]* %arr2 to i8* + %s = call i8* @llvm.noalias.p0i8(i8* %2, metadata !1) + call void @llvm.memset.p0i8.i32(i8* %s, i8 0, i32 %n, i32 0, i1 false) + + unreachable +} + ; Check that alloca arguments are not aligned if less than 8 bytes in size define void @f3(i8* %dest, i32 %n) { entry: @@ -322,3 +366,9 @@ declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind + +declare i8* @llvm.noalias.p0i8(i8*, metadata) nounwind + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} +