If we have two unknown sizes and one GEP operand and one non-GEP operand, then we currently simply return MayAlias. The comment says we can't do anything useful ... but we can! We can still check that the underlying objects are different (and do so for the GEP-GEP case). To reduce the compile-time impact, this a) checks this early, before doing the relatively expensive GEP decomposition that will not be used and b) doesn't do the check if the other operand is a phi or select. In that case, the phi/select will already recurse, so this would just do two slightly different recursive walks that arrive at the same roots. Compile-time is still a bit of a mixed bag: https://llvm-compile-time-tracker.com/compare.php?from=624af932a808b363a888139beca49f57313d9a3b&to=845356e14adbe651a553ed11318ddb5e79a24bcd&stat=instructions On average this is a small improvement, but sqlite with ThinLTO has a 0.5% regression (lencod has a 1% improvement). The BasicAA test case checks this by using two memsets with unknown size. However, the more interesting case where this is useful is the LoopVectorize test case, as analysis of accesses in loops tends to always us unknown sizes. Differential Revision: https://reviews.llvm.org/D92401
39 lines
1.3 KiB
LLVM
39 lines
1.3 KiB
LLVM
; This test ensures loop versioning does not produce an invalid dominator tree
|
|
; if the exit block of the loop (bb0) dominates the runtime check block
|
|
; (bb1 will become the runtime check block).
|
|
|
|
; RUN: opt -loop-distribute -enable-loop-distribute -verify-dom-info -S -o - %s > %t
|
|
; RUN: opt -loop-simplify -loop-distribute -enable-loop-distribute -verify-dom-info -S -o - %s > %t
|
|
; RUN: FileCheck --check-prefix CHECK-VERSIONING -input-file %t %s
|
|
|
|
; RUN: opt -loop-versioning -verify-dom-info -S -o - %s > %t
|
|
; RUN: opt -loop-simplify -loop-versioning -verify-dom-info -S -o - %s > %t
|
|
; RUN: FileCheck --check-prefix CHECK-VERSIONING -input-file %t %s
|
|
|
|
@c1 = external global i16
|
|
|
|
define void @f(i16 %a, [1 x i32]* %p) {
|
|
br label %bb0
|
|
|
|
bb0:
|
|
br label %bb1
|
|
|
|
bb1:
|
|
%tmp1 = load i16, i16* @c1
|
|
br label %bb2
|
|
|
|
bb2:
|
|
%tmp2 = phi i16 [ %tmp1, %bb1 ], [ %tmp3, %bb2 ]
|
|
%tmp4 = getelementptr inbounds [1 x i32], [1 x i32]* %p, i32 0, i32 4
|
|
store i32 1, i32* %tmp4
|
|
%tmp5 = getelementptr inbounds [1 x i32], [1 x i32]* %p, i32 0, i32 9
|
|
store i32 0, i32* %tmp5
|
|
%tmp3 = add i16 %tmp2, 1
|
|
store i16 %tmp2, i16* @c1
|
|
%tmp6 = icmp sle i16 %tmp3, 0
|
|
br i1 %tmp6, label %bb2, label %bb0
|
|
}
|
|
|
|
; Simple check to make sure loop versioning happened.
|
|
; CHECK-VERSIONING: bb2.lver.check:
|