xref: /llvm-project/llvm/test/Transforms/SCCP/ipsccp-clear-returned.ll (revision 16bb8c16aab32e2ee623a2b64d976548be247180)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s
3
4; if IPSCCP determines a function returns undef,
5; then the "returned" attribute of input arguments
6; should be cleared.
7
8define i32 @main() {
9; CHECK-LABEL: define i32 @main() {
10; CHECK-NEXT:  [[ENTRY:.*:]]
11; CHECK-NEXT:    [[CALL:%.*]] = call i32 @func_return_undef(i32 1)
12; CHECK-NEXT:    ret i32 1
13;
14entry:
15  %call = call i32 @func_return_undef(i32 returned 1)
16  ret i32 %call
17}
18
19define internal i32 @func_return_undef(i32 returned %arg) {
20; CHECK-LABEL: define internal i32 @func_return_undef(
21; CHECK-SAME: i32 [[ARG:%.*]]) {
22; CHECK-NEXT:  [[ENTRY:.*:]]
23; CHECK-NEXT:    ret i32 poison
24;
25entry:
26  ret i32 %arg
27}
28
29; The only case that users of zapped functions are non-call site
30; users is that they are blockaddr users. Skip them because we
31; want to remove the returned attribute for call sites
32define internal i32 @blockaddr_user(i1 %c, i32 returned %d) {
33; CHECK-LABEL: define internal i32 @blockaddr_user(
34; CHECK-SAME: i1 [[C:%.*]], i32 [[D:%.*]]) {
35; CHECK-NEXT:  [[ENTRY:.*:]]
36; CHECK-NEXT:    br i1 [[C]], label %[[BB1:.*]], label %[[BB2:.*]]
37; CHECK:       [[BB1]]:
38; CHECK-NEXT:    br label %[[BRANCH_BLOCK:.*]]
39; CHECK:       [[BB2]]:
40; CHECK-NEXT:    br label %[[BRANCH_BLOCK]]
41; CHECK:       [[BRANCH_BLOCK]]:
42; CHECK-NEXT:    [[ADDR:%.*]] = phi ptr [ blockaddress(@blockaddr_user, %[[TARGET1:.*]]), %[[BB1]] ], [ blockaddress(@blockaddr_user, %[[TARGET2:.*]]), %[[BB2]] ]
43; CHECK-NEXT:    indirectbr ptr [[ADDR]], [label %[[TARGET1]], label %target2]
44; CHECK:       [[TARGET1]]:
45; CHECK-NEXT:    br label %[[TARGET2]]
46; CHECK:       [[TARGET2]]:
47; CHECK-NEXT:    ret i32 poison
48;
49entry:
50  br i1 %c, label %bb1, label %bb2
51
52bb1:
53  br label %branch.block
54
55bb2:
56  br label %branch.block
57
58branch.block:
59  %addr = phi ptr [blockaddress(@blockaddr_user, %target1), %bb1], [blockaddress(@blockaddr_user, %target2), %bb2]
60  indirectbr ptr %addr, [label %target1, label %target2]
61
62target1:
63  br label %target2
64
65target2:
66  ret i32 %d
67}
68
69define i32 @call_blockaddr_user(i1 %c) {
70; CHECK-LABEL: define i32 @call_blockaddr_user(
71; CHECK-SAME: i1 [[C:%.*]]) {
72; CHECK-NEXT:    [[R:%.*]] = call i32 @blockaddr_user(i1 [[C]], i32 10)
73; CHECK-NEXT:    ret i32 10
74;
75  %r = call i32 @blockaddr_user(i1 %c, i32 returned 10)
76  ret i32 %r
77}
78