llvm/test/Analysis/BasicAA/zext.ll
Michael Kruse 52ebe03cb0 [BasicAA] Use MayAlias instead of PartialAlias for fallback.
Using various methods, BasicAA tries to determine whether two
GetElementPtr memory locations alias when its base pointers are known
to be equal. When none of its heuristics are applicable, it falls back
to PartialAlias to, according to a comment, protect TBAA making a wrong
decision in case of unions and malloc. PartialAlias is not correct,
because a PartialAlias result implies that some, but not all, bytes
overlap which is not necessarily the case here.

AAResults returns the first analysis result that is not MayAlias.
BasicAA is always the first alias analysis. When it returns
PartialAlias, no other analysis is queried to give a more exact result
(which was the intention of returning PartialAlias instead of MayAlias).
For instance, ScopedAA could return a more accurate result.

The PartialAlias hack was introduced in r131781 (and re-applied in
r132632 after some reverts) to fix llvm.org/PR9971 where TBAA returns a
wrong NoAlias result due to a union. A test case for the malloc case
mentioned in the comment was not provided and I don't think it is
affected since it returns an omnipotent char anyway.

Since r303851 (https://reviews.llvm.org/D33328) clang does emit specific
TBAA for unions anymore (but "omnipotent char" instead). Hence, the
PartialAlias workaround is not required anymore.

This patch passes the test-suite and check-llvm/check-clang of a
self-hoisted build on x64.

Reviewed By: hfinkel

Differential Revision: https://reviews.llvm.org/D34318

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305938 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-21 18:25:37 +00:00

232 lines
7.1 KiB
LLVM

; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK-LABEL: test_with_zext
; CHECK: NoAlias: i8* %a, i8* %b
define void @test_with_zext() {
%1 = tail call i8* @malloc(i64 120)
%a = getelementptr inbounds i8, i8* %1, i64 8
%2 = getelementptr inbounds i8, i8* %1, i64 16
%3 = zext i32 3 to i64
%b = getelementptr inbounds i8, i8* %2, i64 %3
ret void
}
; CHECK-LABEL: test_with_lshr
; CHECK: NoAlias: i8* %a, i8* %b
define void @test_with_lshr(i64 %i) {
%1 = tail call i8* @malloc(i64 120)
%a = getelementptr inbounds i8, i8* %1, i64 8
%2 = getelementptr inbounds i8, i8* %1, i64 16
%3 = lshr i64 %i, 2
%b = getelementptr inbounds i8, i8* %2, i64 %3
ret void
}
; CHECK-LABEL: test_with_a_loop
; CHECK: NoAlias: i8* %a, i8* %b
define void @test_with_a_loop(i8* %mem) {
br label %for.loop
for.loop:
%i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
%a = getelementptr inbounds i8, i8* %mem, i64 8
%a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
%i.64 = zext i32 %i to i64
%b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
%i.plus1 = add nuw nsw i32 %i, 1
%cmp = icmp eq i32 %i.plus1, 10
br i1 %cmp, label %for.loop.exit, label %for.loop
for.loop.exit:
ret void
}
; CHECK-LABEL: test_with_varying_base_pointer_in_loop
; CHECK: NoAlias: i8* %a, i8* %b
define void @test_with_varying_base_pointer_in_loop(i8* %mem.orig) {
br label %for.loop
for.loop:
%mem = phi i8* [ %mem.orig, %0 ], [ %mem.plus1, %for.loop ]
%i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
%a = getelementptr inbounds i8, i8* %mem, i64 8
%a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
%i.64 = zext i32 %i to i64
%b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
%i.plus1 = add nuw nsw i32 %i, 1
%mem.plus1 = getelementptr inbounds i8, i8* %mem, i64 8
%cmp = icmp eq i32 %i.plus1, 10
br i1 %cmp, label %for.loop.exit, label %for.loop
for.loop.exit:
ret void
}
; CHECK-LABEL: test_sign_extension
; CHECK: MayAlias: i64* %b.i64, i8* %a
define void @test_sign_extension(i32 %p) {
%1 = tail call i8* @malloc(i64 120)
%p.64 = zext i32 %p to i64
%a = getelementptr inbounds i8, i8* %1, i64 %p.64
%p.minus1 = add i32 %p, -1
%p.minus1.64 = zext i32 %p.minus1 to i64
%b.i8 = getelementptr inbounds i8, i8* %1, i64 %p.minus1.64
%b.i64 = bitcast i8* %b.i8 to i64*
ret void
}
; CHECK-LABEL: test_fe_tools
; CHECK: MayAlias: i32* %a, i32* %b
define void @test_fe_tools([8 x i32]* %values) {
br label %reorder
for.loop:
%i = phi i32 [ 0, %reorder ], [ %i.next, %for.loop ]
%idxprom = zext i32 %i to i64
%b = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 %idxprom
%i.next = add nuw nsw i32 %i, 1
%1 = icmp eq i32 %i.next, 10
br i1 %1, label %for.loop.exit, label %for.loop
reorder:
%a = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 1
br label %for.loop
for.loop.exit:
ret void
}
@b = global i32 0, align 4
@d = global i32 0, align 4
; CHECK-LABEL: test_spec2006
; CHECK: MayAlias: i32** %x, i32** %y
define void @test_spec2006() {
%h = alloca [1 x [2 x i32*]], align 16
%d.val = load i32, i32* @d, align 4
%d.promoted = sext i32 %d.val to i64
%1 = icmp slt i32 %d.val, 2
br i1 %1, label %.lr.ph, label %3
.lr.ph: ; preds = %0
br label %2
; <label>:2 ; preds = %.lr.ph, %2
%i = phi i32 [ %d.val, %.lr.ph ], [ %i.plus1, %2 ]
%i.promoted = sext i32 %i to i64
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %d.promoted, i64 %i.promoted
%i.plus1 = add nsw i32 %i, 1
%cmp = icmp slt i32 %i.plus1, 2
br i1 %cmp, label %2, label %3
; <label>:3 ; preds = %._crit_edge, %0
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
ret void
}
; CHECK-LABEL: test_modulo_analysis_easy_case
; CHECK: NoAlias: i32** %x, i32** %y
define void @test_modulo_analysis_easy_case(i64 %i) {
%h = alloca [1 x [2 x i32*]], align 16
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i, i64 0
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
ret void
}
; CHECK-LABEL: test_modulo_analysis_in_loop
; CHECK: NoAlias: i32** %x, i32** %y
define void @test_modulo_analysis_in_loop() {
%h = alloca [1 x [2 x i32*]], align 16
br label %for.loop
for.loop:
%i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
%i.promoted = sext i32 %i to i64
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 0
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
%i.plus1 = add nsw i32 %i, 1
%cmp = icmp slt i32 %i.plus1, 2
br i1 %cmp, label %for.loop, label %for.loop.exit
for.loop.exit:
ret void
}
; CHECK-LABEL: test_modulo_analysis_with_global
; CHECK: MayAlias: i32** %x, i32** %y
define void @test_modulo_analysis_with_global() {
%h = alloca [1 x [2 x i32*]], align 16
%b = load i32, i32* @b, align 4
%b.promoted = sext i32 %b to i64
br label %for.loop
for.loop:
%i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
%i.promoted = sext i32 %i to i64
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 %b.promoted
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
%i.plus1 = add nsw i32 %i, 1
%cmp = icmp slt i32 %i.plus1, 2
br i1 %cmp, label %for.loop, label %for.loop.exit
for.loop.exit:
ret void
}
; CHECK-LABEL: test_const_eval
; CHECK: NoAlias: i8* %a, i8* %b
define void @test_const_eval(i8* %ptr, i64 %offset) {
%a = getelementptr inbounds i8, i8* %ptr, i64 %offset
%a.dup = getelementptr inbounds i8, i8* %ptr, i64 %offset
%three = zext i32 3 to i64
%b = getelementptr inbounds i8, i8* %a.dup, i64 %three
ret void
}
; CHECK-LABEL: test_const_eval_scaled
; CHECK: MustAlias: i8* %a, i8* %b
define void @test_const_eval_scaled(i8* %ptr) {
%three = zext i32 3 to i64
%six = mul i64 %three, 2
%a = getelementptr inbounds i8, i8* %ptr, i64 %six
%b = getelementptr inbounds i8, i8* %ptr, i64 6
ret void
}
; CHECK-LABEL: Function: foo
; CHECK: MustAlias: float* %arrayidx, float* %arrayidx4.84
define float @foo(i32 *%A, float %rend, float** %wayar) {
entry:
%x0 = load i32, i32* %A, align 4
%conv = sext i32 %x0 to i64
%mul = shl nsw i64 %conv, 3
%call = tail call i8* @malloc(i64 %mul)
%x1 = bitcast i8* %call to float*
%sub = add nsw i32 %x0, -1
%idxprom = sext i32 %sub to i64
%arrayidx = getelementptr inbounds float, float* %x1, i64 %idxprom
store float %rend, float* %arrayidx, align 8
%indvars.iv76.83 = add nsw i64 %conv, -1
%arrayidx4.84 = getelementptr inbounds float, float* %x1, i64 %indvars.iv76.83
%x4 = load float, float* %arrayidx4.84, align 8
ret float %x4
}
; Function Attrs: nounwind
declare noalias i8* @malloc(i64)