Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 1 | ; RUN: opt < %s -sroa -S | FileCheck %s |
Chandler Carruth | 43c8b46 | 2012-10-04 10:39:28 +0000 | [diff] [blame] | 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 3 | |
| 4 | define i32 @test1() { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 5 | ; CHECK-LABEL: @test1( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 6 | entry: |
| 7 | %a = alloca [2 x i32] |
| 8 | ; CHECK-NOT: alloca |
| 9 | |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 10 | %a0 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 0 |
| 11 | %a1 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 12 | store i32 0, i32* %a0 |
| 13 | store i32 1, i32* %a1 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 14 | %v0 = load i32, i32* %a0 |
| 15 | %v1 = load i32, i32* %a1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 16 | ; CHECK-NOT: store |
| 17 | ; CHECK-NOT: load |
| 18 | |
| 19 | %cond = icmp sle i32 %v0, %v1 |
| 20 | br i1 %cond, label %then, label %exit |
| 21 | |
| 22 | then: |
| 23 | br label %exit |
| 24 | |
| 25 | exit: |
| 26 | %phi = phi i32* [ %a1, %then ], [ %a0, %entry ] |
| 27 | ; CHECK: phi i32 [ 1, %{{.*}} ], [ 0, %{{.*}} ] |
| 28 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 29 | %result = load i32, i32* %phi |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 30 | ret i32 %result |
| 31 | } |
| 32 | |
| 33 | define i32 @test2() { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 34 | ; CHECK-LABEL: @test2( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 35 | entry: |
| 36 | %a = alloca [2 x i32] |
| 37 | ; CHECK-NOT: alloca |
| 38 | |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 39 | %a0 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 0 |
| 40 | %a1 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 41 | store i32 0, i32* %a0 |
| 42 | store i32 1, i32* %a1 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 43 | %v0 = load i32, i32* %a0 |
| 44 | %v1 = load i32, i32* %a1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 45 | ; CHECK-NOT: store |
| 46 | ; CHECK-NOT: load |
| 47 | |
| 48 | %cond = icmp sle i32 %v0, %v1 |
| 49 | %select = select i1 %cond, i32* %a1, i32* %a0 |
| 50 | ; CHECK: select i1 %{{.*}}, i32 1, i32 0 |
| 51 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 52 | %result = load i32, i32* %select |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 53 | ret i32 %result |
| 54 | } |
| 55 | |
| 56 | define i32 @test3(i32 %x) { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 57 | ; CHECK-LABEL: @test3( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 58 | entry: |
| 59 | %a = alloca [2 x i32] |
| 60 | ; CHECK-NOT: alloca |
| 61 | |
Chandler Carruth | 54e8f0b | 2012-10-01 01:49:22 +0000 | [diff] [blame] | 62 | ; Note that we build redundant GEPs here to ensure that having different GEPs |
| 63 | ; into the same alloca partation continues to work with PHI speculation. This |
| 64 | ; was the underlying cause of PR13926. |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 65 | %a0 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 0 |
| 66 | %a0b = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 0 |
| 67 | %a1 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 1 |
| 68 | %a1b = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 69 | store i32 0, i32* %a0 |
| 70 | store i32 1, i32* %a1 |
| 71 | ; CHECK-NOT: store |
| 72 | |
| 73 | switch i32 %x, label %bb0 [ i32 1, label %bb1 |
| 74 | i32 2, label %bb2 |
Chandler Carruth | 54e8f0b | 2012-10-01 01:49:22 +0000 | [diff] [blame] | 75 | i32 3, label %bb3 |
| 76 | i32 4, label %bb4 |
| 77 | i32 5, label %bb5 |
| 78 | i32 6, label %bb6 |
| 79 | i32 7, label %bb7 ] |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 80 | |
| 81 | bb0: |
| 82 | br label %exit |
| 83 | bb1: |
| 84 | br label %exit |
| 85 | bb2: |
| 86 | br label %exit |
| 87 | bb3: |
| 88 | br label %exit |
Chandler Carruth | 54e8f0b | 2012-10-01 01:49:22 +0000 | [diff] [blame] | 89 | bb4: |
| 90 | br label %exit |
| 91 | bb5: |
| 92 | br label %exit |
| 93 | bb6: |
| 94 | br label %exit |
| 95 | bb7: |
| 96 | br label %exit |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 97 | |
| 98 | exit: |
Chandler Carruth | 54e8f0b | 2012-10-01 01:49:22 +0000 | [diff] [blame] | 99 | %phi = phi i32* [ %a1, %bb0 ], [ %a0, %bb1 ], [ %a0, %bb2 ], [ %a1, %bb3 ], |
| 100 | [ %a1b, %bb4 ], [ %a0b, %bb5 ], [ %a0b, %bb6 ], [ %a1b, %bb7 ] |
| 101 | ; CHECK: phi i32 [ 1, %{{.*}} ], [ 0, %{{.*}} ], [ 0, %{{.*}} ], [ 1, %{{.*}} ], [ 1, %{{.*}} ], [ 0, %{{.*}} ], [ 0, %{{.*}} ], [ 1, %{{.*}} ] |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 102 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 103 | %result = load i32, i32* %phi |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 104 | ret i32 %result |
| 105 | } |
| 106 | |
| 107 | define i32 @test4() { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 108 | ; CHECK-LABEL: @test4( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 109 | entry: |
| 110 | %a = alloca [2 x i32] |
| 111 | ; CHECK-NOT: alloca |
| 112 | |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 113 | %a0 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 0 |
| 114 | %a1 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 115 | store i32 0, i32* %a0 |
| 116 | store i32 1, i32* %a1 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 117 | %v0 = load i32, i32* %a0 |
| 118 | %v1 = load i32, i32* %a1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 119 | ; CHECK-NOT: store |
| 120 | ; CHECK-NOT: load |
| 121 | |
| 122 | %cond = icmp sle i32 %v0, %v1 |
| 123 | %select = select i1 %cond, i32* %a0, i32* %a0 |
| 124 | ; CHECK-NOT: select |
| 125 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 126 | %result = load i32, i32* %select |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 127 | ret i32 %result |
| 128 | ; CHECK: ret i32 0 |
| 129 | } |
| 130 | |
| 131 | define i32 @test5(i32* %b) { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 132 | ; CHECK-LABEL: @test5( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 133 | entry: |
| 134 | %a = alloca [2 x i32] |
| 135 | ; CHECK-NOT: alloca |
| 136 | |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 137 | %a1 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 138 | store i32 1, i32* %a1 |
| 139 | ; CHECK-NOT: store |
| 140 | |
| 141 | %select = select i1 true, i32* %a1, i32* %b |
| 142 | ; CHECK-NOT: select |
| 143 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 144 | %result = load i32, i32* %select |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 145 | ; CHECK-NOT: load |
| 146 | |
| 147 | ret i32 %result |
| 148 | ; CHECK: ret i32 1 |
| 149 | } |
| 150 | |
Chandler Carruth | 225d4bd | 2012-09-21 23:36:40 +0000 | [diff] [blame] | 151 | declare void @f(i32*, i32*) |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 152 | |
| 153 | define i32 @test6(i32* %b) { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 154 | ; CHECK-LABEL: @test6( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 155 | entry: |
| 156 | %a = alloca [2 x i32] |
Chandler Carruth | 225d4bd | 2012-09-21 23:36:40 +0000 | [diff] [blame] | 157 | %c = alloca i32 |
| 158 | ; CHECK-NOT: alloca |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 159 | |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 160 | %a1 = getelementptr [2 x i32], [2 x i32]* %a, i64 0, i32 1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 161 | store i32 1, i32* %a1 |
| 162 | |
| 163 | %select = select i1 true, i32* %a1, i32* %b |
| 164 | %select2 = select i1 false, i32* %a1, i32* %b |
Chandler Carruth | 225d4bd | 2012-09-21 23:36:40 +0000 | [diff] [blame] | 165 | %select3 = select i1 false, i32* %c, i32* %b |
| 166 | ; CHECK: %[[select2:.*]] = select i1 false, i32* undef, i32* %b |
| 167 | ; CHECK: %[[select3:.*]] = select i1 false, i32* undef, i32* %b |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 168 | |
| 169 | ; Note, this would potentially escape the alloca pointer except for the |
| 170 | ; constant folding of the select. |
Chandler Carruth | 225d4bd | 2012-09-21 23:36:40 +0000 | [diff] [blame] | 171 | call void @f(i32* %select2, i32* %select3) |
| 172 | ; CHECK: call void @f(i32* %[[select2]], i32* %[[select3]]) |
| 173 | |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 174 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 175 | %result = load i32, i32* %select |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 176 | ; CHECK-NOT: load |
| 177 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 178 | %dead = load i32, i32* %c |
Chandler Carruth | 225d4bd | 2012-09-21 23:36:40 +0000 | [diff] [blame] | 179 | |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 180 | ret i32 %result |
| 181 | ; CHECK: ret i32 1 |
| 182 | } |
| 183 | |
| 184 | define i32 @test7() { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 185 | ; CHECK-LABEL: @test7( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 186 | ; CHECK-NOT: alloca |
| 187 | |
| 188 | entry: |
| 189 | %X = alloca i32 |
| 190 | br i1 undef, label %good, label %bad |
| 191 | |
| 192 | good: |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 193 | %Y1 = getelementptr i32, i32* %X, i64 0 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 194 | store i32 0, i32* %Y1 |
| 195 | br label %exit |
| 196 | |
| 197 | bad: |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 198 | %Y2 = getelementptr i32, i32* %X, i64 1 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 199 | store i32 0, i32* %Y2 |
| 200 | br label %exit |
| 201 | |
| 202 | exit: |
| 203 | %P = phi i32* [ %Y1, %good ], [ %Y2, %bad ] |
| 204 | ; CHECK: %[[phi:.*]] = phi i32 [ 0, %good ], |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 205 | %Z2 = load i32, i32* %P |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 206 | ret i32 %Z2 |
| 207 | ; CHECK: ret i32 %[[phi]] |
| 208 | } |
| 209 | |
| 210 | define i32 @test8(i32 %b, i32* %ptr) { |
| 211 | ; Ensure that we rewrite allocas to the used type when that use is hidden by |
| 212 | ; a PHI that can be speculated. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 213 | ; CHECK-LABEL: @test8( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 214 | ; CHECK-NOT: alloca |
| 215 | ; CHECK-NOT: load |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 216 | ; CHECK: %[[value:.*]] = load i32, i32* %ptr |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 217 | ; CHECK-NOT: load |
| 218 | ; CHECK: %[[result:.*]] = phi i32 [ undef, %else ], [ %[[value]], %then ] |
| 219 | ; CHECK-NEXT: ret i32 %[[result]] |
| 220 | |
| 221 | entry: |
| 222 | %f = alloca float |
| 223 | %test = icmp ne i32 %b, 0 |
| 224 | br i1 %test, label %then, label %else |
| 225 | |
| 226 | then: |
| 227 | br label %exit |
| 228 | |
| 229 | else: |
| 230 | %bitcast = bitcast float* %f to i32* |
| 231 | br label %exit |
| 232 | |
| 233 | exit: |
| 234 | %phi = phi i32* [ %bitcast, %else ], [ %ptr, %then ] |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 235 | %loaded = load i32, i32* %phi, align 4 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 236 | ret i32 %loaded |
| 237 | } |
| 238 | |
| 239 | define i32 @test9(i32 %b, i32* %ptr) { |
| 240 | ; Same as @test8 but for a select rather than a PHI node. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 241 | ; CHECK-LABEL: @test9( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 242 | ; CHECK-NOT: alloca |
| 243 | ; CHECK-NOT: load |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 244 | ; CHECK: %[[value:.*]] = load i32, i32* %ptr |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 245 | ; CHECK-NOT: load |
| 246 | ; CHECK: %[[result:.*]] = select i1 %{{.*}}, i32 undef, i32 %[[value]] |
| 247 | ; CHECK-NEXT: ret i32 %[[result]] |
| 248 | |
| 249 | entry: |
| 250 | %f = alloca float |
| 251 | store i32 0, i32* %ptr |
| 252 | %test = icmp ne i32 %b, 0 |
| 253 | %bitcast = bitcast float* %f to i32* |
| 254 | %select = select i1 %test, i32* %bitcast, i32* %ptr |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 255 | %loaded = load i32, i32* %select, align 4 |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 256 | ret i32 %loaded |
| 257 | } |
| 258 | |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 259 | define float @test10(i32 %b, float* %ptr) { |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 260 | ; Don't try to promote allocas which are not elligible for it even after |
| 261 | ; rewriting due to the necessity of inserting bitcasts when speculating a PHI |
| 262 | ; node. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 263 | ; CHECK-LABEL: @test10( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 264 | ; CHECK: %[[alloca:.*]] = alloca |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 265 | ; CHECK: %[[argvalue:.*]] = load float, float* %ptr |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 266 | ; CHECK: %[[cast:.*]] = bitcast double* %[[alloca]] to float* |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 267 | ; CHECK: %[[allocavalue:.*]] = load float, float* %[[cast]] |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 268 | ; CHECK: %[[result:.*]] = phi float [ %[[allocavalue]], %else ], [ %[[argvalue]], %then ] |
| 269 | ; CHECK-NEXT: ret float %[[result]] |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 270 | |
| 271 | entry: |
| 272 | %f = alloca double |
| 273 | store double 0.0, double* %f |
| 274 | %test = icmp ne i32 %b, 0 |
| 275 | br i1 %test, label %then, label %else |
| 276 | |
| 277 | then: |
| 278 | br label %exit |
| 279 | |
| 280 | else: |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 281 | %bitcast = bitcast double* %f to float* |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 282 | br label %exit |
| 283 | |
| 284 | exit: |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 285 | %phi = phi float* [ %bitcast, %else ], [ %ptr, %then ] |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 286 | %loaded = load float, float* %phi, align 4 |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 287 | ret float %loaded |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 288 | } |
| 289 | |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 290 | define float @test11(i32 %b, float* %ptr) { |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 291 | ; Same as @test10 but for a select rather than a PHI node. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 292 | ; CHECK-LABEL: @test11( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 293 | ; CHECK: %[[alloca:.*]] = alloca |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 294 | ; CHECK: %[[cast:.*]] = bitcast double* %[[alloca]] to float* |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 295 | ; CHECK: %[[allocavalue:.*]] = load float, float* %[[cast]] |
| 296 | ; CHECK: %[[argvalue:.*]] = load float, float* %ptr |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 297 | ; CHECK: %[[result:.*]] = select i1 %{{.*}}, float %[[allocavalue]], float %[[argvalue]] |
| 298 | ; CHECK-NEXT: ret float %[[result]] |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 299 | |
| 300 | entry: |
| 301 | %f = alloca double |
| 302 | store double 0.0, double* %f |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 303 | store float 0.0, float* %ptr |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 304 | %test = icmp ne i32 %b, 0 |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 305 | %bitcast = bitcast double* %f to float* |
| 306 | %select = select i1 %test, float* %bitcast, float* %ptr |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 307 | %loaded = load float, float* %select, align 4 |
Chandler Carruth | 435c4e0 | 2012-10-15 08:40:30 +0000 | [diff] [blame] | 308 | ret float %loaded |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 309 | } |
| 310 | |
| 311 | define i32 @test12(i32 %x, i32* %p) { |
| 312 | ; Ensure we don't crash or fail to nuke dead selects of allocas if no load is |
| 313 | ; never found. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 314 | ; CHECK-LABEL: @test12( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 315 | ; CHECK-NOT: alloca |
| 316 | ; CHECK-NOT: select |
| 317 | ; CHECK: ret i32 %x |
| 318 | |
| 319 | entry: |
| 320 | %a = alloca i32 |
| 321 | store i32 %x, i32* %a |
| 322 | %dead = select i1 undef, i32* %a, i32* %p |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 323 | %load = load i32, i32* %a |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 324 | ret i32 %load |
| 325 | } |
| 326 | |
| 327 | define i32 @test13(i32 %x, i32* %p) { |
| 328 | ; Ensure we don't crash or fail to nuke dead phis of allocas if no load is ever |
| 329 | ; found. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 330 | ; CHECK-LABEL: @test13( |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 331 | ; CHECK-NOT: alloca |
| 332 | ; CHECK-NOT: phi |
| 333 | ; CHECK: ret i32 %x |
| 334 | |
| 335 | entry: |
| 336 | %a = alloca i32 |
| 337 | store i32 %x, i32* %a |
| 338 | br label %loop |
| 339 | |
| 340 | loop: |
| 341 | %phi = phi i32* [ %p, %entry ], [ %a, %loop ] |
| 342 | br i1 undef, label %loop, label %exit |
| 343 | |
| 344 | exit: |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 345 | %load = load i32, i32* %a |
Chandler Carruth | 1b398ae | 2012-09-14 09:22:59 +0000 | [diff] [blame] | 346 | ret i32 %load |
| 347 | } |
Chandler Carruth | 8b907e8 | 2012-09-25 10:03:40 +0000 | [diff] [blame] | 348 | |
Chandler Carruth | 58e25d3 | 2013-07-24 12:12:17 +0000 | [diff] [blame] | 349 | define i32 @test14(i1 %b1, i1 %b2, i32* %ptr) { |
| 350 | ; Check for problems when there are both selects and phis and one is |
| 351 | ; speculatable toward promotion but the other is not. That should block all of |
| 352 | ; the speculation. |
| 353 | ; CHECK-LABEL: @test14( |
| 354 | ; CHECK: alloca |
| 355 | ; CHECK: alloca |
| 356 | ; CHECK: select |
| 357 | ; CHECK: phi |
| 358 | ; CHECK: phi |
| 359 | ; CHECK: select |
| 360 | ; CHECK: ret i32 |
| 361 | |
| 362 | entry: |
| 363 | %f = alloca i32 |
| 364 | %g = alloca i32 |
| 365 | store i32 0, i32* %f |
| 366 | store i32 0, i32* %g |
| 367 | %f.select = select i1 %b1, i32* %f, i32* %ptr |
| 368 | br i1 %b2, label %then, label %else |
| 369 | |
| 370 | then: |
| 371 | br label %exit |
| 372 | |
| 373 | else: |
| 374 | br label %exit |
| 375 | |
| 376 | exit: |
| 377 | %f.phi = phi i32* [ %f, %then ], [ %f.select, %else ] |
| 378 | %g.phi = phi i32* [ %g, %then ], [ %ptr, %else ] |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 379 | %f.loaded = load i32, i32* %f.phi |
Chandler Carruth | 58e25d3 | 2013-07-24 12:12:17 +0000 | [diff] [blame] | 380 | %g.select = select i1 %b1, i32* %g, i32* %g.phi |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 381 | %g.loaded = load i32, i32* %g.select |
Chandler Carruth | 58e25d3 | 2013-07-24 12:12:17 +0000 | [diff] [blame] | 382 | %result = add i32 %f.loaded, %g.loaded |
| 383 | ret i32 %result |
| 384 | } |
| 385 | |
Chandler Carruth | 8b907e8 | 2012-09-25 10:03:40 +0000 | [diff] [blame] | 386 | define i32 @PR13905() { |
| 387 | ; Check a pattern where we have a chain of dead phi nodes to ensure they are |
| 388 | ; deleted and promotion can proceed. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 389 | ; CHECK-LABEL: @PR13905( |
Chandler Carruth | 8b907e8 | 2012-09-25 10:03:40 +0000 | [diff] [blame] | 390 | ; CHECK-NOT: alloca i32 |
| 391 | ; CHECK: ret i32 undef |
| 392 | |
| 393 | entry: |
| 394 | %h = alloca i32 |
| 395 | store i32 0, i32* %h |
| 396 | br i1 undef, label %loop1, label %exit |
| 397 | |
| 398 | loop1: |
| 399 | %phi1 = phi i32* [ null, %entry ], [ %h, %loop1 ], [ %h, %loop2 ] |
| 400 | br i1 undef, label %loop1, label %loop2 |
| 401 | |
| 402 | loop2: |
| 403 | br i1 undef, label %loop1, label %exit |
| 404 | |
| 405 | exit: |
| 406 | %phi2 = phi i32* [ %phi1, %loop2 ], [ null, %entry ] |
| 407 | ret i32 undef |
| 408 | } |
| 409 | |
| 410 | define i32 @PR13906() { |
| 411 | ; Another pattern which can lead to crashes due to failing to clear out dead |
| 412 | ; PHI nodes or select nodes. This triggers subtly differently from the above |
| 413 | ; cases because the PHI node is (recursively) alive, but the select is dead. |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 414 | ; CHECK-LABEL: @PR13906( |
Chandler Carruth | 8b907e8 | 2012-09-25 10:03:40 +0000 | [diff] [blame] | 415 | ; CHECK-NOT: alloca |
| 416 | |
| 417 | entry: |
| 418 | %c = alloca i32 |
| 419 | store i32 0, i32* %c |
| 420 | br label %for.cond |
| 421 | |
| 422 | for.cond: |
| 423 | %d.0 = phi i32* [ undef, %entry ], [ %c, %if.then ], [ %d.0, %for.cond ] |
| 424 | br i1 undef, label %if.then, label %for.cond |
| 425 | |
| 426 | if.then: |
| 427 | %tmpcast.d.0 = select i1 undef, i32* %c, i32* %d.0 |
| 428 | br label %for.cond |
| 429 | } |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 430 | |
| 431 | define i64 @PR14132(i1 %flag) { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 432 | ; CHECK-LABEL: @PR14132( |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 433 | ; Here we form a PHI-node by promoting the pointer alloca first, and then in |
| 434 | ; order to promote the other two allocas, we speculate the load of the |
| 435 | ; now-phi-node-pointer. In doing so we end up loading a 64-bit value from an i8 |
Chandler Carruth | a1c54bb | 2013-03-14 11:32:24 +0000 | [diff] [blame] | 436 | ; alloca. While this is a bit dubious, we were asserting on trying to |
| 437 | ; rewrite it. The trick is that the code using the value may carefully take |
| 438 | ; steps to only use the not-undef bits, and so we need to at least loosely |
| 439 | ; support this.. |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 440 | entry: |
Chandler Carruth | ccffdaf | 2015-07-22 03:32:42 +0000 | [diff] [blame] | 441 | %a = alloca i64, align 8 |
| 442 | %b = alloca i8, align 8 |
| 443 | %ptr = alloca i64*, align 8 |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 444 | ; CHECK-NOT: alloca |
| 445 | |
| 446 | %ptr.cast = bitcast i64** %ptr to i8** |
Chandler Carruth | ccffdaf | 2015-07-22 03:32:42 +0000 | [diff] [blame] | 447 | store i64 0, i64* %a, align 8 |
| 448 | store i8 1, i8* %b, align 8 |
| 449 | store i64* %a, i64** %ptr, align 8 |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 450 | br i1 %flag, label %if.then, label %if.end |
| 451 | |
| 452 | if.then: |
Chandler Carruth | ccffdaf | 2015-07-22 03:32:42 +0000 | [diff] [blame] | 453 | store i8* %b, i8** %ptr.cast, align 8 |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 454 | br label %if.end |
Chandler Carruth | a1c54bb | 2013-03-14 11:32:24 +0000 | [diff] [blame] | 455 | ; CHECK-NOT: store |
| 456 | ; CHECK: %[[ext:.*]] = zext i8 1 to i64 |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 457 | |
| 458 | if.end: |
Chandler Carruth | ccffdaf | 2015-07-22 03:32:42 +0000 | [diff] [blame] | 459 | %tmp = load i64*, i64** %ptr, align 8 |
| 460 | %result = load i64, i64* %tmp, align 8 |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 461 | ; CHECK-NOT: load |
Chandler Carruth | a1c54bb | 2013-03-14 11:32:24 +0000 | [diff] [blame] | 462 | ; CHECK: %[[result:.*]] = phi i64 [ %[[ext]], %if.then ], [ 0, %entry ] |
Chandler Carruth | 3e994a2 | 2012-11-20 10:02:19 +0000 | [diff] [blame] | 463 | |
| 464 | ret i64 %result |
| 465 | ; CHECK-NEXT: ret i64 %[[result]] |
| 466 | } |
Chandler Carruth | 83ea195 | 2013-07-24 09:47:28 +0000 | [diff] [blame] | 467 | |
| 468 | define float @PR16687(i64 %x, i1 %flag) { |
| 469 | ; CHECK-LABEL: @PR16687( |
| 470 | ; Check that even when we try to speculate the same phi twice (in two slices) |
| 471 | ; on an otherwise promotable construct, we don't get ahead of ourselves and try |
| 472 | ; to promote one of the slices prior to speculating it. |
| 473 | |
| 474 | entry: |
| 475 | %a = alloca i64, align 8 |
| 476 | store i64 %x, i64* %a |
| 477 | br i1 %flag, label %then, label %else |
| 478 | ; CHECK-NOT: alloca |
| 479 | ; CHECK-NOT: store |
| 480 | ; CHECK: %[[lo:.*]] = trunc i64 %x to i32 |
| 481 | ; CHECK: %[[shift:.*]] = lshr i64 %x, 32 |
| 482 | ; CHECK: %[[hi:.*]] = trunc i64 %[[shift]] to i32 |
| 483 | |
| 484 | then: |
| 485 | %a.f = bitcast i64* %a to float* |
| 486 | br label %end |
| 487 | ; CHECK: %[[lo_cast:.*]] = bitcast i32 %[[lo]] to float |
| 488 | |
| 489 | else: |
| 490 | %a.raw = bitcast i64* %a to i8* |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 491 | %a.raw.4 = getelementptr i8, i8* %a.raw, i64 4 |
Chandler Carruth | 83ea195 | 2013-07-24 09:47:28 +0000 | [diff] [blame] | 492 | %a.raw.4.f = bitcast i8* %a.raw.4 to float* |
| 493 | br label %end |
| 494 | ; CHECK: %[[hi_cast:.*]] = bitcast i32 %[[hi]] to float |
| 495 | |
| 496 | end: |
| 497 | %a.phi.f = phi float* [ %a.f, %then ], [ %a.raw.4.f, %else ] |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 498 | %f = load float, float* %a.phi.f |
Chandler Carruth | 83ea195 | 2013-07-24 09:47:28 +0000 | [diff] [blame] | 499 | ret float %f |
| 500 | ; CHECK: %[[phi:.*]] = phi float [ %[[lo_cast]], %then ], [ %[[hi_cast]], %else ] |
| 501 | ; CHECK-NOT: load |
| 502 | ; CHECK: ret float %[[phi]] |
| 503 | } |
Jingyue Wu | ec33fa9 | 2014-08-22 22:45:57 +0000 | [diff] [blame] | 504 | |
| 505 | ; Verifies we fixed PR20425. We should be able to promote all alloca's to |
| 506 | ; registers in this test. |
| 507 | ; |
| 508 | ; %0 = slice |
| 509 | ; %1 = slice |
| 510 | ; %2 = phi(%0, %1) // == slice |
| 511 | define float @simplify_phi_nodes_that_equal_slice(i1 %cond, float* %temp) { |
| 512 | ; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice( |
| 513 | entry: |
| 514 | %arr = alloca [4 x float], align 4 |
| 515 | ; CHECK-NOT: alloca |
| 516 | br i1 %cond, label %then, label %else |
| 517 | |
| 518 | then: |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 519 | %0 = getelementptr inbounds [4 x float], [4 x float]* %arr, i64 0, i64 3 |
Jingyue Wu | ec33fa9 | 2014-08-22 22:45:57 +0000 | [diff] [blame] | 520 | store float 1.000000e+00, float* %0, align 4 |
| 521 | br label %merge |
| 522 | |
| 523 | else: |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 524 | %1 = getelementptr inbounds [4 x float], [4 x float]* %arr, i64 0, i64 3 |
Jingyue Wu | ec33fa9 | 2014-08-22 22:45:57 +0000 | [diff] [blame] | 525 | store float 2.000000e+00, float* %1, align 4 |
| 526 | br label %merge |
| 527 | |
| 528 | merge: |
| 529 | %2 = phi float* [ %0, %then ], [ %1, %else ] |
| 530 | store float 0.000000e+00, float* %temp, align 4 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 531 | %3 = load float, float* %2, align 4 |
Jingyue Wu | ec33fa9 | 2014-08-22 22:45:57 +0000 | [diff] [blame] | 532 | ret float %3 |
| 533 | } |
| 534 | |
| 535 | ; A slightly complicated example for PR20425. |
| 536 | ; |
| 537 | ; %0 = slice |
| 538 | ; %1 = phi(%0) // == slice |
| 539 | ; %2 = slice |
| 540 | ; %3 = phi(%1, %2) // == slice |
| 541 | define float @simplify_phi_nodes_that_equal_slice_2(i1 %cond, float* %temp) { |
| 542 | ; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice_2( |
| 543 | entry: |
| 544 | %arr = alloca [4 x float], align 4 |
| 545 | ; CHECK-NOT: alloca |
| 546 | br i1 %cond, label %then, label %else |
| 547 | |
| 548 | then: |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 549 | %0 = getelementptr inbounds [4 x float], [4 x float]* %arr, i64 0, i64 3 |
Jingyue Wu | ec33fa9 | 2014-08-22 22:45:57 +0000 | [diff] [blame] | 550 | store float 1.000000e+00, float* %0, align 4 |
| 551 | br label %then2 |
| 552 | |
| 553 | then2: |
| 554 | %1 = phi float* [ %0, %then ] |
| 555 | store float 2.000000e+00, float* %1, align 4 |
| 556 | br label %merge |
| 557 | |
| 558 | else: |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 559 | %2 = getelementptr inbounds [4 x float], [4 x float]* %arr, i64 0, i64 3 |
Jingyue Wu | ec33fa9 | 2014-08-22 22:45:57 +0000 | [diff] [blame] | 560 | store float 3.000000e+00, float* %2, align 4 |
| 561 | br label %merge |
| 562 | |
| 563 | merge: |
| 564 | %3 = phi float* [ %1, %then2 ], [ %2, %else ] |
| 565 | store float 0.000000e+00, float* %temp, align 4 |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 566 | %4 = load float, float* %3, align 4 |
Jingyue Wu | ec33fa9 | 2014-08-22 22:45:57 +0000 | [diff] [blame] | 567 | ret float %4 |
| 568 | } |
David Majnemer | d4cffcf | 2014-09-01 21:20:14 +0000 | [diff] [blame] | 569 | |
| 570 | %struct.S = type { i32 } |
| 571 | |
| 572 | ; Verifies we fixed PR20822. We have a foldable PHI feeding a speculatable PHI |
| 573 | ; which requires the rewriting of the speculated PHI to handle insertion |
| 574 | ; when the incoming pointer is itself from a PHI node. We would previously |
| 575 | ; insert a bitcast instruction *before* a PHI, producing an invalid module; |
| 576 | ; make sure we insert *after* the first non-PHI instruction. |
| 577 | define void @PR20822() { |
| 578 | ; CHECK-LABEL: @PR20822( |
| 579 | entry: |
| 580 | %f = alloca %struct.S, align 4 |
| 581 | ; CHECK: %[[alloca:.*]] = alloca |
| 582 | br i1 undef, label %if.end, label %for.cond |
| 583 | |
| 584 | for.cond: ; preds = %for.cond, %entry |
| 585 | br label %if.end |
| 586 | |
| 587 | if.end: ; preds = %for.cond, %entry |
| 588 | %f2 = phi %struct.S* [ %f, %entry ], [ %f, %for.cond ] |
| 589 | ; CHECK: phi i32 |
| 590 | ; CHECK: %[[cast:.*]] = bitcast i32* %[[alloca]] to %struct.S* |
| 591 | phi i32 [ undef, %entry ], [ undef, %for.cond ] |
| 592 | br i1 undef, label %if.then5, label %if.then2 |
| 593 | |
| 594 | if.then2: ; preds = %if.end |
| 595 | br label %if.then5 |
| 596 | |
| 597 | if.then5: ; preds = %if.then2, %if.end |
| 598 | %f1 = phi %struct.S* [ undef, %if.then2 ], [ %f2, %if.end ] |
| 599 | ; CHECK: phi {{.*}} %[[cast]] |
| 600 | store %struct.S undef, %struct.S* %f1, align 4 |
| 601 | ret void |
| 602 | } |