Skip to content

Commit c6d1b19

Browse files
committed
[SimplifyCFG] Don't sink loads/stores with swifterror pointers.
swifterror pointers can only be used as pointer operands of load & store instructions (and as swifterror argument of a call). Sinking loads or stores with swifterror pointer operands would require introducing a select of of the pointer operands, which isn't allowed. Check for this condition in canSinkInstructions. Reviewed By: aschwaighofer Differential Revision: https://reviews.llvm.org/D158083
1 parent eaa518c commit c6d1b19

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1817,10 +1817,19 @@ static bool canSinkInstructions(
18171817
}
18181818

18191819
const Instruction *I0 = Insts.front();
1820-
for (auto *I : Insts)
1820+
for (auto *I : Insts) {
18211821
if (!I->isSameOperationAs(I0))
18221822
return false;
18231823

1824+
// swifterror pointers can only be used by a load or store; sinking a load
1825+
// or store would require introducing a select for the pointer operand,
1826+
// which isn't allowed for swifterror pointers.
1827+
if (isa<StoreInst>(I) && I->getOperand(1)->isSwiftError())
1828+
return false;
1829+
if (isa<LoadInst>(I) && I->getOperand(0)->isSwiftError())
1830+
return false;
1831+
}
1832+
18241833
// All instructions in Insts are known to be the same opcode. If they have a
18251834
// use, check that the only user is a PHI or in the same block as the
18261835
// instruction, because if a user is in the same block as an instruction we're

llvm/test/Transforms/SimplifyCFG/hoist-sink-swifterror-store.ll

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1-
; RUN: opt -passes='simplifycfg<sink-common-insts;hoist-common-insts>,verify' -disable-output %s
2-
3-
; XFAIL: *
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
43

54
declare void @clobber1()
65
declare void @clobber2()
76

8-
; FIXME: currently simplifycfg tries to sink the stores to the exit block and
9-
; introduces a select for the pointer operand. This is not allowed for
10-
; swifterror pointers.
11-
define swiftcc void @sink_store(ptr %arg, ptr swifterror %arg1, i1 %c) {
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:%.*]]) {
12+
; CHECK-NEXT: bb:
13+
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
14+
; CHECK: then:
15+
; CHECK-NEXT: call void @clobber1()
16+
; CHECK-NEXT: store ptr null, ptr [[ARG]], align 8
17+
; CHECK-NEXT: br label [[EXIT:%.*]]
18+
; CHECK: else:
19+
; CHECK-NEXT: call void @clobber2()
20+
; CHECK-NEXT: store ptr null, ptr [[ARG1]], align 8
21+
; CHECK-NEXT: br label [[EXIT]]
22+
; CHECK: exit:
23+
; CHECK-NEXT: ret void
24+
;
1225
bb:
1326
br i1 %c, label %then, label %else
1427

@@ -27,6 +40,21 @@ exit:
2740
}
2841

2942
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:%.*]]) {
45+
; CHECK-NEXT: bb:
46+
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
47+
; CHECK: then:
48+
; CHECK-NEXT: store ptr null, ptr [[ARG]], align 8
49+
; CHECK-NEXT: call void @clobber1()
50+
; CHECK-NEXT: br label [[EXIT:%.*]]
51+
; CHECK: else:
52+
; CHECK-NEXT: store ptr null, ptr [[ARG1]], align 8
53+
; CHECK-NEXT: call void @clobber2()
54+
; CHECK-NEXT: br label [[EXIT]]
55+
; CHECK: exit:
56+
; CHECK-NEXT: ret void
57+
;
3058
bb:
3159
br i1 %c, label %then, label %else
3260

@@ -66,6 +94,22 @@ exit:
6694
ret ptr %p
6795
}
6896
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:%.*]]) {
99+
; CHECK-NEXT: bb:
100+
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
101+
; CHECK: then:
102+
; CHECK-NEXT: [[L1:%.*]] = load ptr, ptr [[ARG]], align 8
103+
; CHECK-NEXT: call void @clobber1()
104+
; CHECK-NEXT: br label [[EXIT:%.*]]
105+
; CHECK: else:
106+
; CHECK-NEXT: [[L2:%.*]] = load ptr, ptr [[ARG1]], align 8
107+
; CHECK-NEXT: call void @clobber2()
108+
; CHECK-NEXT: br label [[EXIT]]
109+
; CHECK: exit:
110+
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[L1]], [[THEN]] ], [ [[L2]], [[ELSE]] ]
111+
; CHECK-NEXT: ret ptr [[P]]
112+
;
69113
bb:
70114
br i1 %c, label %then, label %else
71115

0 commit comments

Comments
 (0)