blob: d3c71ab22a1e468b1539321ac06a1fd3eb7bbe02 [file]
; RUN: llvm-dis < %s.bc | FileCheck %s
; RUN: verify-uselistorder < %s.bc
; Test that old-style scalar tags used as !tbaa.struct field tags in older
; bitcode are auto-upgraded to the struct-path aware format on load, whatever
; instruction carries the !tbaa.struct. Null and already struct-path field
; tags are left unchanged; an immutability flag is kept.
;
define void @copy_memcpy(ptr %a, ptr %b) {
; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct [[TS:![0-9]+]]
call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct !0
ret void
}
define void @copy_memmove(ptr %a, ptr %b) {
; CHECK: call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct [[TS]]
call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 12, i1 false), !tbaa.struct !0
ret void
}
define i32 @access_load_store(ptr %p) {
; CHECK: %v = load i32, ptr %p, align 4, !tbaa.struct [[TS]]
; CHECK: store i32 %v, ptr %p, align 4, !tbaa.struct [[TS]]
%v = load i32, ptr %p, align 4, !tbaa.struct !0
store i32 %v, ptr %p, align 4, !tbaa.struct !0
ret i32 %v
}
define i32 @access_atomicrmw(ptr %p, i32 %v) {
; CHECK: %r = atomicrmw add ptr %p, i32 %v seq_cst, align 4, !tbaa.struct [[TS]]
%r = atomicrmw add ptr %p, i32 %v seq_cst, align 4, !tbaa.struct !0
ret i32 %r
}
define void @copy_flag_and_structpath(ptr %a, ptr %b) {
; CHECK: call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 8, i1 false), !tbaa.struct [[TS2:![0-9]+]]
call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 8, i1 false), !tbaa.struct !5
ret void
}
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
declare void @llvm.memmove.p0.p0.i64(ptr, ptr, i64, i1)
; Old-style 2-operand scalar field tags and a null field tag.
!0 = !{i64 0, i64 4, !1, i64 4, i64 4, !3, i64 8, i64 4, null}
!1 = !{!"int", !2}
!2 = !{!"omnipotent char", !4}
!3 = !{!"float", !2}
!4 = !{!"Simple C/C++ TBAA"}
; Old-style 3-operand (immutable) field tag and an already struct-path field tag.
!5 = !{i64 0, i64 4, !6, i64 4, i64 4, !7}
!6 = !{!"const int", !2, i64 1}
!7 = !{!8, !8, i64 0}
!8 = !{!"double", !2}
; CHECK: [[TS]] = !{i64 0, i64 4, [[TAG_INT:![0-9]+]], i64 4, i64 4, [[TAG_FLOAT:![0-9]+]], i64 8, i64 4, null}
; CHECK: [[TAG_INT]] = !{[[TYPE_INT:![0-9]+]], [[TYPE_INT]], i64 0}
; CHECK: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR:![0-9]+]]}
; CHECK: [[TYPE_CHAR]] = !{!"omnipotent char", !{{[0-9]+}}}
; CHECK: [[TAG_FLOAT]] = !{[[TYPE_FLOAT:![0-9]+]], [[TYPE_FLOAT]], i64 0}
; CHECK: [[TYPE_FLOAT]] = !{!"float", [[TYPE_CHAR]]}
; The immutability flag (i64 1) is preserved; the already struct-path tag is unchanged.
; CHECK: [[TS2]] = !{i64 0, i64 4, [[TAG_CONST:![0-9]+]], i64 4, i64 4, [[TAG_DOUBLE:![0-9]+]]}
; CHECK: [[TAG_CONST]] = !{[[TYPE_CONST:![0-9]+]], [[TYPE_CONST]], i64 0, i64 1}
; CHECK: [[TYPE_CONST]] = !{!"const int", [[TYPE_CHAR]]}
; CHECK: [[TAG_DOUBLE]] = !{[[TYPE_DOUBLE:![0-9]+]], [[TYPE_DOUBLE]], i64 0}
; CHECK: [[TYPE_DOUBLE]] = !{!"double", [[TYPE_CHAR]]}