Skip to content

[ValueTracking] AllowEphemerals for alignment assumptions. #10135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -822,9 +822,12 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
continue;
if (RetainedKnowledge RK = getKnowledgeFromBundle(
*I, I->bundle_op_info_begin()[Elem.Index])) {
// Allow AllowEphemerals in isValidAssumeForContext, as the CxtI might
// be the producer of the pointer in the bundle. At the moment, align
// assumptions aren't optimized away.
if (RK.WasOn == V && RK.AttrKind == Attribute::Alignment &&
isPowerOf2_64(RK.ArgValue) &&
isValidAssumeForContext(I, Q.CxtI, Q.DT))
isValidAssumeForContext(I, Q.CxtI, Q.DT, /*AllowEphemerals*/ true))
Known.Zero.setLowBits(Log2_64(RK.ArgValue));
}
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,246 @@ exit:
ret i32 0
}

define void @ptr_induction_eq_2(ptr %a, i64 %n) {
; CHECK-LABEL: 'ptr_induction_eq_2'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_eq_2
; CHECK-NEXT: %b = getelementptr inbounds ptr, ptr %a, i64 %n
; CHECK-NEXT: --> ((8 * %n)<nsw> + %a) U: full-set S: full-set
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * ((-8 + (8 * %n)<nsw>) /u 8))<nuw> + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a),+,8}<nuw><%loop> U: full-set S: full-set Exits: (8 + (8 * ((-8 + (8 * %n)<nsw>) /u 8))<nuw> + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_eq_2
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%b = getelementptr inbounds ptr, ptr %a, i64 %n
%cmp = icmp eq ptr %a, %b
br i1 %cmp, label %exit, label %loop

loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b
br i1 %exitcond, label %exit, label %loop

exit:
ret void
}

define void @ptr_induction_early_exit_eq_1_with_align_on_load(ptr %a, ptr %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_with_align_on_load'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_with_align_on_load
; CHECK-NEXT: %a_ = load ptr, ptr %a, align 8, !align !0
; CHECK-NEXT: --> %a_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %b_ = load ptr, ptr %b, align 8, !align !0
; CHECK-NEXT: --> %b_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
; CHECK-NEXT: --> {%a_,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a_),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_with_align_on_load
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
;
entry:
%a_ = load ptr, ptr %a, !align !{i64 8}
%b_ = load ptr, ptr %b, !align !{i64 8}
%cmp = icmp eq ptr %a_, %b_
br i1 %cmp, label %exit, label %loop

loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc

loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b_
br i1 %exitcond, label %exit, label %loop

exit:
ret void
}

define void @ptr_induction_early_exit_eq_1_with_align_on_arguments(ptr align 8 %a, ptr align 8 %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_with_align_on_arguments'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_with_align_on_arguments
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_with_align_on_arguments
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
;
entry:
%cmp = icmp eq ptr %a, %b
br i1 %cmp, label %exit, label %loop

loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc

loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b
br i1 %exitcond, label %exit, label %loop

exit:
ret void
}

define void @ptr_induction_early_exit_eq_1_align_assumption_1(ptr %a, ptr %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_align_assumption_1'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_align_assumption_1
; CHECK-NEXT: %a_ = load ptr, ptr %a, align 8
; CHECK-NEXT: --> %a_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %b_ = load ptr, ptr %b, align 8
; CHECK-NEXT: --> %b_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
; CHECK-NEXT: --> {%a_,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a_),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_align_assumption_1
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
;
entry:
%a_ = load ptr, ptr %a
call void @llvm.assume(i1 true) [ "align"(ptr %a_, i64 8) ]
%b_ = load ptr, ptr %b
call void @llvm.assume(i1 true) [ "align"(ptr %b_, i64 8) ]
%cmp = icmp eq ptr %a_, %b_
br i1 %cmp, label %exit, label %loop

loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc

loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b_
br i1 %exitcond, label %exit, label %loop

exit:
ret void
}

define void @ptr_induction_early_exit_eq_1_align_assumption_2(ptr %a, ptr %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_align_assumption_2'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_align_assumption_2
; CHECK-NEXT: %a_ = load ptr, ptr %a, align 8
; CHECK-NEXT: --> %a_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %b_ = load ptr, ptr %b, align 8
; CHECK-NEXT: --> %b_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
; CHECK-NEXT: --> {%a_,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a_),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_align_assumption_2
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
;
entry:
%a_ = load ptr, ptr %a
%b_ = load ptr, ptr %b
call void @llvm.assume(i1 true) [ "align"(ptr %a_, i64 8) ]
call void @llvm.assume(i1 true) [ "align"(ptr %b_, i64 8) ]
%cmp = icmp eq ptr %a_, %b_
br i1 %cmp, label %exit, label %loop

loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc

loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b_
br i1 %exitcond, label %exit, label %loop

exit:
ret void
}

define void @ptr_induction_early_exit_eq_2(ptr %a, i64 %n, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_2'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_2
; CHECK-NEXT: %b = getelementptr inbounds ptr, ptr %a, i64 %n
; CHECK-NEXT: --> ((8 * %n)<nsw> + %a) U: full-set S: full-set
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a),+,8}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_2
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (8 * %n)<nsw>) /u 8)
;
entry:
%b = getelementptr inbounds ptr, ptr %a, i64 %n
%cmp = icmp eq ptr %a, %b
br i1 %cmp, label %exit, label %loop

loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc

loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b
br i1 %exitcond, label %exit, label %loop

exit:
ret void
}

define void @gep_addrec_nw(ptr %a) {
; CHECK-LABEL: 'gep_addrec_nw'
; CHECK-NEXT: Classifying expressions for: @gep_addrec_nw
Expand Down