| 
3 | 3 | 
 
  | 
4 | 4 | declare void @clobber1()  | 
5 | 5 | declare void @clobber2()  | 
 | 6 | +declare swiftcc void @foo(ptr swifterror)  | 
 | 7 | +declare swiftcc void @bar(ptr swifterror, ptr)  | 
6 | 8 | 
 
  | 
7 | 9 | ; Do not try to sink the stores to the exit block, as this requires introducing  | 
8 | 10 | ; a select for the pointer operand. This is not allowed for swifterror pointers.  | 
 | 
76 | 78 | ; introduces a select for the pointer operand. This is not allowed for  | 
77 | 79 | ; swifterror pointers.  | 
78 | 80 | define swiftcc ptr @sink_load(ptr %arg, ptr swifterror %arg1, i1 %c) {  | 
 | 81 | +; CHECK-LABEL: define swiftcc ptr @sink_load  | 
 | 82 | +; CHECK-SAME: (ptr [[ARG:%.*]], ptr swifterror [[ARG1:%.*]], i1 [[C:%.*]]) {  | 
 | 83 | +; CHECK-NEXT:  bb:  | 
 | 84 | +; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]  | 
 | 85 | +; CHECK:       then:  | 
 | 86 | +; CHECK-NEXT:    call void @clobber1()  | 
 | 87 | +; CHECK-NEXT:    [[L1:%.*]] = load ptr, ptr [[ARG]], align 8  | 
 | 88 | +; CHECK-NEXT:    br label [[EXIT:%.*]]  | 
 | 89 | +; CHECK:       else:  | 
 | 90 | +; CHECK-NEXT:    call void @clobber2()  | 
 | 91 | +; CHECK-NEXT:    [[L2:%.*]] = load ptr, ptr [[ARG1]], align 8  | 
 | 92 | +; CHECK-NEXT:    br label [[EXIT]]  | 
 | 93 | +; CHECK:       exit:  | 
 | 94 | +; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[L1]], [[THEN]] ], [ [[L2]], [[ELSE]] ]  | 
 | 95 | +; CHECK-NEXT:    ret ptr [[P]]  | 
 | 96 | +;  | 
79 | 97 | bb:  | 
80 | 98 |   br i1 %c, label %then, label %else  | 
81 | 99 | 
 
  | 
@@ -127,3 +145,77 @@ exit:  | 
127 | 145 |   %p = phi ptr [ %l1, %then ], [ %l2, %else ]  | 
128 | 146 |   ret ptr %p  | 
129 | 147 | }  | 
 | 148 | + | 
 | 149 | + | 
 | 150 | +define swiftcc void @sink_call(i1 %c) {  | 
 | 151 | +; CHECK-LABEL: define swiftcc void @sink_call  | 
 | 152 | +; CHECK-SAME: (i1 [[C:%.*]]) {  | 
 | 153 | +; CHECK-NEXT:    [[TMP1:%.*]] = alloca swifterror ptr, align 8  | 
 | 154 | +; CHECK-NEXT:    [[TMP2:%.*]] = alloca swifterror ptr, align 8  | 
 | 155 | +; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]  | 
 | 156 | +; CHECK:       then:  | 
 | 157 | +; CHECK-NEXT:    call void @clobber1()  | 
 | 158 | +; CHECK-NEXT:    call swiftcc void @foo(ptr [[TMP2]])  | 
 | 159 | +; CHECK-NEXT:    br label [[EXIT:%.*]]  | 
 | 160 | +; CHECK:       else:  | 
 | 161 | +; CHECK-NEXT:    call void @clobber2()  | 
 | 162 | +; CHECK-NEXT:    call swiftcc void @foo(ptr [[TMP1]])  | 
 | 163 | +; CHECK-NEXT:    br label [[EXIT]]  | 
 | 164 | +; CHECK:       exit:  | 
 | 165 | +; CHECK-NEXT:    ret void  | 
 | 166 | +;  | 
 | 167 | +  %2 = alloca swifterror ptr, align 8  | 
 | 168 | +  %3 = alloca swifterror ptr, align 8  | 
 | 169 | +  br i1 %c, label %then, label %else  | 
 | 170 | + | 
 | 171 | +then:  | 
 | 172 | +  call void @clobber1()  | 
 | 173 | +  call swiftcc void @foo(ptr %3)  | 
 | 174 | +  br label %exit  | 
 | 175 | + | 
 | 176 | +else:  | 
 | 177 | +  call void @clobber2()  | 
 | 178 | +  call swiftcc void @foo(ptr %2)  | 
 | 179 | +  br label %exit  | 
 | 180 | + | 
 | 181 | +exit:  | 
 | 182 | +  ret void  | 
 | 183 | +}  | 
 | 184 | + | 
 | 185 | + | 
 | 186 | +define swiftcc void @safe_sink_call(i1 %c) {  | 
 | 187 | +; CHECK-LABEL: define swiftcc void @safe_sink_call  | 
 | 188 | +; CHECK-SAME: (i1 [[C:%.*]]) {  | 
 | 189 | +; CHECK-NEXT:    [[ERR:%.*]] = alloca swifterror ptr, align 8  | 
 | 190 | +; CHECK-NEXT:    [[A:%.*]] = alloca ptr, align 8  | 
 | 191 | +; CHECK-NEXT:    [[B:%.*]] = alloca ptr, align 8  | 
 | 192 | +; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]  | 
 | 193 | +; CHECK:       then:  | 
 | 194 | +; CHECK-NEXT:    call void @clobber1()  | 
 | 195 | +; CHECK-NEXT:    br label [[EXIT:%.*]]  | 
 | 196 | +; CHECK:       else:  | 
 | 197 | +; CHECK-NEXT:    call void @clobber2()  | 
 | 198 | +; CHECK-NEXT:    br label [[EXIT]]  | 
 | 199 | +; CHECK:       exit:  | 
 | 200 | +; CHECK-NEXT:    [[B_SINK:%.*]] = phi ptr [ [[B]], [[ELSE]] ], [ [[A]], [[THEN]] ]  | 
 | 201 | +; CHECK-NEXT:    call swiftcc void @bar(ptr [[ERR]], ptr [[B_SINK]])  | 
 | 202 | +; CHECK-NEXT:    ret void  | 
 | 203 | +;  | 
 | 204 | +  %err = alloca swifterror ptr, align 8  | 
 | 205 | +  %a = alloca ptr, align 8  | 
 | 206 | +  %b = alloca ptr, align 8  | 
 | 207 | +  br i1 %c, label %then, label %else  | 
 | 208 | + | 
 | 209 | +then:  | 
 | 210 | +  call void @clobber1()  | 
 | 211 | +  call swiftcc void @bar(ptr %err, ptr %a)  | 
 | 212 | +  br label %exit  | 
 | 213 | + | 
 | 214 | +else:  | 
 | 215 | +  call void @clobber2()  | 
 | 216 | +  call swiftcc void @bar(ptr %err, ptr %b)  | 
 | 217 | +  br label %exit  | 
 | 218 | + | 
 | 219 | +exit:  | 
 | 220 | +  ret void  | 
 | 221 | +}  | 
0 commit comments