-
Notifications
You must be signed in to change notification settings - Fork 10.8k
/
return-argument.ll
132 lines (123 loc) · 5.87 KB
/
return-argument.ll
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
; 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-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -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
;; This function returns its second argument on all return statements
define internal i32* @incdec(i1 %C, i32* %V) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write)
; TUNIT-LABEL: define {{[^@]+}}@incdec
; TUNIT-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] {
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: T:
; TUNIT-NEXT: ret i32* [[V]]
; TUNIT: F:
; TUNIT-NEXT: ret i32* [[V]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@incdec
; CGSCC-SAME: (i1 [[C:%.*]], i32* nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] {
; CGSCC-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: T:
; CGSCC-NEXT: [[X1:%.*]] = add i32 [[X]], 1
; CGSCC-NEXT: store i32 [[X1]], i32* [[V]], align 4
; CGSCC-NEXT: ret i32* [[V]]
; CGSCC: F:
; CGSCC-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
; CGSCC-NEXT: store i32 [[X2]], i32* [[V]], align 4
; CGSCC-NEXT: ret i32* [[V]]
;
%X = load i32, i32* %V
br i1 %C, label %T, label %F
T: ; preds = %0
%X1 = add i32 %X, 1
store i32 %X1, i32* %V
ret i32* %V
F: ; preds = %0
%X2 = sub i32 %X, 1
store i32 %X2, i32* %V
ret i32* %V
}
;; This function returns its first argument as a part of a multiple return
;; value
define internal { i32, i32 } @foo(i32 %A, i32 %B) {
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@foo
; CGSCC-SAME: (i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] {
; CGSCC-NEXT: [[X:%.*]] = add i32 [[A]], [[B]]
; CGSCC-NEXT: [[Y:%.*]] = insertvalue { i32, i32 } undef, i32 [[A]], 0
; CGSCC-NEXT: [[Z:%.*]] = insertvalue { i32, i32 } [[Y]], i32 [[X]], 1
; CGSCC-NEXT: ret { i32, i32 } [[Z]]
;
%X = add i32 %A, %B
%Y = insertvalue { i32, i32 } undef, i32 %A, 0
%Z = insertvalue { i32, i32 } %Y, i32 %X, 1
ret { i32, i32 } %Z
}
define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@caller
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
; TUNIT-NEXT: [[Q:%.*]] = alloca i32, align 4
; TUNIT-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; TUNIT-NEXT: br label [[OK:%.*]]
; TUNIT: OK:
; TUNIT-NEXT: br label [[RET:%.*]]
; TUNIT: LPAD:
; TUNIT-NEXT: unreachable
; TUNIT: RET:
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree nosync nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@caller
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
; CGSCC-NEXT: [[Q:%.*]] = alloca i32, align 4
; CGSCC-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) #[[ATTR3:[0-9]+]]
; CGSCC-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR4:[0-9]+]]
; CGSCC-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
; CGSCC-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR3]]
; CGSCC-NEXT: br label [[OK:%.*]]
; CGSCC: OK:
; CGSCC-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
; CGSCC-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
; CGSCC-NEXT: store i32 [[Z]], i32* [[W]], align 4
; CGSCC-NEXT: br label [[RET:%.*]]
; CGSCC: LPAD:
; CGSCC-NEXT: unreachable
; CGSCC: RET:
; CGSCC-NEXT: ret void
;
%Q = alloca i32
;; Call incdec to see if %W is properly replaced by %Q
%W = call i32* @incdec(i1 %C, i32* %Q ) ; <i32> [#uses=1]
;; Call @foo twice, to prevent the arguments from propagating into the
;; function (so we can check the returned argument is properly
;; propagated per-caller).
%S1 = call { i32, i32 } @foo(i32 1, i32 2)
%X1 = extractvalue { i32, i32 } %S1, 0
%S2 = invoke { i32, i32 } @foo(i32 3, i32 4) to label %OK unwind label %LPAD
OK:
%X2 = extractvalue { i32, i32 } %S2, 0
%Z = add i32 %X1, %X2
store i32 %Z, i32* %W
br label %RET
LPAD:
%exn = landingpad {i8*, i32}
cleanup
br label %RET
RET:
ret void
}
declare i32 @__gxx_personality_v0(...)
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) }
; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn }
;.
; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR3]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR4]] = { willreturn }
;.
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CHECK: {{.*}}