This is a followup to #117750. Currently, AlwaysInline only invalidates analyses at the end, by returning that no analyses are preserved. However, this means that analyses fetched during inlining may be outdated. The aforementioned PR exposed this issue. Instead, bring the logic closer to what the normal inliner does, by directly invalidating the caller in FAM. This should make sure that we don't receive any outdated analyses even if they are fetched during inlining. Also drop the BFI updating entirely -- there's no point in doing it if we're going to invalidate everything anyway.
102 lines
3.5 KiB
LLVM
102 lines
3.5 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt -S -passes="function(require<block-freq>,loop(loop-unroll-full)),always-inline" < %s | FileCheck %s
|
|
|
|
; Make sure this does not crash.
|
|
|
|
define void @f_116_0(ptr %p) alwaysinline {
|
|
; CHECK-LABEL: define void @f_116_0(
|
|
; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[DOTPRE:%.*]] = load i16, ptr [[P]], align 1
|
|
; CHECK-NEXT: br label %[[FOR_COND:.*]]
|
|
; CHECK: [[FOR_COND]]:
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i16 [[DOTPRE]], 1
|
|
; CHECK-NEXT: br i1 [[CMP3]], label %[[FOR_BODY:.*]], label %[[FOR_COND_CLEANUP:.*]]
|
|
; CHECK: [[FOR_COND_CLEANUP]]:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: [[FOR_BODY]]:
|
|
; CHECK-NEXT: br label %[[FOR_COND]]
|
|
;
|
|
entry:
|
|
%.pre = load i16, ptr %p, align 1
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body, %entry
|
|
%cmp3 = icmp ult i16 %.pre, 1
|
|
br i1 %cmp3, label %for.body, label %for.cond.cleanup
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret void
|
|
|
|
for.body: ; preds = %for.cond
|
|
br label %for.cond
|
|
}
|
|
|
|
define void @f_321_0(ptr %p) alwaysinline {
|
|
; CHECK-LABEL: define void @f_321_0(
|
|
; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[FOR_COND:.*]]
|
|
; CHECK: [[FOR_COND]]:
|
|
; CHECK-NEXT: br i1 false, label %[[CRIT_EDGE:.*]], label %[[FOR_COND_CLEANUP:.*]]
|
|
; CHECK: [[CRIT_EDGE]]:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: [[FOR_COND_CLEANUP]]:
|
|
; CHECK-NEXT: [[DOTPRE_I:%.*]] = load i16, ptr [[P]], align 1
|
|
; CHECK-NEXT: br label %[[FOR_COND_I:.*]]
|
|
; CHECK: [[FOR_COND_I]]:
|
|
; CHECK-NEXT: [[CMP3_I:%.*]] = icmp ult i16 [[DOTPRE_I]], 1
|
|
; CHECK-NEXT: br i1 [[CMP3_I]], label %[[FOR_BODY_I:.*]], label %[[F_116_0_EXIT:.*]]
|
|
; CHECK: [[FOR_BODY_I]]:
|
|
; CHECK-NEXT: br label %[[FOR_COND_I]]
|
|
; CHECK: [[F_116_0_EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %crit_edge, %entry
|
|
br i1 false, label %crit_edge, label %for.cond.cleanup
|
|
|
|
crit_edge: ; preds = %for.cond
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
call void @f_116_0(ptr %p)
|
|
ret void
|
|
}
|
|
|
|
define i16 @main(ptr %p) {
|
|
; CHECK-LABEL: define i16 @main(
|
|
; CHECK-SAME: ptr [[P:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[FOR_COND:.*]]
|
|
; CHECK: [[FOR_COND]]:
|
|
; CHECK-NEXT: br label %[[FOR_COND]]
|
|
; CHECK: [[IF_ELSE:.*:]]
|
|
; CHECK-NEXT: [[DOTPRE_I_I:%.*]] = load i16, ptr [[P]], align 1
|
|
; CHECK-NEXT: br label %[[FOR_COND_I_I:.*]]
|
|
; CHECK: [[FOR_COND_I_I]]:
|
|
; CHECK-NEXT: [[CMP3_I_I:%.*]] = icmp ult i16 [[DOTPRE_I_I]], 1
|
|
; CHECK-NEXT: br i1 [[CMP3_I_I]], label %[[FOR_BODY_I_I:.*]], label %[[F_321_0_EXIT:.*]]
|
|
; CHECK: [[FOR_BODY_I_I]]:
|
|
; CHECK-NEXT: br label %[[FOR_COND_I_I]]
|
|
; CHECK: [[F_321_0_EXIT]]:
|
|
; CHECK-NEXT: br label %[[FOR_COND115:.*]]
|
|
; CHECK: [[FOR_COND115]]:
|
|
; CHECK-NEXT: br label %[[FOR_COND115]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.cond, %entry
|
|
br label %for.cond
|
|
|
|
if.else: ; No predecessors!
|
|
call void @f_321_0(ptr %p)
|
|
br label %for.cond115
|
|
|
|
for.cond115: ; preds = %for.cond115, %if.else
|
|
br label %for.cond115
|
|
}
|