172 changes: 83 additions & 89 deletions llvm/test/Analysis/BasicAA/q.bad.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,57 @@ target triple = "thumbv7--linux-gnueabi"

; CHECK-LABEL: test_zext_sext_amounts255
; CHECK: NoAlias: i8* %a, i8* %b
define void @test_zext_sext_amounts255(i8* %mem) {
define void @test_zext_sext_amounts255(ptr %mem) {
%sext.1 = sext i8 255 to i16
%sext.zext.1 = zext i16 %sext.1 to i64
%sext.2 = sext i8 255 to i32
%sext.zext.2 = zext i32 %sext.2 to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1
%b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2
load i8, i8* %a
load i8, i8* %b
%a = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.1
%b = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.2
load i8, ptr %a
load i8, ptr %b
ret void
}

; CHECK-LABEL: test_zext_sext_amounts
; CHECK: MayAlias: i8* %a, i8* %b
; %a and %b only PartialAlias as, although they're both zext(sext(%num)) they'll extend the sign by a different
; number of bits before zext-ing the remainder.
define void @test_zext_sext_amounts(i8* %mem, i8 %num) {
define void @test_zext_sext_amounts(ptr %mem, i8 %num) {
%sext.1 = sext i8 %num to i16
%sext.zext.1 = zext i16 %sext.1 to i64
%sext.2 = sext i8 %num to i32
%sext.zext.2 = zext i32 %sext.2 to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1
%b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2
load i8, i8* %a
load i8, i8* %b
%a = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.1
%b = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.2
load i8, ptr %a
load i8, ptr %b
ret void
}

; CHECK-LABEL: based_on_pr18068
; CHECK: NoAlias: i8* %a, i8* %b
; CHECK: NoAlias: i8* %a, i8* %c
define void @based_on_pr18068(i32 %loaded, i8* %mem) {
define void @based_on_pr18068(i32 %loaded, ptr %mem) {
%loaded.64 = zext i32 %loaded to i64
%add1 = add i32 %loaded, -1 ; unsigned wraps unless %loaded == 0
%add1.64 = zext i32 %add1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias
%sub1 = sub i32 %loaded, 1 ; unsigned wraps iff %loaded == 0
%sub1.64 = zext i32 %sub1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias
%a = getelementptr inbounds i8, i8* %mem, i64 %loaded.64
%b = getelementptr inbounds i8, i8* %mem, i64 %add1.64
%c = getelementptr inbounds i8, i8* %mem, i64 %sub1.64
load i8, i8* %a
load i8, i8* %b
load i8, i8* %c
%a = getelementptr inbounds i8, ptr %mem, i64 %loaded.64
%b = getelementptr inbounds i8, ptr %mem, i64 %add1.64
%c = getelementptr inbounds i8, ptr %mem, i64 %sub1.64
load i8, ptr %a
load i8, ptr %b
load i8, ptr %c
ret void
}

; CHECK-LABEL: test_path_dependence
; CHECK: MayAlias: i8* %a, i8* %b
; CHECK: MustAlias: i8* %a, i8* %c
; CHECK: MayAlias: i8* %a, i8* %d
define void @test_path_dependence(i16 %p, i8* %mem) {
define void @test_path_dependence(i16 %p, ptr %mem) {
%p.minus1 = add i16 %p, -1 ; this will always unsigned-wrap, unless %p == 0
%p.minus1.64 = zext i16 %p.minus1 to i64
%p.64.again = add i64 %p.minus1.64, 1 ; either %p (if we wrapped) or 65536 (if we didn't)
Expand All @@ -68,153 +68,147 @@ define void @test_path_dependence(i16 %p, i8* %mem) {
%p.nsw.64.again = add nsw i64 %p.nsw.minus1.64, 1 ; ...and so this is very much != %p

%p.64 = zext i16 %p to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %p.64
%b = getelementptr inbounds i8, i8* %mem, i64 %p.64.again
%c = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.nuw.64.again
%d = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.64.again
load i8, i8* %a
load i8, i8* %b
load i8, i8* %c
load i8, i8* %d
%a = getelementptr inbounds i8, ptr %mem, i64 %p.64
%b = getelementptr inbounds i8, ptr %mem, i64 %p.64.again
%c = getelementptr inbounds i8, ptr %mem, i64 %p.nsw.nuw.64.again
%d = getelementptr inbounds i8, ptr %mem, i64 %p.nsw.64.again
load i8, ptr %a
load i8, ptr %b
load i8, ptr %c
load i8, ptr %d
ret void
}

; CHECK-LABEL: test_zext_sext_255
; CHECK: NoAlias: i8* %a, i8* %b
define void @test_zext_sext_255(i8* %mem) {
define void @test_zext_sext_255(ptr %mem) {
%zext.255 = zext i8 255 to i16 ; 0x00FF
%sext.255 = sext i8 255 to i16 ; 0xFFFF
%zext.sext.255 = zext i16 %sext.255 to i32 ; 0x0000FFFF
%sext.zext.255 = sext i16 %zext.255 to i32 ; 0x000000FF
%zext.zext.sext.255 = zext i32 %zext.sext.255 to i64
%zext.sext.zext.255 = zext i32 %sext.zext.255 to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.255
%b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.255
load i8, i8* %a
load i8, i8* %b
%a = getelementptr inbounds i8, ptr %mem, i64 %zext.zext.sext.255
%b = getelementptr inbounds i8, ptr %mem, i64 %zext.sext.zext.255
load i8, ptr %a
load i8, ptr %b
ret void
}

; CHECK-LABEL: test_zext_sext_num
; CHECK: MayAlias: i8* %a, i8* %b
; %a and %b NoAlias if %num == 255 (see @test_zext_sext_255), but %a and %b NoAlias for other values of %num (e.g. 0)
define void @test_zext_sext_num(i8* %mem, i8 %num) {
define void @test_zext_sext_num(ptr %mem, i8 %num) {
%zext.num = zext i8 %num to i16
%sext.num = sext i8 %num to i16
%zext.sext.num = zext i16 %sext.num to i32
%sext.zext.num = sext i16 %zext.num to i32
%zext.zext.sext.num = zext i32 %zext.sext.num to i64
%zext.sext.zext.num = zext i32 %sext.zext.num to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.num
%b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.num
load i8, i8* %a
load i8, i8* %b
%a = getelementptr inbounds i8, ptr %mem, i64 %zext.zext.sext.num
%b = getelementptr inbounds i8, ptr %mem, i64 %zext.sext.zext.num
load i8, ptr %a
load i8, ptr %b
ret void
}

; CHECK-LABEL: uncompressStream
; CHECK: MustAlias: i8* %a, i8* %b
; CHECK: NoAlias: i8* %a, i8* %c
define void @uncompressStream(i8* %mem) {
define void @uncompressStream(ptr %mem) {
%zext.255 = zext i8 255 to i32
%sext.255 = sext i8 255 to i32
%a = getelementptr inbounds i8, i8* %mem, i32 255
%b = getelementptr inbounds i8, i8* %mem, i32 %zext.255
%c = getelementptr inbounds i8, i8* %mem, i32 %sext.255
load i8, i8* %a
load i8, i8* %b
load i8, i8* %c
%a = getelementptr inbounds i8, ptr %mem, i32 255
%b = getelementptr inbounds i8, ptr %mem, i32 %zext.255
%c = getelementptr inbounds i8, ptr %mem, i32 %sext.255
load i8, ptr %a
load i8, ptr %b
load i8, ptr %c
ret void
}

; CHECK-LABEL: constantOffsetHeuristic_i3_i32
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
define void @constantOffsetHeuristic_i3_i32(i32* %mem, i3 %val) {
define void @constantOffsetHeuristic_i3_i32(ptr %mem, i3 %val) {
%zext.plus.7 = add nsw i3 %val, 7
%zext.plus.4 = add nsw i3 %val, 4
%zext.val = zext i3 %val to i32
%zext.4 = zext i3 %zext.plus.4 to i32
%zext.7 = zext i3 %zext.plus.7 to i32
%a = getelementptr inbounds i32, i32* %mem, i32 %zext.4
%b = getelementptr inbounds i32, i32* %mem, i32 %zext.7
%c = getelementptr inbounds i32, i32* %mem, i32 %zext.val
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
%a = getelementptr inbounds i32, ptr %mem, i32 %zext.4
%b = getelementptr inbounds i32, ptr %mem, i32 %zext.7
%c = getelementptr inbounds i32, ptr %mem, i32 %zext.val
load i32, ptr %a
load i32, ptr %b
load i32, ptr %c
ret void
}

; CHECK-LABEL: constantOffsetHeuristic_i8_i32
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
define void @constantOffsetHeuristic_i8_i32(i32* %mem, i8 %val) {
define void @constantOffsetHeuristic_i8_i32(ptr %mem, i8 %val) {
%zext.plus.7 = add nsw i8 %val, 7
%zext.plus.4 = add nsw i8 %val, 4
%zext.val = zext i8 %val to i32
%zext.4 = zext i8 %zext.plus.4 to i32
%zext.7 = zext i8 %zext.plus.7 to i32
%a = getelementptr inbounds i32, i32* %mem, i32 %zext.4
%b = getelementptr inbounds i32, i32* %mem, i32 %zext.7
%c = getelementptr inbounds i32, i32* %mem, i32 %zext.val
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
%a = getelementptr inbounds i32, ptr %mem, i32 %zext.4
%b = getelementptr inbounds i32, ptr %mem, i32 %zext.7
%c = getelementptr inbounds i32, ptr %mem, i32 %zext.val
load i32, ptr %a
load i32, ptr %b
load i32, ptr %c
ret void
}

; CHECK-LABEL: constantOffsetHeuristic_i3_i8
; CHECK: MayAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: MayAlias: i32* %b, i32* %c
define void @constantOffsetHeuristic_i3_i8(i8* %mem, i3 %val) {
; CHECK: MayAlias: i32* %a.8, i32* %b.8
; CHECK: NoAlias: i32* %a.8, i32* %c.8
; CHECK: MayAlias: i32* %b.8, i32* %c.8
define void @constantOffsetHeuristic_i3_i8(ptr %mem, i3 %val) {
%zext.plus.7 = add nsw i3 %val, 7
%zext.plus.4 = add nsw i3 %val, 4
%zext.val = zext i3 %val to i32
%zext.4 = zext i3 %zext.plus.4 to i32
%zext.7 = zext i3 %zext.plus.7 to i32
%a.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.4
%b.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.7
%c.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.val
%a = bitcast i8* %a.8 to i32*
%b = bitcast i8* %b.8 to i32*
%c = bitcast i8* %c.8 to i32*
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
%a.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.4
%b.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.7
%c.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.val
load i32, ptr %a.8
load i32, ptr %b.8
load i32, ptr %c.8
ret void
}

; CHECK-LABEL: constantOffsetHeuristic_i8_i8
; CHECK: MayAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
define void @constantOffsetHeuristic_i8_i8(i8* %mem, i8 %val) {
; CHECK: MayAlias: i32* %a.8, i32* %b.8
; CHECK: NoAlias: i32* %a.8, i32* %c.8
; CHECK: NoAlias: i32* %b.8, i32* %c.8
define void @constantOffsetHeuristic_i8_i8(ptr %mem, i8 %val) {
%zext.plus.7 = add nsw i8 %val, 7
%zext.plus.4 = add nsw i8 %val, 4
%zext.val = zext i8 %val to i32
%zext.4 = zext i8 %zext.plus.4 to i32
%zext.7 = zext i8 %zext.plus.7 to i32
%a.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.4
%b.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.7
%c.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.val
%a = bitcast i8* %a.8 to i32*
%b = bitcast i8* %b.8 to i32*
%c = bitcast i8* %c.8 to i32*
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
%a.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.4
%b.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.7
%c.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.val
load i32, ptr %a.8
load i32, ptr %b.8
load i32, ptr %c.8
ret void
}

; CHECK-LABEL: different_large_bitwidths
; MayAlias: i64* %p1, i64* %p2
define void @different_large_bitwidths(i8* %a, i64 %i, i128 %j) {
%p1 = getelementptr i8, i8* %a, i64 %i
%p2 = getelementptr i8, i8* %a, i128 %j
load i8, i8* %p1
load i8, i8* %p2
; MayAlias: ptr %p1, ptr %p2
define void @different_large_bitwidths(ptr %a, i64 %i, i128 %j) {
%p1 = getelementptr i8, ptr %a, i64 %i
%p2 = getelementptr i8, ptr %a, i128 %j
load i8, ptr %p1
load i8, ptr %p2
ret void
}
244 changes: 121 additions & 123 deletions llvm/test/Analysis/BasicAA/range.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,195 +5,193 @@

; CHECK: Function: t1
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t1(%struct.S* %s) {
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0
load i32, i32* %gep1
load i32, i32* %gep2
define void @t1(ptr %s) {
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 1
%gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 0
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t2_fwd
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t2_fwd(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0
load i32, i32* %gep1
load i32, i32* %gep2
define void @t2_fwd(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !0
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 0
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t2_rev
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t2_rev(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
load i32, i32* %gep1
load i32, i32* %gep2
define void @t2_rev(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !0
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 0
%gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t3_fwd
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t3_fwd(%struct.S* %s, i32* %q) {
%knownzero = load i32, i32* %q, !range !1
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %knownzero
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1
load i32, i32* %gep1
load i32, i32* %gep2
define void @t3_fwd(ptr %s, ptr %q) {
%knownzero = load i32, ptr %q, !range !1
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %knownzero
%gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 1
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t3_rev
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t3_rev(%struct.S* %s, i32* %q) {
%knownzero = load i32, i32* %q, !range !1
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %knownzero
load i32, i32* %gep1
load i32, i32* %gep2
define void @t3_rev(ptr %s, ptr %q) {
%knownzero = load i32, ptr %q, !range !1
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 1
%gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %knownzero
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: member_after
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @member_after(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 2
load i32, i32* %gep1
load i32, i32* %gep2
define void @member_after(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !0
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: member_after_rev
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @member_after_rev(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 2
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
load i32, i32* %gep1
load i32, i32* %gep2
define void @member_after_rev(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !0
%gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: member_before
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @member_before(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0
load i32, i32* %gep1
load i32, i32* %gep2
; CHECK: NoAlias: i32* %gep1, i32* %s
define void @member_before(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !0
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
load i32, ptr %gep1
load i32, ptr %s
ret void
}

; CHECK: Function: member_before_rev
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @member_before_rev(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
load i32, i32* %gep1
load i32, i32* %gep2
; CHECK: NoAlias: i32* %gep1, i32* %s
define void @member_before_rev(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !0
%gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
load i32, ptr %gep1
load i32, ptr %s
ret void
}

; CHECK-LABEL: Function: t5
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t5(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !3
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
define void @t5(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !3
%gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 0
load %struct.S2, ptr %s
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: Function: t6
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -16): i32* %gep2, %struct.S2* %s
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t6(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !3
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 3
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
define void @t6(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !3
%gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 3
load %struct.S2, ptr %s
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: Function: t7
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t7(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !4
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
define void @t7(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !4
%gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 0
load %struct.S2, ptr %s
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: Function: t8
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -24): i32* %gep2, %struct.S2* %s
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t8(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !4
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 1
load %struct.S2, %struct.S2* %s
load i32, i32* %q
load i32, i32* %gep1
load i32, i32* %gep2
define void @t8(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !4
%gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 1
load %struct.S2, ptr %s
load i32, ptr %q
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: Function: t9
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t9(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !5
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
define void @t9(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !5
%gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 0
load %struct.S2, ptr %s
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: Function: t10
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t10(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !5
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
define void @t10(ptr %s, ptr %q) {
%in_array = load i32, ptr %q, !range !5
%gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 0
load %struct.S2, ptr %s
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: Function: zeroext_index
; CHECK: MayAlias: i32* %gep, [256 x i32]* %s
define void @zeroext_index([256 x i32]* %s, i8* %q) {
%a = load i8, i8* %q, !range !6
define void @zeroext_index(ptr %s, ptr %q) {
%a = load i8, ptr %q, !range !6
%in_array = zext i8 %a to i32
%gep = getelementptr inbounds [256 x i32], [256 x i32]* %s, i64 0, i32 %in_array
load [256 x i32], [256 x i32]* %s
load i32, i32* %gep
%gep = getelementptr inbounds [256 x i32], ptr %s, i64 0, i32 %in_array
load [256 x i32], ptr %s
load i32, ptr %gep
ret void
}

Expand All @@ -205,18 +203,18 @@ define void @zeroext_index([256 x i32]* %s, i8* %q) {
; CHECK: MayAlias: i32* %p.02, i32* %p.2
; CHECK: NoAlias: i32* %p.01, i32* %p.3
; CHECK: NoAlias: i32* %p.02, i32* %p.3
define void @multiple(i32* %p, i32* %o1_ptr, i32* %o2_ptr) {
%o1 = load i32, i32* %o1_ptr, !range !0
%o2 = load i32, i32* %o2_ptr, !range !0
%p.01 = getelementptr i32, i32* %p, i32 %o1 ; p + [0, 1]
%p.02 = getelementptr i32, i32* %p.01, i32 %o2 ; p + [0, 2]
%p.2 = getelementptr i32, i32* %p, i32 2
%p.3 = getelementptr i32, i32* %p, i32 3
load i32, i32* %p
load i32, i32* %p.01
load i32, i32* %p.02
load i32, i32* %p.2
load i32, i32* %p.3
define void @multiple(ptr %p, ptr %o1_ptr, ptr %o2_ptr) {
%o1 = load i32, ptr %o1_ptr, !range !0
%o2 = load i32, ptr %o2_ptr, !range !0
%p.01 = getelementptr i32, ptr %p, i32 %o1 ; p + [0, 1]
%p.02 = getelementptr i32, ptr %p.01, i32 %o2 ; p + [0, 2]
%p.2 = getelementptr i32, ptr %p, i32 2
%p.3 = getelementptr i32, ptr %p, i32 3
load i32, ptr %p
load i32, ptr %p.01
load i32, ptr %p.02
load i32, ptr %p.2
load i32, ptr %p.3
ret void
}

Expand All @@ -228,16 +226,16 @@ define void @multiple(i32* %p, i32* %o1_ptr, i32* %o2_ptr) {
; CHECK: MayAlias: i8* %p, i8* %p.o.1
; CHECK: NoAlias: i8* %p.neg1, i8* %p.o.1
; CHECK: NoAlias: i8* %p.o, i8* %p.o.1
define void @benign_overflow(i8* %p, i64 %o) {
define void @benign_overflow(ptr %p, i64 %o) {
%c = icmp sge i64 %o, -1
call void @llvm.assume(i1 %c)
%p.neg1 = getelementptr i8, i8* %p, i64 -1
%p.o = getelementptr i8, i8* %p, i64 %o
%p.o.1 = getelementptr i8, i8* %p.o, i64 1
load i8, i8* %p
load i8, i8* %p.neg1
load i8, i8* %p.o
load i8, i8* %p.o.1
%p.neg1 = getelementptr i8, ptr %p, i64 -1
%p.o = getelementptr i8, ptr %p, i64 %o
%p.o.1 = getelementptr i8, ptr %p.o, i64 1
load i8, ptr %p
load i8, ptr %p.neg1
load i8, ptr %p.o
load i8, ptr %p.o.1
ret void
}

Expand Down
59 changes: 28 additions & 31 deletions llvm/test/Analysis/BasicAA/returned.ll
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,35 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; CHECK-DAG: NoAlias: i32* %x, i32* %z
; CHECK-DAG: NoAlias: i32* %y, i32* %z

; CHECK-DAG: MayAlias: %struct* %st, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10

; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8

; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10

define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0
%y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1
%sta = call %struct* @func2(%struct* %st)
%z = getelementptr inbounds %struct, %struct* %sta, i64 %k, i32 2
%y_12 = bitcast i32* %y to %struct*
%y_10 = bitcast i32* %y to i80*
%ya = call i32* @func1(i32* %y)
%y_8 = bitcast i32* %ya to i64*
load %struct, %struct* %st
load %struct, %struct* %sta
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
; CHECK-DAG: MayAlias: %struct* %st, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, i80* %y

; CHECK-DAG: MayAlias: %struct* %st, i64* %ya
; CHECK-DAG: MayAlias: i64* %ya, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %ya

; CHECK-DAG: MustAlias: %struct* %y, i32* %y
; CHECK-DAG: MustAlias: i32* %y, i64* %ya
; CHECK-DAG: MustAlias: i80* %y, i32* %y

define void @test_simple(ptr %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr inbounds %struct, ptr %st, i64 %i, i32 0
%y = getelementptr inbounds %struct, ptr %st, i64 %j, i32 1
%sta = call ptr @func2(ptr %st)
%z = getelementptr inbounds %struct, ptr %sta, i64 %k, i32 2
%ya = call ptr @func1(ptr %y)
load %struct, ptr %st
load %struct, ptr %sta
load i32, ptr %x
load i32, ptr %y
load i32, ptr %z
load %struct, ptr %y
load i80, ptr %y
load i64, ptr %ya
ret void
}

declare i32* @func1(i32* returned) nounwind
declare %struct* @func2(%struct* returned) nounwind
declare ptr @func1(ptr returned) nounwind
declare ptr @func2(ptr returned) nounwind

211 changes: 98 additions & 113 deletions llvm/test/Analysis/BasicAA/sequential-gep.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,191 +2,176 @@

; CHECK: Function: t1
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t1([8 x i32]* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
define void @t1(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
%gep1 = getelementptr [8 x i32], ptr %p, i32 2, i32 %addend
%gep2 = getelementptr [8 x i32], ptr %p, i32 2, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t2
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t2([8 x i32]* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
define void @t2(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
%gep1 = getelementptr [8 x i32], ptr %p, i32 1, i32 %addend
%gep2 = getelementptr [8 x i32], ptr %p, i32 0, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t3
; CHECK: MustAlias: i32* %gep1, i32* %gep2
define void @t3([8 x i32]* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
define void @t3(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
%gep1 = getelementptr [8 x i32], ptr %p, i32 0, i32 %add
%gep2 = getelementptr [8 x i32], ptr %p, i32 0, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t4
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t4([8 x i32]* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
define void @t4(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 %add, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
%gep1 = getelementptr [8 x i32], ptr %p, i32 1, i32 %addend
%gep2 = getelementptr [8 x i32], ptr %p, i32 %add, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK: Function: t5
; CHECK: MayAlias: i64* %bc, i32* %gep2
define void @t5([8 x i32]* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
; CHECK: MayAlias: i64* %gep1, i32* %gep2
define void @t5(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
%bc = bitcast i32* %gep1 to i64*
load i32, i32* %gep2
load i64, i64* %bc
%gep1 = getelementptr [8 x i32], ptr %p, i32 2, i32 %addend
%gep2 = getelementptr [8 x i32], ptr %p, i32 2, i32 %add
load i32, ptr %gep2
load i64, ptr %gep1
ret void
}

; CHECK-LABEL: Function: add_non_zero_simple
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @add_non_zero_simple(i32* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
define void @add_non_zero_simple(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add i32 %addend, %knownnonzero
%gep1 = getelementptr i32, i32* %p, i32 %addend
%gep2 = getelementptr i32, i32* %p, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
%gep1 = getelementptr i32, ptr %p, i32 %addend
%gep2 = getelementptr i32, ptr %p, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: Function: add_non_zero_different_scales
; CHECK: MayAlias: i32* %gep1, i16* %gep2
define void @add_non_zero_different_scales(i32* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
define void @add_non_zero_different_scales(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add i32 %addend, %knownnonzero
%p16 = bitcast i32* %p to i16*
%gep1 = getelementptr i32, i32* %p, i32 %addend
%gep2 = getelementptr i16, i16* %p16, i32 %add
load i32, i32* %gep1
load i16, i16* %gep2
%gep1 = getelementptr i32, ptr %p, i32 %addend
%gep2 = getelementptr i16, ptr %p, i32 %add
load i32, ptr %gep1
load i16, ptr %gep2
ret void
}

; CHECK-LABEL: Function: add_non_zero_different_sizes
; CHECK: NoAlias: i16* %gep1.16, i32* %gep2
; CHECK: NoAlias: i32* %gep1, i16* %gep2.16
; CHECK: NoAlias: i16* %gep1.16, i16* %gep2.16
; CHECK: MayAlias: i64* %gep1.64, i32* %gep2
; CHECK: MayAlias: i64* %gep1.64, i16* %gep2.16
; CHECK: MayAlias: i32* %gep1, i64* %gep2.64
; CHECK: MayAlias: i16* %gep1.16, i64* %gep2.64
; CHECK: MayAlias: i64* %gep1.64, i64* %gep2.64
define void @add_non_zero_different_sizes(i32* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
; CHECK: NoAlias: i16* %gep1, i32* %gep2
; CHECK: NoAlias: i32* %gep1, i16* %gep2
; CHECK: NoAlias: i16* %gep1, i16* %gep2
; CHECK: MayAlias: i64* %gep1, i32* %gep2
; CHECK: MayAlias: i64* %gep1, i16* %gep2
; CHECK: MayAlias: i32* %gep1, i64* %gep2
; CHECK: MayAlias: i16* %gep1, i64* %gep2
; CHECK: MayAlias: i64* %gep1, i64* %gep2
define void @add_non_zero_different_sizes(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add i32 %addend, %knownnonzero
%gep1 = getelementptr i32, i32* %p, i32 %addend
%gep2 = getelementptr i32, i32* %p, i32 %add
%gep1.16 = bitcast i32* %gep1 to i16*
%gep2.16 = bitcast i32* %gep2 to i16*
%gep1.64 = bitcast i32* %gep1 to i64*
%gep2.64 = bitcast i32* %gep2 to i64*
load i32, i32* %gep1
load i32, i32* %gep2
load i16, i16* %gep1.16
load i16, i16* %gep2.16
load i64, i64* %gep1.64
load i64, i64* %gep2.64
%gep1 = getelementptr i32, ptr %p, i32 %addend
%gep2 = getelementptr i32, ptr %p, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
load i16, ptr %gep1
load i16, ptr %gep2
load i64, ptr %gep1
load i64, ptr %gep2
ret void
}


; CHECK-LABEL: add_non_zero_with_offset
; MayAlias: i32* %gep1, i32* %gep2
; NoAlias: i16* %gep1.16, i16* %gep2.16
define void @add_non_zero_with_offset(i32* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
; MayAlias: ptr %gep1, ptr %gep2
; NoAlias: ptr %gep1, ptr %gep2
define void @add_non_zero_with_offset(ptr %p, i32 %addend, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%add = add i32 %addend, %knownnonzero
%p.8 = bitcast i32* %p to i8*
%p.off.8 = getelementptr i8, i8* %p.8, i32 2
%p.off = bitcast i8* %p.off.8 to i32*
%gep1 = getelementptr i32, i32* %p.off, i32 %addend
%gep2 = getelementptr i32, i32* %p, i32 %add
%gep1.16 = bitcast i32* %gep1 to i16*
%gep2.16 = bitcast i32* %gep2 to i16*
load i32, i32* %gep1
load i32, i32* %gep2
load i16, i16* %gep1.16
load i16, i16* %gep2.16
%p.off.8 = getelementptr i8, ptr %p, i32 2
%gep1 = getelementptr i32, ptr %p.off.8, i32 %addend
%gep2 = getelementptr i32, ptr %p, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
load i16, ptr %gep1
load i16, ptr %gep2
ret void
}

; CHECK-LABEL: Function: add_non_zero_assume
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @add_non_zero_assume(i32* %p, i32 %addend, i32 %knownnonzero) {
define void @add_non_zero_assume(ptr %p, i32 %addend, i32 %knownnonzero) {
%cmp = icmp ne i32 %knownnonzero, 0
call void @llvm.assume(i1 %cmp)
%add = add i32 %addend, %knownnonzero
%gep1 = getelementptr i32, i32* %p, i32 %addend
%gep2 = getelementptr i32, i32* %p, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
%gep1 = getelementptr i32, ptr %p, i32 %addend
%gep2 = getelementptr i32, ptr %p, i32 %add
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: non_zero_index_simple
; CHECK: NoAlias: i32* %gep, i32* %p
; CHECK: NoAlias: i16* %gep.16, i32* %p
; CHECK: MayAlias: i64* %gep.64, i32* %p
define void @non_zero_index_simple(i32* %p, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
%gep = getelementptr i32, i32* %p, i32 %knownnonzero
%gep.16 = bitcast i32* %gep to i16*
%gep.64 = bitcast i32* %gep to i64*
load i32, i32* %p
load i32, i32* %gep
load i16, i16* %gep.16
load i64, i64* %gep.64
; CHECK: NoAlias: i16* %gep, i32* %p
; CHECK: MayAlias: i64* %gep, i32* %p
define void @non_zero_index_simple(ptr %p, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%gep = getelementptr i32, ptr %p, i32 %knownnonzero
load i32, ptr %p
load i32, ptr %gep
load i16, ptr %gep
load i64, ptr %gep
ret void
}

; CHECK-LABEL: non_zero_index_with_offset
; CHECK: MayAlias: i32* %gep, i32* %p
; CHECK: NoAlias: i16* %gep.16, i32* %p
define void @non_zero_index_with_offset(i32* %p, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
%p.8 = bitcast i32* %p to i8*
%p.off.8 = getelementptr i8, i8* %p.8, i32 2
%p.off = bitcast i8* %p.off.8 to i32*
%gep = getelementptr i32, i32* %p.off, i32 %knownnonzero
%gep.16 = bitcast i32* %gep to i16*
load i32, i32* %p
load i32, i32* %gep
load i16, i16* %gep.16
; CHECK: NoAlias: i16* %gep, i32* %p
define void @non_zero_index_with_offset(ptr %p, ptr %q) {
%knownnonzero = load i32, ptr %q, !range !0
%p.off.8 = getelementptr i8, ptr %p, i32 2
%gep = getelementptr i32, ptr %p.off.8, i32 %knownnonzero
load i32, ptr %p
load i32, ptr %gep
load i16, ptr %gep
ret void
}

; CHECK-LABEL: non_zero_index_assume
; CHECK: NoAlias: i32* %gep, i32* %p
define void @non_zero_index_assume(i32* %p, i32 %knownnonzero) {
define void @non_zero_index_assume(ptr %p, i32 %knownnonzero) {
%cmp = icmp ne i32 %knownnonzero, 0
call void @llvm.assume(i1 %cmp)
%gep = getelementptr i32, i32* %p, i32 %knownnonzero
load i32, i32* %p
load i32, i32* %gep
%gep = getelementptr i32, ptr %p, i32 %knownnonzero
load i32, ptr %p
load i32, ptr %gep
ret void
}

Expand Down
233 changes: 112 additions & 121 deletions llvm/test/Analysis/BasicAA/struct-geps.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,40 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; CHECK-DAG: NoAlias: i32* %x, i32* %z
; CHECK-DAG: NoAlias: i32* %y, i32* %z

; CHECK-DAG: MayAlias: %struct* %st, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10

; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8

; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10

define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0
%y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1
%z = getelementptr inbounds %struct, %struct* %st, i64 %k, i32 2
%y_12 = bitcast i32* %y to %struct*
%y_10 = bitcast i32* %y to i80*
%y_8 = bitcast i32* %y to i64*
load %struct, %struct* %st
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
; CHECK-DAG: MayAlias: %struct* %st, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, i80* %y

; CHECK-DAG: MayAlias: %struct* %st, i64* %y
; CHECK-DAG: MayAlias: i64* %y, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y

; CHECK-DAG: MustAlias: %struct* %y, i32* %y
; CHECK-DAG: MustAlias: i64* %y, i32* %y
; CHECK-DAG: MustAlias: i80* %y, i32* %y

define void @test_simple(ptr %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr inbounds %struct, ptr %st, i64 %i, i32 0
%y = getelementptr inbounds %struct, ptr %st, i64 %j, i32 1
%z = getelementptr inbounds %struct, ptr %st, i64 %k, i32 2
load %struct, ptr %st
load i32, ptr %x
load i32, ptr %y
load i32, ptr %z
load %struct, ptr %y
load i80, ptr %y
load i64, ptr %y
ret void
}

; As the GEP is not inbounds, these pointers may alias due to overflow.
; CHECK-LABEL: test_not_inbounds
; CHECK: MayAlias: i32* %x, i32* %y
define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr %struct, %struct* %st, i64 %i, i32 0
%y = getelementptr %struct, %struct* %st, i64 %j, i32 1
load i32, i32* %x
load i32, i32* %y
define void @test_not_inbounds(ptr %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr %struct, ptr %st, i64 %i, i32 0
%y = getelementptr %struct, ptr %st, i64 %j, i32 1
load i32, ptr %x
load i32, ptr %y
ret void
}

Expand All @@ -64,32 +61,29 @@ define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) {
; CHECK-DAG: NoAlias: i32* %x, i32* %z
; CHECK-DAG: NoAlias: i32* %y, i32* %z

; CHECK-DAG: MayAlias: [1 x %struct]* %st, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10

; CHECK-DAG: MayAlias: [1 x %struct]* %st, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8

; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10

define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1) {
%x = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %i, i64 %i1, i32 0
%y = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %j, i64 %j1, i32 1
%z = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %k, i64 %k1, i32 2
%y_12 = bitcast i32* %y to %struct*
%y_10 = bitcast i32* %y to i80*
%y_8 = bitcast i32* %y to i64*
load [1 x %struct], [1 x %struct]* %st
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
; CHECK-DAG: MayAlias: [1 x %struct]* %st, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, i80* %y

; CHECK-DAG: MayAlias: [1 x %struct]* %st, i64* %y
; CHECK-DAG: MayAlias: i64* %y, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y

; CHECK-DAG: MustAlias: %struct* %y, i32* %y
; CHECK-DAG: MustAlias: i64* %y, i32* %y
; CHECK-DAG: MustAlias: i80* %y, i32* %y

define void @test_in_array(ptr %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1) {
%x = getelementptr inbounds [1 x %struct], ptr %st, i64 %i, i64 %i1, i32 0
%y = getelementptr inbounds [1 x %struct], ptr %st, i64 %j, i64 %j1, i32 1
%z = getelementptr inbounds [1 x %struct], ptr %st, i64 %k, i64 %k1, i32 2
load [1 x %struct], ptr %st
load i32, ptr %x
load i32, ptr %y
load i32, ptr %z
load %struct, ptr %y
load i80, ptr %y
load i64, ptr %y
ret void
}

Expand All @@ -103,32 +97,29 @@ define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1,
; CHECK-DAG: NoAlias: i32* %x, i32* %z
; CHECK-DAG: NoAlias: i32* %y, i32* %z

; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10

; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8

; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10

define void @test_in_3d_array([1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %j2, i64 %k2, i64 %i3, i64 %j3, i64 %k3) {
%x = getelementptr inbounds [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %i1, i64 %i2, i64 %i3, i32 0
%y = getelementptr inbounds [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st, i64 %j, i64 %j1, i64 %j2, i64 %j3, i32 1
%z = getelementptr inbounds [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st, i64 %k, i64 %k1, i64 %k2, i64 %k3, i32 2
%y_12 = bitcast i32* %y to %struct*
%y_10 = bitcast i32* %y to i80*
%y_8 = bitcast i32* %y to i64*
load [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, %struct* %y
; CHECK-DAG: MayAlias: i32* %x, i80* %y

; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y
; CHECK-DAG: MayAlias: i64* %y, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y

; CHECK-DAG: MustAlias: %struct* %y, i32* %y
; CHECK-DAG: MustAlias: i64* %y, i32* %y
; CHECK-DAG: MustAlias: i80* %y, i32* %y

define void @test_in_3d_array(ptr %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %j2, i64 %k2, i64 %i3, i64 %j3, i64 %k3) {
%x = getelementptr inbounds [1 x [1 x [1 x %struct]]], ptr %st, i64 %i, i64 %i1, i64 %i2, i64 %i3, i32 0
%y = getelementptr inbounds [1 x [1 x [1 x %struct]]], ptr %st, i64 %j, i64 %j1, i64 %j2, i64 %j3, i32 1
%z = getelementptr inbounds [1 x [1 x [1 x %struct]]], ptr %st, i64 %k, i64 %k1, i64 %k2, i64 %k3, i32 2
load [1 x [1 x [1 x %struct]]], ptr %st
load i32, ptr %x
load i32, ptr %y
load i32, ptr %z
load %struct, ptr %y
load i80, ptr %y
load i64, ptr %y
ret void
}

Expand All @@ -147,20 +138,20 @@ define void @test_in_3d_array([1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %j, i6
; CHECK-DAG: NoAlias: i32* %x2, i32* %z
; CHECK-DAG: NoAlias: i32* %y2, i32* %z

define void @test_same_underlying_object_same_indices(%struct* %st, i64 %i, i64 %j, i64 %k) {
%st2 = getelementptr inbounds %struct, %struct* %st, i32 10
%x2 = getelementptr inbounds %struct, %struct* %st2, i64 %i, i32 0
%y2 = getelementptr inbounds %struct, %struct* %st2, i64 %j, i32 1
%z2 = getelementptr inbounds %struct, %struct* %st2, i64 %k, i32 2
%x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0
%y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1
%z = getelementptr inbounds %struct, %struct* %st, i64 %k, i32 2
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load i32, i32* %x2
load i32, i32* %y2
load i32, i32* %z2
define void @test_same_underlying_object_same_indices(ptr %st, i64 %i, i64 %j, i64 %k) {
%st2 = getelementptr inbounds %struct, ptr %st, i32 10
%x2 = getelementptr inbounds %struct, ptr %st2, i64 %i, i32 0
%y2 = getelementptr inbounds %struct, ptr %st2, i64 %j, i32 1
%z2 = getelementptr inbounds %struct, ptr %st2, i64 %k, i32 2
%x = getelementptr inbounds %struct, ptr %st, i64 %i, i32 0
%y = getelementptr inbounds %struct, ptr %st, i64 %j, i32 1
%z = getelementptr inbounds %struct, ptr %st, i64 %k, i32 2
load i32, ptr %x
load i32, ptr %y
load i32, ptr %z
load i32, ptr %x2
load i32, ptr %y2
load i32, ptr %z2
ret void
}

Expand All @@ -179,20 +170,20 @@ define void @test_same_underlying_object_same_indices(%struct* %st, i64 %i, i64
; CHECK-DAG: NoAlias: i32* %x2, i32* %z
; CHECK-DAG: NoAlias: i32* %y2, i32* %z

define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %k2, i64 %j2) {
%st2 = getelementptr inbounds %struct, %struct* %st, i32 10
%x2 = getelementptr inbounds %struct, %struct* %st2, i64 %i2, i32 0
%y2 = getelementptr inbounds %struct, %struct* %st2, i64 %j2, i32 1
%z2 = getelementptr inbounds %struct, %struct* %st2, i64 %k2, i32 2
%x = getelementptr inbounds %struct, %struct* %st, i64 %i1, i32 0
%y = getelementptr inbounds %struct, %struct* %st, i64 %j1, i32 1
%z = getelementptr inbounds %struct, %struct* %st, i64 %k1, i32 2
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load i32, i32* %x2
load i32, i32* %y2
load i32, i32* %z2
define void @test_same_underlying_object_different_indices(ptr %st, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %k2, i64 %j2) {
%st2 = getelementptr inbounds %struct, ptr %st, i32 10
%x2 = getelementptr inbounds %struct, ptr %st2, i64 %i2, i32 0
%y2 = getelementptr inbounds %struct, ptr %st2, i64 %j2, i32 1
%z2 = getelementptr inbounds %struct, ptr %st2, i64 %k2, i32 2
%x = getelementptr inbounds %struct, ptr %st, i64 %i1, i32 0
%y = getelementptr inbounds %struct, ptr %st, i64 %j1, i32 1
%z = getelementptr inbounds %struct, ptr %st, i64 %k1, i32 2
load i32, ptr %x
load i32, ptr %y
load i32, ptr %z
load i32, ptr %x2
load i32, ptr %y2
load i32, ptr %z2
ret void
}

Expand All @@ -201,21 +192,21 @@ define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1

; CHECK-LABEL: test_struct_in_array
; CHECK-DAG: MustAlias: i32* %x, i32* %y
define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 1, i32 1, i32 0
%y = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 0, i32 1, i32 1
load i32, i32* %x
load i32, i32* %y
define void @test_struct_in_array(ptr %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr inbounds %struct2, ptr %st, i32 0, i32 1, i32 1, i32 0
%y = getelementptr inbounds %struct2, ptr %st, i32 0, i32 0, i32 1, i32 1
load i32, ptr %x
load i32, ptr %y
ret void
}

; PR27418 - Treat GEP indices with the same value but different types the same
; CHECK-LABEL: test_different_index_types
; CHECK: MustAlias: i16* %tmp1, i16* %tmp2
define void @test_different_index_types([2 x i16]* %arr) {
%tmp1 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i32 1
%tmp2 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i16 1
load i16, i16* %tmp1
load i16, i16* %tmp2
define void @test_different_index_types(ptr %arr) {
%tmp1 = getelementptr inbounds [2 x i16], ptr %arr, i16 0, i32 1
%tmp2 = getelementptr inbounds [2 x i16], ptr %arr, i16 0, i16 1
load i16, ptr %tmp1
load i16, ptr %tmp2
ret void
}
10 changes: 5 additions & 5 deletions llvm/test/Analysis/BasicAA/tail-byval.ll
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
; RUN: opt -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s

declare void @takebyval(i32* byval(i32) %p)
declare void @takebyval(ptr byval(i32) %p)

define i32 @tailbyval() {
entry:
%p = alloca i32
store i32 42, i32* %p
tail call void @takebyval(i32* byval(i32) %p)
%rv = load i32, i32* %p
store i32 42, ptr %p
tail call void @takebyval(ptr byval(i32) %p)
%rv = load i32, ptr %p
ret i32 %rv
}
; FIXME: This should be Just Ref.
; CHECK-LABEL: Function: tailbyval: 1 pointers, 1 call sites
; CHECK-NEXT: Both ModRef: Ptr: i32* %p <-> tail call void @takebyval(i32* byval(i32) %p)
; CHECK-NEXT: Both ModRef: Ptr: i32* %p <-> tail call void @takebyval(ptr byval(i32) %p)
213 changes: 105 additions & 108 deletions llvm/test/Analysis/BasicAA/vscale.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
define void @gep_alloca_const_offset_1() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
%gep1 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 1
load <vscale x 4 x i32>, ptr %alloc
load <vscale x 4 x i32>, ptr %gep1
load <vscale x 4 x i32>, ptr %gep2
ret void
}

Expand All @@ -23,11 +23,11 @@ define void @gep_alloca_const_offset_1() {
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
define void @gep_alloca_const_offset_2() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
%gep1 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 1
%gep2 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 1
load <vscale x 4 x i32>, ptr %alloc
load <vscale x 4 x i32>, ptr %gep1
load <vscale x 4 x i32>, ptr %gep2
ret void
}

Expand All @@ -37,11 +37,11 @@ define void @gep_alloca_const_offset_2() {
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %gep1, i32* %gep2
define void @gep_alloca_const_offset_3() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load i32, i32* %gep2
%gep1 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 0, i64 1
load <vscale x 4 x i32>, ptr %alloc
load <vscale x 4 x i32>, ptr %gep1
load i32, ptr %gep2
ret void
}

Expand All @@ -53,9 +53,9 @@ define void @gep_alloca_const_offset_4() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0, i64 0
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load i32, i32* %gep2
load <vscale x 4 x i32>, ptr %alloc
load <vscale x 4 x i32>, ptr %gep1
load i32, ptr %gep2
ret void
}

Expand All @@ -65,11 +65,11 @@ define void @gep_alloca_const_offset_4() {
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
define void @gep_alloca_symbolic_offset(i64 %idx1, i64 %idx2) {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 %idx1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 %idx2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
%gep1 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 %idx1
%gep2 = getelementptr <vscale x 4 x i32>, ptr %alloc, i64 %idx2
load <vscale x 4 x i32>, ptr %alloc
load <vscale x 4 x i32>, ptr %gep1
load <vscale x 4 x i32>, ptr %gep2
ret void
}

Expand All @@ -78,25 +78,25 @@ define void @gep_alloca_symbolic_offset(i64 %idx1, i64 %idx2) {
; CHECK-DAG: MayAlias: i32* %gep2, <vscale x 4 x i32>* %p
; TODO: AliasResult for gep1,gep2 can be improved as NoAlias
; CHECK-DAG: MayAlias: i32* %gep1, i32* %gep2
define void @gep_same_base_const_offset(<vscale x 4 x i32>* %p) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %gep1
load i32, i32* %gep2
define void @gep_same_base_const_offset(ptr %p) {
%gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 1
load <vscale x 4 x i32>, ptr %p
load i32, ptr %gep1
load i32, ptr %gep2
ret void
}

; CHECK-LABEL: gep_same_base_symbolic_offset
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %gep2, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
define void @gep_same_base_symbolic_offset(<vscale x 4 x i32>* %p, i64 %idx1, i64 %idx2) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 %idx1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 %idx2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
define void @gep_same_base_symbolic_offset(ptr %p, i64 %idx1, i64 %idx2) {
%gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 %idx1
%gep2 = getelementptr <vscale x 4 x i32>, ptr %p, i64 %idx2
load <vscale x 4 x i32>, ptr %p
load <vscale x 4 x i32>, ptr %gep1
load <vscale x 4 x i32>, ptr %gep2
ret void
}

Expand All @@ -107,51 +107,49 @@ define void @gep_same_base_symbolic_offset(<vscale x 4 x i32>* %p, i64 %idx1, i6
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %p2
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %gep2, <vscale x 4 x i32>* %p1
; CHECK-DAG: NoAlias: <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
define void @gep_different_base_const_offset(<vscale x 4 x i32>* noalias %p1, <vscale x 4 x i32>* noalias %p2) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p1, i64 1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p2, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
define void @gep_different_base_const_offset(ptr noalias %p1, ptr noalias %p2) {
%gep1 = getelementptr <vscale x 4 x i32>, ptr %p1, i64 1
%gep2 = getelementptr <vscale x 4 x i32>, ptr %p2, i64 1
load <vscale x 4 x i32>, ptr %p1
load <vscale x 4 x i32>, ptr %p2
load <vscale x 4 x i32>, ptr %gep1
load <vscale x 4 x i32>, ptr %gep2
ret void
}

; getelementptr + bitcast

; CHECK-LABEL: gep_bitcast_1
; CHECK-DAG: MustAlias: <vscale x 4 x i32>* %p, i32* %p2
; CHECK-DAG: MustAlias: i32* %p, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, i32* %p2
; CHECK-DAG: MayAlias: i32* %gep1, i32* %p
; CHECK-DAG: MayAlias: i32* %gep2, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, i32* %gep2
; CHECK-DAG: NoAlias: i32* %gep2, i32* %p2
define void @gep_bitcast_1(<vscale x 4 x i32>* %p) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
%p2 = bitcast <vscale x 4 x i32>* %p to i32*
%gep2 = getelementptr i32, i32* %p2, i64 4
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %gep1
load i32, i32* %gep2
load i32, i32* %p2
; CHECK-DAG: NoAlias: i32* %gep2, i32* %p
define void @gep_bitcast_1(ptr %p) {
%gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 0
%gep2 = getelementptr i32, ptr %p, i64 4
load <vscale x 4 x i32>, ptr %p
load i32, ptr %gep1
load i32, ptr %gep2
load i32, ptr %p
ret void
}

; CHECK-LABEL: gep_bitcast_2
; CHECK-DAG: MustAlias: <vscale x 4 x i32>* %p, <vscale x 4 x float>* %p2
; CHECK-DAG: MustAlias: <vscale x 4 x float>* %p, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x float>* %p2
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x float>* %p
; CHECK-DAG: MayAlias: float* %gep2, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, float* %gep2
; CHECK-DAG: MayAlias: float* %gep2, <vscale x 4 x float>* %p2
define void @gep_bitcast_2(<vscale x 4 x i32>* %p) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
%p2 = bitcast <vscale x 4 x i32>* %p to <vscale x 4 x float>*
%gep2 = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %p2, i64 1, i64 0
load i32, i32* %gep1
load float, float* %gep2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load <vscale x 4 x float>, <vscale x 4 x float>* %p2
; CHECK-DAG: MayAlias: float* %gep2, <vscale x 4 x float>* %p
define void @gep_bitcast_2(ptr %p) {
%gep1 = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 0
%gep2 = getelementptr <vscale x 4 x float>, ptr %p, i64 1, i64 0
load i32, ptr %gep1
load float, ptr %gep2
load <vscale x 4 x i32>, ptr %p
load <vscale x 4 x float>, ptr %p
ret void
}

Expand All @@ -164,31 +162,30 @@ define void @gep_bitcast_2(<vscale x 4 x i32>* %p) {
; CHECK-DAG: MayAlias: i32* %gep, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_1, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1
define void @gep_recursion_level_1(i32* %a, <vscale x 4 x i32>* %p) {
%gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, i32* %gep, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
define void @gep_recursion_level_1(ptr %a, ptr %p) {
%gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, ptr %gep, i64 1
load <vscale x 4 x i32>, ptr %p
load i32, ptr %a
load i32, ptr %gep
load i32, ptr %gep_rec_1
ret void
}

; CHECK-LABEL: gep_recursion_level_1_bitcast
; CHECK-DAG: MustAlias: i32* %a, <vscale x 4 x i32>* %p
; CHECK-DAG: MustAlias: i32* %a, <vscale x 4 x i32>* %a
; CHECK-DAG: MayAlias: i32* %a, i32* %gep
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1
; CHECK-DAG: MayAlias: i32* %gep, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %a, i32* %gep
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %a, i32* %gep_rec_1
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1
define void @gep_recursion_level_1_bitcast(i32* %a) {
%p = bitcast i32* %a to <vscale x 4 x i32>*
%gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, i32* %gep, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
define void @gep_recursion_level_1_bitcast(ptr %a) {
%gep = getelementptr <vscale x 4 x i32>, ptr %a, i64 1, i64 2
%gep_rec_1 = getelementptr i32, ptr %gep, i64 1
load <vscale x 4 x i32>, ptr %a
load i32, ptr %a
load i32, ptr %gep
load i32, ptr %gep_rec_1
ret void
}

Expand All @@ -203,15 +200,15 @@ define void @gep_recursion_level_1_bitcast(i32* %a) {
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_2
; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_2
define void @gep_recursion_level_2(i32* %a, <vscale x 4 x i32>* %p) {
%gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, i32* %gep, i64 1
%gep_rec_2 = getelementptr i32, i32* %gep_rec_1, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
load i32, i32* %gep_rec_2
define void @gep_recursion_level_2(ptr %a, ptr %p) {
%gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, ptr %gep, i64 1
%gep_rec_2 = getelementptr i32, ptr %gep_rec_1, i64 1
load <vscale x 4 x i32>, ptr %p
load i32, ptr %a
load i32, ptr %gep
load i32, ptr %gep_rec_1
load i32, ptr %gep_rec_2
ret void
}

Expand Down Expand Up @@ -253,22 +250,22 @@ define void @gep_recursion_level_2(i32* %a, <vscale x 4 x i32>* %p) {
; CHECK-DAG: NoAlias: i32* %gep_rec_4, i32* %gep_rec_6
; CHECK-DAG: NoAlias: i32* %gep_rec_5, i32* %gep_rec_6
; GEP max lookup depth was set to 6.
define void @gep_recursion_max_lookup_depth_reached(i32* %a, <vscale x 4 x i32>* %p) {
%gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, i32* %gep, i64 1
%gep_rec_2 = getelementptr i32, i32* %gep_rec_1, i64 1
%gep_rec_3 = getelementptr i32, i32* %gep_rec_2, i64 1
%gep_rec_4 = getelementptr i32, i32* %gep_rec_3, i64 1
%gep_rec_5 = getelementptr i32, i32* %gep_rec_4, i64 1
%gep_rec_6 = getelementptr i32, i32* %gep_rec_5, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
load i32, i32* %gep_rec_2
load i32, i32* %gep_rec_3
load i32, i32* %gep_rec_4
load i32, i32* %gep_rec_5
load i32, i32* %gep_rec_6
define void @gep_recursion_max_lookup_depth_reached(ptr %a, ptr %p) {
%gep = getelementptr <vscale x 4 x i32>, ptr %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, ptr %gep, i64 1
%gep_rec_2 = getelementptr i32, ptr %gep_rec_1, i64 1
%gep_rec_3 = getelementptr i32, ptr %gep_rec_2, i64 1
%gep_rec_4 = getelementptr i32, ptr %gep_rec_3, i64 1
%gep_rec_5 = getelementptr i32, ptr %gep_rec_4, i64 1
%gep_rec_6 = getelementptr i32, ptr %gep_rec_5, i64 1
load <vscale x 4 x i32>, ptr %p
load i32, ptr %a
load i32, ptr %gep
load i32, ptr %gep_rec_1
load i32, ptr %gep_rec_2
load i32, ptr %gep_rec_3
load i32, ptr %gep_rec_4
load i32, ptr %gep_rec_5
load i32, ptr %gep_rec_6
ret void
}
219 changes: 108 additions & 111 deletions llvm/test/Analysis/BasicAA/zext.ll

Large diffs are not rendered by default.