|
7 | 7 |
|
8 | 8 | declare void @capture(ptr)
|
9 | 9 |
|
10 |
| -; In single-thread mode both loads and stores can be promoted. In multi-thread |
11 |
| -; mode only loads can be promoted, as a different thread might write to the |
12 |
| -; global. |
| 10 | +; Even in single-thread mode, can only perform load-only promotion for globals, |
| 11 | +; because we might not have provenance to write to the global. See |
| 12 | +; promote_global_noalias for an example of the issue. |
13 | 13 | define void @promote_global(i1 %c, i1 %c2) {
|
14 |
| -; MT-LABEL: @promote_global( |
15 |
| -; MT-NEXT: entry: |
16 |
| -; MT-NEXT: [[G_PROMOTED:%.*]] = load i32, ptr @g, align 4 |
17 |
| -; MT-NEXT: br label [[LOOP:%.*]] |
18 |
| -; MT: loop: |
19 |
| -; MT-NEXT: [[V_INC2:%.*]] = phi i32 [ [[V_INC1:%.*]], [[LATCH:%.*]] ], [ [[G_PROMOTED]], [[ENTRY:%.*]] ] |
20 |
| -; MT-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[LATCH]] |
21 |
| -; MT: if: |
22 |
| -; MT-NEXT: [[V_INC:%.*]] = add i32 [[V_INC2]], 1 |
23 |
| -; MT-NEXT: store i32 [[V_INC]], ptr @g, align 4 |
24 |
| -; MT-NEXT: br label [[LATCH]] |
25 |
| -; MT: latch: |
26 |
| -; MT-NEXT: [[V_INC1]] = phi i32 [ [[V_INC]], [[IF]] ], [ [[V_INC2]], [[LOOP]] ] |
27 |
| -; MT-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[LOOP]] |
28 |
| -; MT: exit: |
29 |
| -; MT-NEXT: ret void |
30 |
| -; |
31 |
| -; ST-LABEL: @promote_global( |
32 |
| -; ST-NEXT: entry: |
33 |
| -; ST-NEXT: [[G_PROMOTED:%.*]] = load i32, ptr @g, align 4 |
34 |
| -; ST-NEXT: br label [[LOOP:%.*]] |
35 |
| -; ST: loop: |
36 |
| -; ST-NEXT: [[V_INC2:%.*]] = phi i32 [ [[V_INC1:%.*]], [[LATCH:%.*]] ], [ [[G_PROMOTED]], [[ENTRY:%.*]] ] |
37 |
| -; ST-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[LATCH]] |
38 |
| -; ST: if: |
39 |
| -; ST-NEXT: [[V_INC:%.*]] = add i32 [[V_INC2]], 1 |
40 |
| -; ST-NEXT: br label [[LATCH]] |
41 |
| -; ST: latch: |
42 |
| -; ST-NEXT: [[V_INC1]] = phi i32 [ [[V_INC]], [[IF]] ], [ [[V_INC2]], [[LOOP]] ] |
43 |
| -; ST-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[LOOP]] |
44 |
| -; ST: exit: |
45 |
| -; ST-NEXT: [[V_INC1_LCSSA:%.*]] = phi i32 [ [[V_INC1]], [[LATCH]] ] |
46 |
| -; ST-NEXT: store i32 [[V_INC1_LCSSA]], ptr @g, align 4 |
47 |
| -; ST-NEXT: ret void |
| 14 | +; CHECK-LABEL: @promote_global( |
| 15 | +; CHECK-NEXT: entry: |
| 16 | +; CHECK-NEXT: [[G_PROMOTED:%.*]] = load i32, ptr @g, align 4 |
| 17 | +; CHECK-NEXT: br label [[LOOP:%.*]] |
| 18 | +; CHECK: loop: |
| 19 | +; CHECK-NEXT: [[V_INC2:%.*]] = phi i32 [ [[V_INC1:%.*]], [[LATCH:%.*]] ], [ [[G_PROMOTED]], [[ENTRY:%.*]] ] |
| 20 | +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[LATCH]] |
| 21 | +; CHECK: if: |
| 22 | +; CHECK-NEXT: [[V_INC:%.*]] = add i32 [[V_INC2]], 1 |
| 23 | +; CHECK-NEXT: store i32 [[V_INC]], ptr @g, align 4 |
| 24 | +; CHECK-NEXT: br label [[LATCH]] |
| 25 | +; CHECK: latch: |
| 26 | +; CHECK-NEXT: [[V_INC1]] = phi i32 [ [[V_INC]], [[IF]] ], [ [[V_INC2]], [[LOOP]] ] |
| 27 | +; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[LOOP]] |
| 28 | +; CHECK: exit: |
| 29 | +; CHECK-NEXT: ret void |
48 | 30 | ;
|
49 | 31 | entry:
|
50 | 32 | br label %loop
|
@@ -105,48 +87,26 @@ exit:
|
105 | 87 | ; if %c is false and %ptr == @g, then this should store 42 to the pointer.
|
106 | 88 | ; However, if we perform load+store promotion, then we would instead store the
|
107 | 89 | ; original value of the global.
|
108 |
| -; FIXME: This is a miscompile. |
109 | 90 | define void @promote_global_noalias(i1 %c, i1 %c2, ptr noalias %ptr) {
|
110 |
| -; MT-LABEL: @promote_global_noalias( |
111 |
| -; MT-NEXT: entry: |
112 |
| -; MT-NEXT: [[G_PROMOTED:%.*]] = load i32, ptr @g, align 4 |
113 |
| -; MT-NEXT: br label [[LOOP:%.*]] |
114 |
| -; MT: loop: |
115 |
| -; MT-NEXT: [[V_INC2:%.*]] = phi i32 [ [[V_INC1:%.*]], [[LATCH:%.*]] ], [ [[G_PROMOTED]], [[ENTRY:%.*]] ] |
116 |
| -; MT-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] |
117 |
| -; MT: if: |
118 |
| -; MT-NEXT: [[V_INC:%.*]] = add i32 [[V_INC2]], 1 |
119 |
| -; MT-NEXT: store i32 [[V_INC]], ptr @g, align 4 |
120 |
| -; MT-NEXT: br label [[LATCH]] |
121 |
| -; MT: else: |
122 |
| -; MT-NEXT: store i32 42, ptr [[PTR:%.*]], align 4 |
123 |
| -; MT-NEXT: br label [[LATCH]] |
124 |
| -; MT: latch: |
125 |
| -; MT-NEXT: [[V_INC1]] = phi i32 [ [[V_INC2]], [[ELSE]] ], [ [[V_INC]], [[IF]] ] |
126 |
| -; MT-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[LOOP]] |
127 |
| -; MT: exit: |
128 |
| -; MT-NEXT: ret void |
129 |
| -; |
130 |
| -; ST-LABEL: @promote_global_noalias( |
131 |
| -; ST-NEXT: entry: |
132 |
| -; ST-NEXT: [[G_PROMOTED:%.*]] = load i32, ptr @g, align 4 |
133 |
| -; ST-NEXT: br label [[LOOP:%.*]] |
134 |
| -; ST: loop: |
135 |
| -; ST-NEXT: [[V_INC2:%.*]] = phi i32 [ [[V_INC1:%.*]], [[LATCH:%.*]] ], [ [[G_PROMOTED]], [[ENTRY:%.*]] ] |
136 |
| -; ST-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] |
137 |
| -; ST: if: |
138 |
| -; ST-NEXT: [[V_INC:%.*]] = add i32 [[V_INC2]], 1 |
139 |
| -; ST-NEXT: br label [[LATCH]] |
140 |
| -; ST: else: |
141 |
| -; ST-NEXT: store i32 42, ptr [[PTR:%.*]], align 4 |
142 |
| -; ST-NEXT: br label [[LATCH]] |
143 |
| -; ST: latch: |
144 |
| -; ST-NEXT: [[V_INC1]] = phi i32 [ [[V_INC2]], [[ELSE]] ], [ [[V_INC]], [[IF]] ] |
145 |
| -; ST-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[LOOP]] |
146 |
| -; ST: exit: |
147 |
| -; ST-NEXT: [[V_INC1_LCSSA:%.*]] = phi i32 [ [[V_INC1]], [[LATCH]] ] |
148 |
| -; ST-NEXT: store i32 [[V_INC1_LCSSA]], ptr @g, align 4 |
149 |
| -; ST-NEXT: ret void |
| 91 | +; CHECK-LABEL: @promote_global_noalias( |
| 92 | +; CHECK-NEXT: entry: |
| 93 | +; CHECK-NEXT: [[G_PROMOTED:%.*]] = load i32, ptr @g, align 4 |
| 94 | +; CHECK-NEXT: br label [[LOOP:%.*]] |
| 95 | +; CHECK: loop: |
| 96 | +; CHECK-NEXT: [[V_INC2:%.*]] = phi i32 [ [[V_INC1:%.*]], [[LATCH:%.*]] ], [ [[G_PROMOTED]], [[ENTRY:%.*]] ] |
| 97 | +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] |
| 98 | +; CHECK: if: |
| 99 | +; CHECK-NEXT: [[V_INC:%.*]] = add i32 [[V_INC2]], 1 |
| 100 | +; CHECK-NEXT: store i32 [[V_INC]], ptr @g, align 4 |
| 101 | +; CHECK-NEXT: br label [[LATCH]] |
| 102 | +; CHECK: else: |
| 103 | +; CHECK-NEXT: store i32 42, ptr [[PTR:%.*]], align 4 |
| 104 | +; CHECK-NEXT: br label [[LATCH]] |
| 105 | +; CHECK: latch: |
| 106 | +; CHECK-NEXT: [[V_INC1]] = phi i32 [ [[V_INC2]], [[ELSE]] ], [ [[V_INC]], [[IF]] ] |
| 107 | +; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[LOOP]] |
| 108 | +; CHECK: exit: |
| 109 | +; CHECK-NEXT: ret void |
150 | 110 | ;
|
151 | 111 | entry:
|
152 | 112 | br label %loop
|
|
0 commit comments