diff --git a/clang/test/CodeGen/arm64_32-vaarg.c b/clang/test/CodeGen/arm64_32-vaarg.c --- a/clang/test/CodeGen/arm64_32-vaarg.c +++ b/clang/test/CodeGen/arm64_32-vaarg.c @@ -29,7 +29,7 @@ // CHECK-LABEL: define{{.*}} i64 @test_longlong(i64 %input // CHECK: [[STARTPTR:%.*]] = load ptr, ptr %mylist // CHECK: [[ALIGN_TMP:%.+]] = getelementptr inbounds i8, ptr [[STARTPTR]], i32 7 - // CHECK: [[ALIGNED_ADDR:%.+]] = tail call ptr @llvm.ptrmask.p0.i32(ptr nonnull [[ALIGN_TMP]], i32 -8) + // CHECK: [[ALIGNED_ADDR:%.+]] = tail call align 8 ptr @llvm.ptrmask.p0.i32(ptr nonnull [[ALIGN_TMP]], i32 -8) // CHECK: [[NEXT:%.*]] = getelementptr inbounds i8, ptr [[ALIGNED_ADDR]], i32 8 // CHECK: store ptr [[NEXT]], ptr %mylist diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1951,6 +1951,28 @@ {InnerPtr, NewMask})); } } + bool Changed = false; + KnownBits Known = computeKnownBits(II, /*Depth*/ 0, II); + // See if we can deduce non-null. + if (!CI.hasRetAttr(Attribute::NonNull) && + (Known.isNonZero() || + isKnownNonZero(II, DL, /*Depth*/ 0, &AC, II, &DT))) { + CI.addRetAttr(Attribute::NonNull); + Changed = true; + } + + // Known bits will capture if we had alignment information assosiated with + // the pointer argument. + if (Known.countMinTrailingZeros() > Log2(CI.getRetAlign().valueOrOne())) { + if (CI.hasRetAttr(Attribute::Alignment)) + CI.removeRetAttr(Attribute::Alignment); + CI.addRetAttr( + Attribute::get(CI.getContext(), Attribute::Alignment, + uint64_t(1) << Known.countMinTrailingZeros())); + Changed = true; + } + if (Changed) + return &CI; break; } case Intrinsic::uadd_with_overflow: diff --git a/llvm/test/Transforms/InstCombine/align-addr.ll b/llvm/test/Transforms/InstCombine/align-addr.ll --- a/llvm/test/Transforms/InstCombine/align-addr.ll +++ b/llvm/test/Transforms/InstCombine/align-addr.ll @@ -137,7 +137,7 @@ define <16 x i8> @ptrmask_align_unknown_ptr_align8(ptr align 8 %ptr, i64 %mask) { ; CHECK-LABEL: @ptrmask_align_unknown_ptr_align8( -; CHECK-NEXT: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 [[MASK:%.*]]) +; CHECK-NEXT: [[ALIGNED:%.*]] = call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 [[MASK:%.*]]) ; CHECK-NEXT: [[LOAD:%.*]] = load <16 x i8>, ptr [[ALIGNED]], align 8 ; CHECK-NEXT: ret <16 x i8> [[LOAD]] ; @@ -149,7 +149,7 @@ ; Increase load align from 1 to 2 define <16 x i8> @ptrmask_align2_ptr_align1(ptr align 1 %ptr) { ; CHECK-LABEL: @ptrmask_align2_ptr_align1( -; CHECK-NEXT: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -2) +; CHECK-NEXT: [[ALIGNED:%.*]] = call align 2 ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -2) ; CHECK-NEXT: [[LOAD:%.*]] = load <16 x i8>, ptr [[ALIGNED]], align 2 ; CHECK-NEXT: ret <16 x i8> [[LOAD]] ; @@ -161,7 +161,7 @@ ; Increase load align from 1 to 4 define <16 x i8> @ptrmask_align4_ptr_align1(ptr align 1 %ptr) { ; CHECK-LABEL: @ptrmask_align4_ptr_align1( -; CHECK-NEXT: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4) +; CHECK-NEXT: [[ALIGNED:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4) ; CHECK-NEXT: [[LOAD:%.*]] = load <16 x i8>, ptr [[ALIGNED]], align 4 ; CHECK-NEXT: ret <16 x i8> [[LOAD]] ; @@ -173,7 +173,7 @@ ; Increase load align from 1 to 8 define <16 x i8> @ptrmask_align8_ptr_align1(ptr align 1 %ptr) { ; CHECK-LABEL: @ptrmask_align8_ptr_align1( -; CHECK-NEXT: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -8) +; CHECK-NEXT: [[ALIGNED:%.*]] = call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -8) ; CHECK-NEXT: [[LOAD:%.*]] = load <16 x i8>, ptr [[ALIGNED]], align 8 ; CHECK-NEXT: ret <16 x i8> [[LOAD]] ; @@ -210,7 +210,7 @@ ; than the pointer size. define <16 x i8> @ptrmask_align8_ptr_align1_smallmask(ptr align 1 %ptr) { ; CHECK-LABEL: @ptrmask_align8_ptr_align1_smallmask( -; CHECK-NEXT: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -8) +; CHECK-NEXT: [[ALIGNED:%.*]] = call align 8 ptr @llvm.ptrmask.p0.i32(ptr [[PTR:%.*]], i32 -8) ; CHECK-NEXT: [[LOAD:%.*]] = load <16 x i8>, ptr [[ALIGNED]], align 8 ; CHECK-NEXT: ret <16 x i8> [[LOAD]] ; @@ -223,7 +223,7 @@ ; than the pointer size. define <16 x i8> @ptrmask_align8_ptr_align1_bigmask(ptr align 1 %ptr) { ; CHECK-LABEL: @ptrmask_align8_ptr_align1_bigmask( -; CHECK-NEXT: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i128(ptr [[PTR:%.*]], i128 -8) +; CHECK-NEXT: [[ALIGNED:%.*]] = call align 8 ptr @llvm.ptrmask.p0.i128(ptr [[PTR:%.*]], i128 -8) ; CHECK-NEXT: [[LOAD:%.*]] = load <16 x i8>, ptr [[ALIGNED]], align 8 ; CHECK-NEXT: ret <16 x i8> [[LOAD]] ; diff --git a/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll b/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll --- a/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll +++ b/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll @@ -70,8 +70,8 @@ define ptr @fold_2x_type_mismatch_const0(ptr %p, i32 %m1) { ; CHECK-LABEL: define ptr @fold_2x_type_mismatch_const0 ; CHECK-SAME: (ptr [[P:%.*]], i32 [[M1:%.*]]) { -; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -128) -; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 [[M1]]) +; CHECK-NEXT: [[P0:%.*]] = call align 128 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -128) +; CHECK-NEXT: [[P1:%.*]] = call align 128 ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 [[M1]]) ; CHECK-NEXT: ret ptr [[P1]] ; %p0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -128) @@ -83,7 +83,7 @@ ; CHECK-LABEL: define ptr @fold_2x_type_mismatch_const1 ; CHECK-SAME: (ptr [[P:%.*]], i64 [[M0:%.*]]) { ; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[M0]]) -; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 -2) +; CHECK-NEXT: [[P1:%.*]] = call align 2 ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 -2) ; CHECK-NEXT: ret ptr [[P1]] ; %p0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m0) @@ -95,8 +95,8 @@ define ptr @fold_2x_type_mismatch_const2(ptr %p) { ; CHECK-LABEL: define ptr @fold_2x_type_mismatch_const2 ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -4) -; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 -31) +; CHECK-NEXT: [[P0:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -4) +; CHECK-NEXT: [[P1:%.*]] = call align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 -31) ; CHECK-NEXT: ret ptr [[P1]] ; %p0 = call ptr @llvm.ptrmask.p0.i32(ptr %p, i32 -4) diff --git a/llvm/test/Transforms/InstCombine/ptrmask.ll b/llvm/test/Transforms/InstCombine/ptrmask.ll --- a/llvm/test/Transforms/InstCombine/ptrmask.ll +++ b/llvm/test/Transforms/InstCombine/ptrmask.ll @@ -8,7 +8,7 @@ ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs ; CHECK-SAME: (ptr [[P0:%.*]], i64 [[M1:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M1]], 224 -; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]]) +; CHECK-NEXT: [[R:%.*]] = call align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]]) ; CHECK-NEXT: ret ptr [[R]] ; %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224) @@ -31,7 +31,7 @@ define ptr @ptrmask_combine_consecutive_preserve_attrs_todo0(ptr %p0) { ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo0 ; CHECK-SAME: (ptr [[P0:%.*]]) { -; CHECK-NEXT: [[PM0:%.*]] = call noalias ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224) +; CHECK-NEXT: [[PM0:%.*]] = call noalias align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224) ; CHECK-NEXT: ret ptr [[PM0]] ; %pm0 = call noalias ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224) @@ -42,7 +42,7 @@ define ptr @ptrmask_combine_consecutive_preserve_attrs_todo1(ptr %p0) { ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo1 ; CHECK-SAME: (ptr [[P0:%.*]]) { -; CHECK-NEXT: [[PM0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224) +; CHECK-NEXT: [[PM0:%.*]] = call align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224) ; CHECK-NEXT: ret ptr [[PM0]] ; %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224) @@ -53,7 +53,7 @@ define ptr @ptrmask_combine_consecutive_preserve_attrs_todo2(ptr %p0) { ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo2 ; CHECK-SAME: (ptr [[P0:%.*]]) { -; CHECK-NEXT: [[PM0:%.*]] = call noalias ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 224) +; CHECK-NEXT: [[PM0:%.*]] = call noalias align 32 ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 224) ; CHECK-NEXT: ret ptr [[PM0]] ; %pm0 = call noalias ptr @llvm.ptrmask.p0.i32(ptr %p0, i32 224) @@ -64,9 +64,9 @@ define ptr @ptrmask_combine_add_nonnull(ptr %p) { ; CHECK-LABEL: define ptr @ptrmask_combine_add_nonnull ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[PM0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64) +; CHECK-NEXT: [[PM0:%.*]] = call align 64 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64) ; CHECK-NEXT: [[PGEP:%.*]] = getelementptr i8, ptr [[PM0]], i64 33 -; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PGEP]], i64 -16) +; CHECK-NEXT: [[R:%.*]] = call nonnull align 32 ptr @llvm.ptrmask.p0.i64(ptr [[PGEP]], i64 -16) ; CHECK-NEXT: ret ptr [[R]] ; %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -64) @@ -78,7 +78,7 @@ define ptr @ptrmask_combine_add_alignment(ptr %p) { ; CHECK-LABEL: define ptr @ptrmask_combine_add_alignment ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64) +; CHECK-NEXT: [[R:%.*]] = call align 64 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64) ; CHECK-NEXT: ret ptr [[R]] ; %r = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -64) @@ -88,7 +88,7 @@ define ptr @ptrmask_combine_add_alignment2(ptr align 32 %p) { ; CHECK-LABEL: define ptr @ptrmask_combine_add_alignment2 ; CHECK-SAME: (ptr align 32 [[P:%.*]]) { -; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -64) +; CHECK-NEXT: [[R:%.*]] = call align 64 ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -64) ; CHECK-NEXT: ret ptr [[R]] ; %r = call ptr @llvm.ptrmask.p0.i32(ptr %p, i32 -64) @@ -98,7 +98,7 @@ define ptr @ptrmask_combine_improve_alignment(ptr %p) { ; CHECK-LABEL: define ptr @ptrmask_combine_improve_alignment ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: [[R:%.*]] = call align 32 ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -64) +; CHECK-NEXT: [[R:%.*]] = call align 64 ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -64) ; CHECK-NEXT: ret ptr [[R]] ; %r = call align 32 ptr @llvm.ptrmask.p0.i32(ptr %p, i32 -64)