Files
clang-p2996/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
Jeremy Morse 0065d06760 [NFC][DebugInfo] Maintain RemoveDIs flag when attributor creates functions (#79143)
We're using this flag (IsNewDbgInfoFormat) to detect the boundaries in
LLVM of what's treating debug-info as intrinsics (i.e. dbg.value), and
what's using DPValue objects (the non-intrinsic replacement). The
attributor tends to create new wrapper functions and doesn't insert them
into Modules in the usual way, thus we have to manually update that flag
to signal what debug-info mode it's using.

I've added some --try-experimental-debuginfo-iterators RUN lines to
tests that would otherwise crash because of this, so that they're
exercised by our new-debuginfo-iterators buildbot.

NB: there's an attributor test with a dbg.value in it, however
attributes re-order themselves in RemoveDIs mode for various reasons, so
we're going to address that in a different patch.
2024-01-24 15:20:05 +00:00

119 lines
4.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
;; Test with RemoveDIs debug-info mode to exercise a potential crash path.
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=CHECK,CGSCC
define void @f() {
; TUNIT-LABEL: define {{[^@]+}}@f() {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 1
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 1
; TUNIT-NEXT: call void @g(i32 [[TMP0]])
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@f() {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: call void @g(i32 undef)
; CGSCC-NEXT: ret void
;
entry:
%a = alloca i32, align 1
call void @g(ptr %a)
ret void
}
define internal void @g(ptr %a) {
; CHECK: Function Attrs: memory(readwrite, argmem: none)
; CHECK-LABEL: define {{[^@]+}}@g
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32 [[TMP0]], ptr [[A_PRIV]], align 4
; CHECK-NEXT: [[AA:%.*]] = load i32, ptr [[A_PRIV]], align 1
; CHECK-NEXT: call void @z(i32 [[AA]])
; CHECK-NEXT: ret void
;
%aa = load i32, ptr %a, align 1
call void @z(i32 %aa)
ret void
}
declare void @z(i32)
; Test2
; Different alignemnt privatizable arguments
define internal i32 @test(ptr %X, ptr %Y) {
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@test
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
; CGSCC-NEXT: [[Y_PRIV:%.*]] = alloca i64, align 8
; CGSCC-NEXT: store i64 [[TMP0]], ptr [[Y_PRIV]], align 4
; CGSCC-NEXT: [[A:%.*]] = load i32, ptr [[X]], align 4
; CGSCC-NEXT: [[B:%.*]] = load i64, ptr [[Y_PRIV]], align 8
; CGSCC-NEXT: [[C:%.*]] = add i32 [[A]], 1
; CGSCC-NEXT: [[D:%.*]] = add i64 [[B]], 1
; CGSCC-NEXT: [[COND:%.*]] = icmp sgt i64 [[D]], -1
; CGSCC-NEXT: br i1 [[COND]], label [[RETURN1:%.*]], label [[RETURN2:%.*]]
; CGSCC: Return1:
; CGSCC-NEXT: ret i32 [[C]]
; CGSCC: Return2:
; CGSCC-NEXT: ret i32 [[A]]
;
%A = load i32, ptr %X
%B = load i64, ptr %Y
%C = add i32 %A, 1
%D = add i64 %B, 1
%cond = icmp sgt i64 %D, -1
br i1 %cond, label %Return1, label %Return2
Return1:
ret i32 %C
Return2:
ret i32 %A
}
define internal i32 @caller(ptr %A) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@caller
; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR2:[0-9]+]] {
; CGSCC-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
; CGSCC-NEXT: store i32 [[TMP0]], ptr [[A_PRIV]], align 4
; CGSCC-NEXT: [[C:%.*]] = call i32 @test(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_PRIV]], i64 noundef 1) #[[ATTR3:[0-9]+]]
; CGSCC-NEXT: ret i32 [[C]]
;
%B = alloca i64
store i64 1, ptr %B
%C = call i32 @test(ptr %A, ptr %B)
ret i32 %C
}
define i32 @callercaller() {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@callercaller
; TUNIT-SAME: () #[[ATTR1:[0-9]+]] {
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
; TUNIT-NEXT: ret i32 3
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@callercaller
; CGSCC-SAME: () #[[ATTR2]] {
; CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]]
; CGSCC-NEXT: ret i32 [[X]]
;
%B = alloca i32
store i32 2, ptr %B
%X = call i32 @caller(ptr %B)
ret i32 %X
}
;.
; TUNIT: attributes #[[ATTR0]] = { memory(readwrite, argmem: none) }
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0]] = { memory(readwrite, argmem: none) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR3]] = { nofree willreturn memory(read) }
; CGSCC: attributes #[[ATTR4]] = { nofree nosync willreturn }
;.