1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -passes='simplifycfg<sink-common-insts;hoist-common-insts>,verify' -S %s | FileCheck %s
4 declare void @clobber1()
5 declare void @clobber2()
7 ; Do not try to sink the stores to the exit block, as this requires introducing
8 ; a select for the pointer operand. This is not allowed for swifterror pointers.
9 define swiftcc void @sink(ptr %arg, ptr swifterror %arg1, i1 %c) {
10 ; CHECK-LABEL: define swiftcc void @sink
11 ; CHECK-SAME: (ptr [[ARG:%.*]], ptr swifterror [[ARG1:%.*]], i1 [[C:%.*]]) {
13 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
15 ; CHECK-NEXT: call void @clobber1()
16 ; CHECK-NEXT: store ptr null, ptr [[ARG]], align 8
17 ; CHECK-NEXT: br label [[EXIT:%.*]]
19 ; CHECK-NEXT: call void @clobber2()
20 ; CHECK-NEXT: store ptr null, ptr [[ARG1]], align 8
21 ; CHECK-NEXT: br label [[EXIT]]
23 ; CHECK-NEXT: ret void
26 br i1 %c, label %then, label %else
30 store ptr null, ptr %arg, align 8
35 store ptr null, ptr %arg1, align 8
42 define swiftcc void @hoist_store(ptr %arg, ptr swifterror %arg1, i1 %c) {
43 ; CHECK-LABEL: define swiftcc void @hoist_store
44 ; CHECK-SAME: (ptr [[ARG:%.*]], ptr swifterror [[ARG1:%.*]], i1 [[C:%.*]]) {
46 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
48 ; CHECK-NEXT: store ptr null, ptr [[ARG]], align 8
49 ; CHECK-NEXT: call void @clobber1()
50 ; CHECK-NEXT: br label [[EXIT:%.*]]
52 ; CHECK-NEXT: store ptr null, ptr [[ARG1]], align 8
53 ; CHECK-NEXT: call void @clobber2()
54 ; CHECK-NEXT: br label [[EXIT]]
56 ; CHECK-NEXT: ret void
59 br i1 %c, label %then, label %else
62 store ptr null, ptr %arg, align 8
67 store ptr null, ptr %arg1, align 8
75 ; FIXME: currently simplifycfg tries to sink the load to the exit block and
76 ; introduces a select for the pointer operand. This is not allowed for
77 ; swifterror pointers.
78 define swiftcc ptr @sink_load(ptr %arg, ptr swifterror %arg1, i1 %c) {
80 br i1 %c, label %then, label %else
84 %l1 = load ptr, ptr %arg, align 8
89 %l2 = load ptr, ptr %arg1, align 8
93 %p = phi ptr [ %l1, %then ], [ %l2, %else ]
96 define swiftcc ptr @hoist_load(ptr %arg, ptr swifterror %arg1, i1 %c) {
97 ; CHECK-LABEL: define swiftcc ptr @hoist_load
98 ; CHECK-SAME: (ptr [[ARG:%.*]], ptr swifterror [[ARG1:%.*]], i1 [[C:%.*]]) {
100 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
102 ; CHECK-NEXT: [[L1:%.*]] = load ptr, ptr [[ARG]], align 8
103 ; CHECK-NEXT: call void @clobber1()
104 ; CHECK-NEXT: br label [[EXIT:%.*]]
106 ; CHECK-NEXT: [[L2:%.*]] = load ptr, ptr [[ARG1]], align 8
107 ; CHECK-NEXT: call void @clobber2()
108 ; CHECK-NEXT: br label [[EXIT]]
110 ; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[L1]], [[THEN]] ], [ [[L2]], [[ELSE]] ]
111 ; CHECK-NEXT: ret ptr [[P]]
114 br i1 %c, label %then, label %else
117 %l1 = load ptr, ptr %arg, align 8
118 call void @clobber1()
122 %l2 = load ptr, ptr %arg1, align 8
123 call void @clobber2()
127 %p = phi ptr [ %l1, %then ], [ %l2, %else ]