File: noundef.ll

package info (click to toggle)
llvm-toolchain-16 1%3A16.0.6-15~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,634,792 kB
  • sloc: cpp: 6,179,261; ansic: 1,216,205; asm: 741,319; python: 196,614; objc: 75,325; f90: 49,640; lisp: 32,396; pascal: 12,286; sh: 9,394; perl: 7,442; ml: 5,494; awk: 3,523; makefile: 2,723; javascript: 1,206; xml: 886; fortran: 581; cs: 573
file content (144 lines) | stat: -rw-r--r-- 4,992 bytes parent folder | download | duplicates (2)
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
133
134
135
136
137
138
139
140
141
142
143
144
; 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=1 -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

declare void @unknown()

declare void @bar(ptr)

define void @foo() {
; CHECK-LABEL: define {{[^@]+}}@foo() {
; CHECK-NEXT:    [[X:%.*]] = alloca i32, align 4
; CHECK-NEXT:    call void @unknown()
; CHECK-NEXT:    call void @bar(ptr noundef nonnull align 4 dereferenceable(4) [[X]])
; CHECK-NEXT:    ret void
;
  %x = alloca i32
  call void @unknown()
  call void @bar(ptr %x)
  ret void
}

define internal ptr @returned_dead() {
; CHECK-LABEL: define {{[^@]+}}@returned_dead() {
; CHECK-NEXT:    call void @unknown()
; CHECK-NEXT:    ret ptr undef
;
  call void @unknown()
  ret ptr null
}

define void @caller1() {
; CHECK-LABEL: define {{[^@]+}}@caller1() {
; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @returned_dead()
; CHECK-NEXT:    ret void
;
  call ptr @returned_dead()
  ret void
}

define internal void @argument_dead_callback_callee(ptr %c) {
; CHECK-LABEL: define {{[^@]+}}@argument_dead_callback_callee
; CHECK-SAME: (ptr noalias nocapture nofree readnone align 4294967296 [[C:%.*]]) {
; CHECK-NEXT:    call void @unknown()
; CHECK-NEXT:    ret void
;
  call void @unknown()
  ret void
}

define void @callback_caller() {
; TUNIT-LABEL: define {{[^@]+}}@callback_caller() {
; TUNIT-NEXT:    call void @callback_broker(ptr noundef @argument_dead_callback_callee, ptr noalias nocapture nofree readnone align 4294967296 undef)
; TUNIT-NEXT:    ret void
;
; CGSCC-LABEL: define {{[^@]+}}@callback_caller() {
; CGSCC-NEXT:    call void @callback_broker(ptr noundef @argument_dead_callback_callee, ptr noalias nocapture nofree noundef readnone align 4294967296 null)
; CGSCC-NEXT:    ret void
;
  call void @callback_broker(ptr @argument_dead_callback_callee, ptr null)
  ret void
}

; Drop the noundef if when we replace the call argument with `undef`. We use a
; varargs function as we cannot (yet) rewrite their signature. If we ever can,
; try to come up with a different scheme to verify the `noundef` is dropped if
; signature rewriting is not happening.
define internal void @callee_with_dead_noundef_arg(i1 noundef %create, ...) {
; TUNIT-LABEL: define {{[^@]+}}@callee_with_dead_noundef_arg
; TUNIT-SAME: (i1 [[CREATE:%.*]], ...) {
; TUNIT-NEXT:    call void @unknown()
; TUNIT-NEXT:    ret void
;
; CGSCC-LABEL: define {{[^@]+}}@callee_with_dead_noundef_arg
; CGSCC-SAME: (i1 noundef [[CREATE:%.*]], ...) {
; CGSCC-NEXT:    call void @unknown()
; CGSCC-NEXT:    ret void
;
  call void @unknown()
  ret void
}

define void @caller_with_unused_arg(i1 %c) {
; TUNIT-LABEL: define {{[^@]+}}@caller_with_unused_arg
; TUNIT-SAME: (i1 [[C:%.*]]) {
; TUNIT-NEXT:    call void (i1, ...) @callee_with_dead_noundef_arg(i1 undef)
; TUNIT-NEXT:    ret void
;
; CGSCC-LABEL: define {{[^@]+}}@caller_with_unused_arg
; CGSCC-SAME: (i1 noundef [[C:%.*]]) {
; CGSCC-NEXT:    call void (i1, ...) @callee_with_dead_noundef_arg(i1 noundef [[C]])
; CGSCC-NEXT:    ret void
;
  call void (i1, ...) @callee_with_dead_noundef_arg(i1 %c)
  ret void
}

define internal void @callee_with_dead_arg(i1 %create, ...) {
;
; CHECK-LABEL: define {{[^@]+}}@callee_with_dead_arg
; CHECK-SAME: (i1 [[CREATE:%.*]], ...) {
; CHECK-NEXT:  entry:
; CHECK-NEXT:    br label [[IF_THEN3:%.*]]
; CHECK:       if.then:
; CHECK-NEXT:    unreachable
; CHECK:       if.then3:
; CHECK-NEXT:    call void @unknown()
; CHECK-NEXT:    ret void
;
entry:
  br i1 %create, label %if.then3, label %if.then

if.then:                                          ; preds = %entry
  ret void

if.then3:                                         ; preds = %entry
  call void @unknown()
  ret void
}

; Drop the noundef if when we replace the call argument with `undef`. We use a
; varargs function as we cannot (yet) rewrite their signature. If we ever can,
; try to come up with a different scheme to verify the `noundef` is dropped if
; signature rewriting is not happening.
define void @caller_with_noundef_arg() {
;
; TUNIT-LABEL: define {{[^@]+}}@caller_with_noundef_arg() {
; TUNIT-NEXT:    call void (i1, ...) @callee_with_dead_arg(i1 undef)
; TUNIT-NEXT:    ret void
;
; CGSCC-LABEL: define {{[^@]+}}@caller_with_noundef_arg() {
; CGSCC-NEXT:    call void (i1, ...) @callee_with_dead_arg(i1 noundef true)
; CGSCC-NEXT:    ret void
;
  call void (i1, ...) @callee_with_dead_arg(i1 noundef true)
  ret void
}

declare !callback !0 void @callback_broker(ptr, ptr)
!1 = !{i64 0, i64 1, i1 false}
!0 = !{!1}
;.
; CHECK: [[META0:![0-9]+]] = !{!1}
; CHECK: [[META1:![0-9]+]] = !{i64 0, i64 1, i1 false}
;.