llvm.org GIT mirror llvm / 4498596
[PM/LoopUnswitch] Fix PR37889, producing the correct loop nest structure after trivial unswitching. This PR illustrates that a fundamental analysis update was not performed with the new loop unswitch. This update is also somewhat fundamental to the core idea of the new loop unswitch -- we actually *update* the CFG based on the unswitching. In order to do that, we need to update the loop nest in addition to the domtree. For some reason, when writing trivial unswitching, I thought that the loop nest structure cannot be changed by the transformation. But the PR helps illustrate that it clearly can. I've expanded this to a number of different test cases that try to cover the different cases of this. When we unswitch, we move an exit edge of a loop out of the loop. If this exit edge changes which loop reached by an exit is the innermost loop, it changes the parent of the loop. Essentially, this transformation may hoist the inner loop up the nest. I've added the simple logic to handle this reliably in the trivial unswitching case. This just requires updating LoopInfo and rebuilding LCSSA on the impacted loops. In the trivial case, we don't even need to handle dedicated exits because we're only hoisting the one loop and we just split its preheader. I've also ported all of these tests to non-trivial unswitching and verified that the logic already there correctly handles the loop nest updates necessary. Differential Revision: https://reviews.llvm.org/D48851 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336477 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 1 year, 2 months ago
3 changed file(s) with 1243 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
None //===- SimpleLoopUnswitch.cpp - Hoist loop-invariant control flow ---------===//
0 ///===- SimpleLoopUnswitch.cpp - Hoist loop-invariant control flow ---------===//
11 //
22 // The LLVM Compiler Infrastructure
33 //
238238 }
239239 }
240240
241 /// Hoist the current loop up to the innermost loop containing a remaining exit.
242 ///
243 /// Because we've removed an exit from the loop, we may have changed the set of
244 /// loops reachable and need to move the current loop up the loop nest or even
245 /// to an entirely separate nest.
246 static void hoistLoopToNewParent(Loop &L, BasicBlock &Preheader,
247 DominatorTree &DT, LoopInfo &LI) {
248 // If the loop is already at the top level, we can't hoist it anywhere.
249 Loop *OldParentL = L.getParentLoop();
250 if (!OldParentL)
251 return;
252
253 SmallVector Exits;
254 L.getExitBlocks(Exits);
255 Loop *NewParentL = nullptr;
256 for (auto *ExitBB : Exits)
257 if (Loop *ExitL = LI.getLoopFor(ExitBB))
258 if (!NewParentL || NewParentL->contains(ExitL))
259 NewParentL = ExitL;
260
261 if (NewParentL == OldParentL)
262 return;
263
264 // The new parent loop (if different) should always contain the old one.
265 if (NewParentL)
266 assert(NewParentL->contains(OldParentL) &&
267 "Can only hoist this loop up the nest!");
268
269 // The preheader will need to move with the body of this loop. However,
270 // because it isn't in this loop we also need to update the primary loop map.
271 assert(OldParentL == LI.getLoopFor(&Preheader) &&
272 "Parent loop of this loop should contain this loop's preheader!");
273 LI.changeLoopFor(&Preheader, NewParentL);
274
275 // Remove this loop from its old parent.
276 OldParentL->removeChildLoop(&L);
277
278 // Add the loop either to the new parent or as a top-level loop.
279 if (NewParentL)
280 NewParentL->addChildLoop(&L);
281 else
282 LI.addTopLevelLoop(&L);
283
284 // Remove this loops blocks from the old parent and every other loop up the
285 // nest until reaching the new parent. Also update all of these
286 // no-longer-containing loops to reflect the nesting change.
287 for (Loop *OldContainingL = OldParentL; OldContainingL != NewParentL;
288 OldContainingL = OldContainingL->getParentLoop()) {
289 llvm::erase_if(OldContainingL->getBlocksVector(),
290 [&](const BasicBlock *BB) {
291 return BB == &Preheader || L.contains(BB);
292 });
293
294 OldContainingL->getBlocksSet().erase(&Preheader);
295 for (BasicBlock *BB : L.blocks())
296 OldContainingL->getBlocksSet().erase(BB);
297
298 // Because we just hoisted a loop out of this one, we have essentially
299 // created new exit paths from it. That means we need to form LCSSA PHI
300 // nodes for values used in the no-longer-nested loop.
301 formLCSSA(*OldContainingL, DT, &LI, nullptr);
302
303 // We shouldn't need to form dedicated exits because the exit introduced
304 // here is the (just split by unswitching) preheader. As such, it is
305 // necessarily dedicated.
306 assert(OldContainingL->hasDedicatedExits() &&
307 "Unexpected predecessor of hoisted loop preheader!");
308 }
309 }
310
241311 /// Unswitch a trivial branch if the condition is loop invariant.
242312 ///
243313 /// This routine should only be called when loop code leading to the branch has
403473 // within the loop with a constant.
404474 for (Value *Invariant : Invariants)
405475 replaceLoopInvariantUses(L, Invariant, *Replacement);
476
477 // If this was full unswitching, we may have changed the nesting relationship
478 // for this loop so hoist it to its correct parent if needed.
479 if (FullUnswitch)
480 hoistLoopToNewParent(L, *NewPH, DT, LI);
406481
407482 ++NumTrivial;
408483 ++NumBranches;
631706 DTUpdates.push_back({DT.Insert, OldPH, UnswitchedBB});
632707 }
633708 DT.applyUpdates(DTUpdates);
634
635709 assert(DT.verify(DominatorTree::VerificationLevel::Fast));
710
711 // We may have changed the nesting relationship for this loop so hoist it to
712 // its correct parent if needed.
713 hoistLoopToNewParent(L, *NewPH, DT, LI);
714
636715 ++NumTrivial;
637716 ++NumSwitches;
638717 return true;
77
88 declare void @sink1(i32)
99 declare void @sink2(i32)
10
11 declare i1 @cond()
12 declare i32 @cond.i32()
1013
1114 ; Negative test: we cannot unswitch convergent calls.
1215 define void @test_no_unswitch_convergent(i1* %ptr, i1 %cond) {
29602963 ret i32 0
29612964 ; CHECK: loop_exit:
29622965 ; CHECK-NEXT: ret i32 0
2963 }
2966 }
2967
2968 ; Unswitch will not actually change the loop nest from:
2969 ; A < B < C
2970 define void @hoist_inner_loop0() {
2971 ; CHECK-LABEL: define void @hoist_inner_loop0(
2972 entry:
2973 br label %a.header
2974 ; CHECK: entry:
2975 ; CHECK-NEXT: br label %a.header
2976
2977 a.header:
2978 br label %b.header
2979 ; CHECK: a.header:
2980 ; CHECK-NEXT: br label %b.header
2981
2982 b.header:
2983 %v1 = call i1 @cond()
2984 br label %c.header
2985 ; CHECK: b.header:
2986 ; CHECK-NEXT: %v1 = call i1 @cond()
2987 ; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]
2988 ;
2989 ; CHECK: [[B_HEADER_SPLIT_US]]:
2990 ; CHECK-NEXT: br label %[[C_HEADER_US:.*]]
2991 ;
2992 ; CHECK: [[C_HEADER_US]]:
2993 ; CHECK-NEXT: call void @c()
2994 ; CHECK-NEXT: br label %[[B_LATCH_SPLIT_US:.*]]
2995 ;
2996 ; CHECK: [[B_LATCH_SPLIT_US]]:
2997 ; CHECK-NEXT: br label %b.latch
2998 ;
2999 ; CHECK: [[B_HEADER_SPLIT]]:
3000 ; CHECK-NEXT: br label %c.header
3001
3002 c.header:
3003 call void @c()
3004 br i1 %v1, label %b.latch, label %c.latch
3005 ; CHECK: c.header:
3006 ; CHECK-NEXT: call void @c()
3007 ; CHECK-NEXT: br label %c.latch
3008
3009 c.latch:
3010 %v2 = call i1 @cond()
3011 br i1 %v2, label %c.header, label %b.latch
3012 ; CHECK: c.latch:
3013 ; CHECK-NEXT: %v2 = call i1 @cond()
3014 ; CHECK-NEXT: br i1 %v2, label %c.header, label %[[B_LATCH_SPLIT:.*]]
3015
3016 b.latch:
3017 %v3 = call i1 @cond()
3018 br i1 %v3, label %b.header, label %a.latch
3019 ; CHECK: [[B_LATCH_SPLIT]]:
3020 ; CHECK-NEXT: br label %b.latch
3021 ;
3022 ; CHECK: b.latch:
3023 ; CHECK-NEXT: %v3 = call i1 @cond()
3024 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
3025
3026 a.latch:
3027 br label %a.header
3028 ; CHECK: a.latch:
3029 ; CHECK-NEXT: br label %a.header
3030
3031 exit:
3032 ret void
3033 ; CHECK: exit:
3034 ; CHECK-NEXT: ret void
3035 }
3036
3037 ; Unswitch will transform the loop nest from:
3038 ; A < B < C
3039 ; into
3040 ; A < (B, C)
3041 define void @hoist_inner_loop1(i32* %ptr) {
3042 ; CHECK-LABEL: define void @hoist_inner_loop1(
3043 entry:
3044 br label %a.header
3045 ; CHECK: entry:
3046 ; CHECK-NEXT: br label %a.header
3047
3048 a.header:
3049 %x.a = load i32, i32* %ptr
3050 br label %b.header
3051 ; CHECK: a.header:
3052 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
3053 ; CHECK-NEXT: br label %b.header
3054
3055 b.header:
3056 %x.b = load i32, i32* %ptr
3057 %v1 = call i1 @cond()
3058 br label %c.header
3059 ; CHECK: b.header:
3060 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
3061 ; CHECK-NEXT: %v1 = call i1 @cond()
3062 ; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]
3063 ;
3064 ; CHECK: [[B_HEADER_SPLIT_US]]:
3065 ; CHECK-NEXT: br label %[[C_HEADER_US:.*]]
3066 ;
3067 ; CHECK: [[C_HEADER_US]]:
3068 ; CHECK-NEXT: call void @c()
3069 ; CHECK-NEXT: br label %[[B_LATCH_US:.*]]
3070 ;
3071 ; CHECK: [[B_LATCH_US]]:
3072 ; CHECK-NEXT: br label %b.latch
3073 ;
3074 ; CHECK: [[B_HEADER_SPLIT]]:
3075 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
3076 ; CHECK-NEXT: br label %c.header
3077
3078 c.header:
3079 call void @c()
3080 br i1 %v1, label %b.latch, label %c.latch
3081 ; CHECK: c.header:
3082 ; CHECK-NEXT: call void @c()
3083 ; CHECK-NEXT: br label %c.latch
3084
3085 c.latch:
3086 ; Use values from other loops to check LCSSA form.
3087 store i32 %x.a, i32* %ptr
3088 store i32 %x.b, i32* %ptr
3089 %v2 = call i1 @cond()
3090 br i1 %v2, label %c.header, label %a.exit.c
3091 ; CHECK: c.latch:
3092 ; CHECK-NEXT: store i32 %x.a, i32* %ptr
3093 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
3094 ; CHECK-NEXT: %v2 = call i1 @cond()
3095 ; CHECK-NEXT: br i1 %v2, label %c.header, label %a.exit.c
3096
3097 b.latch:
3098 %v3 = call i1 @cond()
3099 br i1 %v3, label %b.header, label %a.exit.b
3100 ; CHECK: b.latch:
3101 ; CHECK-NEXT: %v3 = call i1 @cond()
3102 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.exit.b
3103
3104 a.exit.c:
3105 br label %a.latch
3106 ; CHECK: a.exit.c
3107 ; CHECK-NEXT: br label %a.latch
3108
3109 a.exit.b:
3110 br label %a.latch
3111 ; CHECK: a.exit.b:
3112 ; CHECK-NEXT: br label %a.latch
3113
3114 a.latch:
3115 br label %a.header
3116 ; CHECK: a.latch:
3117 ; CHECK-NEXT: br label %a.header
3118
3119 exit:
3120 ret void
3121 ; CHECK: exit:
3122 ; CHECK-NEXT: ret void
3123 }
3124
3125 ; Unswitch will transform the loop nest from:
3126 ; A < B < C
3127 ; into
3128 ; (A < B), C
3129 define void @hoist_inner_loop2(i32* %ptr) {
3130 ; CHECK-LABEL: define void @hoist_inner_loop2(
3131 entry:
3132 br label %a.header
3133 ; CHECK: entry:
3134 ; CHECK-NEXT: br label %a.header
3135
3136 a.header:
3137 %x.a = load i32, i32* %ptr
3138 br label %b.header
3139 ; CHECK: a.header:
3140 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
3141 ; CHECK-NEXT: br label %b.header
3142
3143 b.header:
3144 %x.b = load i32, i32* %ptr
3145 %v1 = call i1 @cond()
3146 br label %c.header
3147 ; CHECK: b.header:
3148 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
3149 ; CHECK-NEXT: %v1 = call i1 @cond()
3150 ; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]
3151 ;
3152 ; CHECK: [[B_HEADER_SPLIT_US]]:
3153 ; CHECK-NEXT: br label %[[C_HEADER_US:.*]]
3154 ;
3155 ; CHECK: [[C_HEADER_US]]:
3156 ; CHECK-NEXT: call void @c()
3157 ; CHECK-NEXT: br label %[[B_LATCH_US:.*]]
3158 ;
3159 ; CHECK: [[B_LATCH_US]]:
3160 ; CHECK-NEXT: br label %b.latch
3161 ;
3162 ; CHECK: [[B_HEADER_SPLIT]]:
3163 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
3164 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
3165 ; CHECK-NEXT: br label %c.header
3166
3167 c.header:
3168 call void @c()
3169 br i1 %v1, label %b.latch, label %c.latch
3170 ; CHECK: c.header:
3171 ; CHECK-NEXT: call void @c()
3172 ; CHECK-NEXT: br label %c.latch
3173
3174 c.latch:
3175 ; Use values from other loops to check LCSSA form.
3176 store i32 %x.a, i32* %ptr
3177 store i32 %x.b, i32* %ptr
3178 %v2 = call i1 @cond()
3179 br i1 %v2, label %c.header, label %exit
3180 ; CHECK: c.latch:
3181 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
3182 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
3183 ; CHECK-NEXT: %v2 = call i1 @cond()
3184 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
3185
3186 b.latch:
3187 %v3 = call i1 @cond()
3188 br i1 %v3, label %b.header, label %a.latch
3189 ; CHECK: b.latch:
3190 ; CHECK-NEXT: %v3 = call i1 @cond()
3191 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
3192
3193 a.latch:
3194 br label %a.header
3195 ; CHECK: a.latch:
3196 ; CHECK-NEXT: br label %a.header
3197
3198 exit:
3199 ret void
3200 ; CHECK: exit:
3201 ; CHECK-NEXT: ret void
3202 }
3203
3204 ; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.
3205 ; Unswitch will transform the loop nest from:
3206 ; A < B < C < D
3207 ; into
3208 ; (A < B), (C < D)
3209 define void @hoist_inner_loop3(i32* %ptr) {
3210 ; CHECK-LABEL: define void @hoist_inner_loop3(
3211 entry:
3212 br label %a.header
3213 ; CHECK: entry:
3214 ; CHECK-NEXT: br label %a.header
3215
3216 a.header:
3217 %x.a = load i32, i32* %ptr
3218 br label %b.header
3219 ; CHECK: a.header:
3220 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
3221 ; CHECK-NEXT: br label %b.header
3222
3223 b.header:
3224 %x.b = load i32, i32* %ptr
3225 %v1 = call i1 @cond()
3226 br label %c.header
3227 ; CHECK: b.header:
3228 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
3229 ; CHECK-NEXT: %v1 = call i1 @cond()
3230 ; CHECK-NEXT: br i1 %v1, label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]
3231 ;
3232 ; CHECK: [[B_HEADER_SPLIT_US]]:
3233 ; CHECK-NEXT: br label %[[C_HEADER_US:.*]]
3234 ;
3235 ; CHECK: [[C_HEADER_US]]:
3236 ; CHECK-NEXT: call void @c()
3237 ; CHECK-NEXT: br label %[[B_LATCH_US:.*]]
3238 ;
3239 ; CHECK: [[B_LATCH_US]]:
3240 ; CHECK-NEXT: br label %b.latch
3241 ;
3242 ; CHECK: [[B_HEADER_SPLIT]]:
3243 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
3244 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
3245 ; CHECK-NEXT: br label %c.header
3246
3247 c.header:
3248 call void @c()
3249 br i1 %v1, label %b.latch, label %c.body
3250 ; CHECK: c.header:
3251 ; CHECK-NEXT: call void @c()
3252 ; CHECK-NEXT: br label %c.body
3253
3254 c.body:
3255 %x.c = load i32, i32* %ptr
3256 br label %d.header
3257 ; CHECK: c.body:
3258 ; CHECK-NEXT: %x.c = load i32, i32* %ptr
3259 ; CHECK-NEXT: br label %d.header
3260
3261 d.header:
3262 ; Use values from other loops to check LCSSA form.
3263 store i32 %x.a, i32* %ptr
3264 store i32 %x.b, i32* %ptr
3265 store i32 %x.c, i32* %ptr
3266 %v2 = call i1 @cond()
3267 br i1 %v2, label %d.header, label %c.latch
3268 ; CHECK: d.header:
3269 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
3270 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
3271 ; CHECK-NEXT: store i32 %x.c, i32* %ptr
3272 ; CHECK-NEXT: %v2 = call i1 @cond()
3273 ; CHECK-NEXT: br i1 %v2, label %d.header, label %c.latch
3274
3275 c.latch:
3276 %v3 = call i1 @cond()
3277 br i1 %v3, label %c.header, label %exit
3278 ; CHECK: c.latch:
3279 ; CHECK-NEXT: %v3 = call i1 @cond()
3280 ; CHECK-NEXT: br i1 %v3, label %c.header, label %exit
3281
3282 b.latch:
3283 %v4 = call i1 @cond()
3284 br i1 %v4, label %b.header, label %a.latch
3285 ; CHECK: b.latch:
3286 ; CHECK-NEXT: %v4 = call i1 @cond()
3287 ; CHECK-NEXT: br i1 %v4, label %b.header, label %a.latch
3288
3289 a.latch:
3290 br label %a.header
3291 ; CHECK: a.latch:
3292 ; CHECK-NEXT: br label %a.header
3293
3294 exit:
3295 ret void
3296 ; CHECK: exit:
3297 ; CHECK-NEXT: ret void
3298 }
3299
3300 ; This test is designed to exercise checking multiple remaining exits from the
3301 ; loop being unswitched.
3302 ; Unswitch will transform the loop nest from:
3303 ; A < B < C < D
3304 ; into
3305 ; A < B < (C, D)
3306 define void @hoist_inner_loop4() {
3307 ; CHECK-LABEL: define void @hoist_inner_loop4(
3308 entry:
3309 br label %a.header
3310 ; CHECK: entry:
3311 ; CHECK-NEXT: br label %a.header
3312
3313 a.header:
3314 br label %b.header
3315 ; CHECK: a.header:
3316 ; CHECK-NEXT: br label %b.header
3317
3318 b.header:
3319 br label %c.header
3320 ; CHECK: b.header:
3321 ; CHECK-NEXT: br label %c.header
3322
3323 c.header:
3324 %v1 = call i1 @cond()
3325 br label %d.header
3326 ; CHECK: c.header:
3327 ; CHECK-NEXT: %v1 = call i1 @cond()
3328 ; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]
3329 ;
3330 ; CHECK: [[C_HEADER_SPLIT_US]]:
3331 ; CHECK-NEXT: br label %[[D_HEADER_US:.*]]
3332 ;
3333 ; CHECK: [[D_HEADER_US]]:
3334 ; CHECK-NEXT: call void @d()
3335 ; CHECK-NEXT: br label %[[C_LATCH_US:.*]]
3336 ;
3337 ; CHECK: [[C_LATCH_US]]:
3338 ; CHECK-NEXT: br label %c.latch
3339 ;
3340 ; CHECK: [[C_HEADER_SPLIT]]:
3341 ; CHECK-NEXT: br label %d.header
3342
3343 d.header:
3344 call void @d()
3345 br i1 %v1, label %c.latch, label %d.exiting1
3346 ; CHECK: d.header:
3347 ; CHECK-NEXT: call void @d()
3348 ; CHECK-NEXT: br label %d.exiting1
3349
3350 d.exiting1:
3351 %v2 = call i1 @cond()
3352 br i1 %v2, label %d.exiting2, label %a.latch
3353 ; CHECK: d.exiting1:
3354 ; CHECK-NEXT: %v2 = call i1 @cond()
3355 ; CHECK-NEXT: br i1 %v2, label %d.exiting2, label %a.latch
3356
3357 d.exiting2:
3358 %v3 = call i1 @cond()
3359 br i1 %v3, label %d.exiting3, label %loopexit.d
3360 ; CHECK: d.exiting2:
3361 ; CHECK-NEXT: %v3 = call i1 @cond()
3362 ; CHECK-NEXT: br i1 %v3, label %d.exiting3, label %loopexit.d
3363
3364 d.exiting3:
3365 %v4 = call i1 @cond()
3366 br i1 %v4, label %d.latch, label %b.latch
3367 ; CHECK: d.exiting3:
3368 ; CHECK-NEXT: %v4 = call i1 @cond()
3369 ; CHECK-NEXT: br i1 %v4, label %d.latch, label %b.latch
3370
3371 d.latch:
3372 br label %d.header
3373 ; CHECK: d.latch:
3374 ; CHECK-NEXT: br label %d.header
3375
3376 c.latch:
3377 %v5 = call i1 @cond()
3378 br i1 %v5, label %c.header, label %loopexit.c
3379 ; CHECK: c.latch:
3380 ; CHECK-NEXT: %v5 = call i1 @cond()
3381 ; CHECK-NEXT: br i1 %v5, label %c.header, label %loopexit.c
3382
3383 b.latch:
3384 br label %b.header
3385 ; CHECK: b.latch:
3386 ; CHECK-NEXT: br label %b.header
3387
3388 a.latch:
3389 br label %a.header
3390 ; CHECK: a.latch:
3391 ; CHECK-NEXT: br label %a.header
3392
3393 loopexit.d:
3394 br label %exit
3395 ; CHECK: loopexit.d:
3396 ; CHECK-NEXT: br label %exit
3397
3398 loopexit.c:
3399 br label %exit
3400 ; CHECK: loopexit.c:
3401 ; CHECK-NEXT: br label %exit
3402
3403 exit:
3404 ret void
3405 ; CHECK: exit:
3406 ; CHECK-NEXT: ret void
3407 }
3408
3409 ; Unswitch will transform the loop nest from:
3410 ; A < B < C < D
3411 ; into
3412 ; A < ((B < C), D)
3413 define void @hoist_inner_loop5(i32* %ptr) {
3414 ; CHECK-LABEL: define void @hoist_inner_loop5(
3415 entry:
3416 br label %a.header
3417 ; CHECK: entry:
3418 ; CHECK-NEXT: br label %a.header
3419
3420 a.header:
3421 %x.a = load i32, i32* %ptr
3422 br label %b.header
3423 ; CHECK: a.header:
3424 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
3425 ; CHECK-NEXT: br label %b.header
3426
3427 b.header:
3428 %x.b = load i32, i32* %ptr
3429 br label %c.header
3430 ; CHECK: b.header:
3431 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
3432 ; CHECK-NEXT: br label %c.header
3433
3434 c.header:
3435 %x.c = load i32, i32* %ptr
3436 %v1 = call i1 @cond()
3437 br label %d.header
3438 ; CHECK: c.header:
3439 ; CHECK-NEXT: %x.c = load i32, i32* %ptr
3440 ; CHECK-NEXT: %v1 = call i1 @cond()
3441 ; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]
3442 ;
3443 ; CHECK: [[C_HEADER_SPLIT_US]]:
3444 ; CHECK-NEXT: br label %[[D_HEADER_US:.*]]
3445 ;
3446 ; CHECK: [[D_HEADER_US]]:
3447 ; CHECK-NEXT: call void @d()
3448 ; CHECK-NEXT: br label %[[C_LATCH_US:.*]]
3449 ;
3450 ; CHECK: [[C_LATCH_US]]:
3451 ; CHECK-NEXT: br label %c.latch
3452 ;
3453 ; CHECK: [[C_HEADER_SPLIT]]:
3454 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %c.header ]
3455 ; CHECK-NEXT: %[[X_C_LCSSA:.*]] = phi i32 [ %x.c, %c.header ]
3456 ; CHECK-NEXT: br label %d.header
3457
3458 d.header:
3459 call void @d()
3460 br i1 %v1, label %c.latch, label %d.latch
3461 ; CHECK: d.header:
3462 ; CHECK-NEXT: call void @d()
3463 ; CHECK-NEXT: br label %d.latch
3464
3465 d.latch:
3466 ; Use values from other loops to check LCSSA form.
3467 store i32 %x.a, i32* %ptr
3468 store i32 %x.b, i32* %ptr
3469 store i32 %x.c, i32* %ptr
3470 %v2 = call i1 @cond()
3471 br i1 %v2, label %d.header, label %a.latch
3472 ; CHECK: d.latch:
3473 ; CHECK-NEXT: store i32 %x.a, i32* %ptr
3474 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
3475 ; CHECK-NEXT: store i32 %[[X_C_LCSSA]], i32* %ptr
3476 ; CHECK-NEXT: %v2 = call i1 @cond()
3477 ; CHECK-NEXT: br i1 %v2, label %d.header, label %a.latch
3478
3479 c.latch:
3480 %v3 = call i1 @cond()
3481 br i1 %v3, label %c.header, label %b.latch
3482 ; CHECK: c.latch:
3483 ; CHECK-NEXT: %v3 = call i1 @cond()
3484 ; CHECK-NEXT: br i1 %v3, label %c.header, label %b.latch
3485
3486 b.latch:
3487 br label %b.header
3488 ; CHECK: b.latch:
3489 ; CHECK-NEXT: br label %b.header
3490
3491 a.latch:
3492 br label %a.header
3493 ; CHECK: a.latch:
3494 ; CHECK-NEXT: br label %a.header
3495
3496 exit:
3497 ret void
3498 ; CHECK: exit:
3499 ; CHECK-NEXT: ret void
3500 }
3501
3502 define void @hoist_inner_loop_switch(i32* %ptr) {
3503 ; CHECK-LABEL: define void @hoist_inner_loop_switch(
3504 entry:
3505 br label %a.header
3506 ; CHECK: entry:
3507 ; CHECK-NEXT: br label %a.header
3508
3509 a.header:
3510 %x.a = load i32, i32* %ptr
3511 br label %b.header
3512 ; CHECK: a.header:
3513 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
3514 ; CHECK-NEXT: br label %b.header
3515
3516 b.header:
3517 %x.b = load i32, i32* %ptr
3518 %v1 = call i32 @cond.i32()
3519 br label %c.header
3520 ; CHECK: b.header:
3521 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
3522 ; CHECK-NEXT: %v1 = call i32 @cond.i32()
3523 ; CHECK-NEXT: switch i32 %v1, label %[[B_HEADER_SPLIT:.*]] [
3524 ; CHECK-NEXT: i32 1, label %[[B_HEADER_SPLIT_US:.*]]
3525 ; CHECK-NEXT: i32 2, label %[[B_HEADER_SPLIT_US]]
3526 ; CHECK-NEXT: i32 3, label %[[B_HEADER_SPLIT_US]]
3527 ; CHECK-NEXT: ]
3528 ;
3529 ; CHECK: [[B_HEADER_SPLIT_US]]:
3530 ; CHECK-NEXT: br label %[[C_HEADER_US:.*]]
3531 ;
3532 ; CHECK: [[C_HEADER_US]]:
3533 ; CHECK-NEXT: call void @c()
3534 ; CHECK-NEXT: br label %[[B_LATCH_US:.*]]
3535 ;
3536 ; CHECK: [[B_LATCH_US]]:
3537 ; CHECK-NEXT: br label %b.latch
3538 ;
3539 ; CHECK: [[B_HEADER_SPLIT]]:
3540 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
3541 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
3542 ; CHECK-NEXT: br label %c.header
3543
3544 c.header:
3545 call void @c()
3546 switch i32 %v1, label %c.latch [
3547 i32 1, label %b.latch
3548 i32 2, label %b.latch
3549 i32 3, label %b.latch
3550 ]
3551 ; CHECK: c.header:
3552 ; CHECK-NEXT: call void @c()
3553 ; CHECK-NEXT: br label %c.latch
3554
3555 c.latch:
3556 ; Use values from other loops to check LCSSA form.
3557 store i32 %x.a, i32* %ptr
3558 store i32 %x.b, i32* %ptr
3559 %v2 = call i1 @cond()
3560 br i1 %v2, label %c.header, label %exit
3561 ; CHECK: c.latch:
3562 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
3563 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
3564 ; CHECK-NEXT: %v2 = call i1 @cond()
3565 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
3566
3567 b.latch:
3568 %v3 = call i1 @cond()
3569 br i1 %v3, label %b.header, label %a.latch
3570 ; CHECK: b.latch:
3571 ; CHECK-NEXT: %v3 = call i1 @cond()
3572 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
3573
3574 a.latch:
3575 br label %a.header
3576 ; CHECK: a.latch:
3577 ; CHECK-NEXT: br label %a.header
3578
3579 exit:
3580 ret void
3581 ; CHECK: exit:
3582 ; CHECK-NEXT: ret void
3583 }
0 ; RUN: opt -passes='loop(unswitch),verify' -S < %s | FileCheck %s
11
22 declare void @some_func() noreturn
3
4 declare i1 @cond()
5 declare i32 @cond.i32()
36
47 ; This test contains two trivial unswitch condition in one loop.
58 ; LoopUnswitch pass should be able to unswitch the second one
618621 ; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ]
619622 ; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]]
620623 }
624
625 ; Unswitch will not actually change the loop nest from:
626 ; A < B < C
627 define void @hoist_inner_loop0() {
628 ; CHECK-LABEL: define void @hoist_inner_loop0(
629 entry:
630 br label %a.header
631 ; CHECK: entry:
632 ; CHECK-NEXT: br label %a.header
633
634 a.header:
635 br label %b.header
636 ; CHECK: a.header:
637 ; CHECK-NEXT: br label %b.header
638
639 b.header:
640 %v1 = call i1 @cond()
641 br label %c.header
642 ; CHECK: b.header:
643 ; CHECK-NEXT: %v1 = call i1 @cond()
644 ; CHECK-NEXT: br i1 %v1, label %[[B_LATCH_SPLIT:.*]], label %[[B_HEADER_SPLIT:.*]]
645 ;
646 ; CHECK: [[B_HEADER_SPLIT]]:
647 ; CHECK-NEXT: br label %c.header
648
649 c.header:
650 br i1 %v1, label %b.latch, label %c.latch
651 ; CHECK: c.header:
652 ; CHECK-NEXT: br label %c.latch
653
654 c.latch:
655 %v2 = call i1 @cond()
656 br i1 %v2, label %c.header, label %b.latch
657 ; CHECK: c.latch:
658 ; CHECK-NEXT: %v2 = call i1 @cond()
659 ; CHECK-NEXT: br i1 %v2, label %c.header, label %b.latch
660
661 b.latch:
662 %v3 = call i1 @cond()
663 br i1 %v3, label %b.header, label %a.latch
664 ; CHECK: b.latch:
665 ; CHECK-NEXT: br label %[[B_LATCH_SPLIT]]
666 ;
667 ; CHECK: [[B_LATCH_SPLIT]]:
668 ; CHECK-NEXT: %v3 = call i1 @cond()
669 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
670
671 a.latch:
672 br label %a.header
673 ; CHECK: a.latch:
674 ; CHECK-NEXT: br label %a.header
675
676 exit:
677 ret void
678 ; CHECK: exit:
679 ; CHECK-NEXT: ret void
680 }
681
682 ; Unswitch will transform the loop nest from:
683 ; A < B < C
684 ; into
685 ; A < (B, C)
686 define void @hoist_inner_loop1(i32* %ptr) {
687 ; CHECK-LABEL: define void @hoist_inner_loop1(
688 entry:
689 br label %a.header
690 ; CHECK: entry:
691 ; CHECK-NEXT: br label %a.header
692
693 a.header:
694 %x.a = load i32, i32* %ptr
695 br label %b.header
696 ; CHECK: a.header:
697 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
698 ; CHECK-NEXT: br label %b.header
699
700 b.header:
701 %x.b = load i32, i32* %ptr
702 %v1 = call i1 @cond()
703 br label %c.header
704 ; CHECK: b.header:
705 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
706 ; CHECK-NEXT: %v1 = call i1 @cond()
707 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
708 ;
709 ; CHECK: [[B_HEADER_SPLIT]]:
710 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
711 ; CHECK-NEXT: br label %c.header
712
713 c.header:
714 br i1 %v1, label %b.latch, label %c.latch
715 ; CHECK: c.header:
716 ; CHECK-NEXT: br label %c.latch
717
718 c.latch:
719 ; Use values from other loops to check LCSSA form.
720 store i32 %x.a, i32* %ptr
721 store i32 %x.b, i32* %ptr
722 %v2 = call i1 @cond()
723 br i1 %v2, label %c.header, label %a.exit.c
724 ; CHECK: c.latch:
725 ; CHECK-NEXT: store i32 %x.a, i32* %ptr
726 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
727 ; CHECK-NEXT: %v2 = call i1 @cond()
728 ; CHECK-NEXT: br i1 %v2, label %c.header, label %a.exit.c
729
730 b.latch:
731 %v3 = call i1 @cond()
732 br i1 %v3, label %b.header, label %a.exit.b
733 ; CHECK: b.latch:
734 ; CHECK-NEXT: %v3 = call i1 @cond()
735 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.exit.b
736
737 a.exit.c:
738 br label %a.latch
739 ; CHECK: a.exit.c
740 ; CHECK-NEXT: br label %a.latch
741
742 a.exit.b:
743 br label %a.latch
744 ; CHECK: a.exit.b:
745 ; CHECK-NEXT: br label %a.latch
746
747 a.latch:
748 br label %a.header
749 ; CHECK: a.latch:
750 ; CHECK-NEXT: br label %a.header
751
752 exit:
753 ret void
754 ; CHECK: exit:
755 ; CHECK-NEXT: ret void
756 }
757
758 ; Unswitch will transform the loop nest from:
759 ; A < B < C
760 ; into
761 ; (A < B), C
762 define void @hoist_inner_loop2(i32* %ptr) {
763 ; CHECK-LABEL: define void @hoist_inner_loop2(
764 entry:
765 br label %a.header
766 ; CHECK: entry:
767 ; CHECK-NEXT: br label %a.header
768
769 a.header:
770 %x.a = load i32, i32* %ptr
771 br label %b.header
772 ; CHECK: a.header:
773 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
774 ; CHECK-NEXT: br label %b.header
775
776 b.header:
777 %x.b = load i32, i32* %ptr
778 %v1 = call i1 @cond()
779 br label %c.header
780 ; CHECK: b.header:
781 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
782 ; CHECK-NEXT: %v1 = call i1 @cond()
783 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
784 ;
785 ; CHECK: [[B_HEADER_SPLIT]]:
786 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
787 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
788 ; CHECK-NEXT: br label %c.header
789
790 c.header:
791 br i1 %v1, label %b.latch, label %c.latch
792 ; CHECK: c.header:
793 ; CHECK-NEXT: br label %c.latch
794
795 c.latch:
796 ; Use values from other loops to check LCSSA form.
797 store i32 %x.a, i32* %ptr
798 store i32 %x.b, i32* %ptr
799 %v2 = call i1 @cond()
800 br i1 %v2, label %c.header, label %exit
801 ; CHECK: c.latch:
802 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
803 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
804 ; CHECK-NEXT: %v2 = call i1 @cond()
805 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
806
807 b.latch:
808 %v3 = call i1 @cond()
809 br i1 %v3, label %b.header, label %a.latch
810 ; CHECK: b.latch:
811 ; CHECK-NEXT: %v3 = call i1 @cond()
812 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
813
814 a.latch:
815 br label %a.header
816 ; CHECK: a.latch:
817 ; CHECK-NEXT: br label %a.header
818
819 exit:
820 ret void
821 ; CHECK: exit:
822 ; CHECK-NEXT: ret void
823 }
824
825 ; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.
826 ; Unswitch will transform the loop nest from:
827 ; A < B < C < D
828 ; into
829 ; (A < B), (C < D)
830 define void @hoist_inner_loop3(i32* %ptr) {
831 ; CHECK-LABEL: define void @hoist_inner_loop3(
832 entry:
833 br label %a.header
834 ; CHECK: entry:
835 ; CHECK-NEXT: br label %a.header
836
837 a.header:
838 %x.a = load i32, i32* %ptr
839 br label %b.header
840 ; CHECK: a.header:
841 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
842 ; CHECK-NEXT: br label %b.header
843
844 b.header:
845 %x.b = load i32, i32* %ptr
846 %v1 = call i1 @cond()
847 br label %c.header
848 ; CHECK: b.header:
849 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
850 ; CHECK-NEXT: %v1 = call i1 @cond()
851 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
852 ;
853 ; CHECK: [[B_HEADER_SPLIT]]:
854 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
855 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
856 ; CHECK-NEXT: br label %c.header
857
858 c.header:
859 br i1 %v1, label %b.latch, label %c.body
860 ; CHECK: c.header:
861 ; CHECK-NEXT: br label %c.body
862
863 c.body:
864 %x.c = load i32, i32* %ptr
865 br label %d.header
866 ; CHECK: c.body:
867 ; CHECK-NEXT: %x.c = load i32, i32* %ptr
868 ; CHECK-NEXT: br label %d.header
869
870 d.header:
871 ; Use values from other loops to check LCSSA form.
872 store i32 %x.a, i32* %ptr
873 store i32 %x.b, i32* %ptr
874 store i32 %x.c, i32* %ptr
875 %v2 = call i1 @cond()
876 br i1 %v2, label %d.header, label %c.latch
877 ; CHECK: d.header:
878 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
879 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
880 ; CHECK-NEXT: store i32 %x.c, i32* %ptr
881 ; CHECK-NEXT: %v2 = call i1 @cond()
882 ; CHECK-NEXT: br i1 %v2, label %d.header, label %c.latch
883
884 c.latch:
885 %v3 = call i1 @cond()
886 br i1 %v3, label %c.header, label %exit
887 ; CHECK: c.latch:
888 ; CHECK-NEXT: %v3 = call i1 @cond()
889 ; CHECK-NEXT: br i1 %v3, label %c.header, label %exit
890
891 b.latch:
892 %v4 = call i1 @cond()
893 br i1 %v4, label %b.header, label %a.latch
894 ; CHECK: b.latch:
895 ; CHECK-NEXT: %v4 = call i1 @cond()
896 ; CHECK-NEXT: br i1 %v4, label %b.header, label %a.latch
897
898 a.latch:
899 br label %a.header
900 ; CHECK: a.latch:
901 ; CHECK-NEXT: br label %a.header
902
903 exit:
904 ret void
905 ; CHECK: exit:
906 ; CHECK-NEXT: ret void
907 }
908
909 ; This test is designed to exercise checking multiple remaining exits from the
910 ; loop being unswitched.
911 ; Unswitch will transform the loop nest from:
912 ; A < B < C < D
913 ; into
914 ; A < B < (C, D)
915 define void @hoist_inner_loop4() {
916 ; CHECK-LABEL: define void @hoist_inner_loop4(
917 entry:
918 br label %a.header
919 ; CHECK: entry:
920 ; CHECK-NEXT: br label %a.header
921
922 a.header:
923 br label %b.header
924 ; CHECK: a.header:
925 ; CHECK-NEXT: br label %b.header
926
927 b.header:
928 br label %c.header
929 ; CHECK: b.header:
930 ; CHECK-NEXT: br label %c.header
931
932 c.header:
933 %v1 = call i1 @cond()
934 br label %d.header
935 ; CHECK: c.header:
936 ; CHECK-NEXT: %v1 = call i1 @cond()
937 ; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT:.*]], label %c.latch
938 ;
939 ; CHECK: [[C_HEADER_SPLIT]]:
940 ; CHECK-NEXT: br label %d.header
941
942 d.header:
943 br i1 %v1, label %d.exiting1, label %c.latch
944 ; CHECK: d.header:
945 ; CHECK-NEXT: br label %d.exiting1
946
947 d.exiting1:
948 %v2 = call i1 @cond()
949 br i1 %v2, label %d.exiting2, label %a.latch
950 ; CHECK: d.exiting1:
951 ; CHECK-NEXT: %v2 = call i1 @cond()
952 ; CHECK-NEXT: br i1 %v2, label %d.exiting2, label %a.latch
953
954 d.exiting2:
955 %v3 = call i1 @cond()
956 br i1 %v3, label %d.exiting3, label %loopexit.d
957 ; CHECK: d.exiting2:
958 ; CHECK-NEXT: %v3 = call i1 @cond()
959 ; CHECK-NEXT: br i1 %v3, label %d.exiting3, label %loopexit.d
960
961 d.exiting3:
962 %v4 = call i1 @cond()
963 br i1 %v4, label %d.latch, label %b.latch
964 ; CHECK: d.exiting3:
965 ; CHECK-NEXT: %v4 = call i1 @cond()
966 ; CHECK-NEXT: br i1 %v4, label %d.latch, label %b.latch
967
968 d.latch:
969 br label %d.header
970 ; CHECK: d.latch:
971 ; CHECK-NEXT: br label %d.header
972
973 c.latch:
974 %v5 = call i1 @cond()
975 br i1 %v5, label %c.header, label %loopexit.c
976 ; CHECK: c.latch:
977 ; CHECK-NEXT: %v5 = call i1 @cond()
978 ; CHECK-NEXT: br i1 %v5, label %c.header, label %loopexit.c
979
980 b.latch:
981 br label %b.header
982 ; CHECK: b.latch:
983 ; CHECK-NEXT: br label %b.header
984
985 a.latch:
986 br label %a.header
987 ; CHECK: a.latch:
988 ; CHECK-NEXT: br label %a.header
989
990 loopexit.d:
991 br label %exit
992 ; CHECK: loopexit.d:
993 ; CHECK-NEXT: br label %exit
994
995 loopexit.c:
996 br label %exit
997 ; CHECK: loopexit.c:
998 ; CHECK-NEXT: br label %exit
999
1000 exit:
1001 ret void
1002 ; CHECK: exit:
1003 ; CHECK-NEXT: ret void
1004 }
1005
1006 ; Unswitch will transform the loop nest from:
1007 ; A < B < C < D
1008 ; into
1009 ; A < ((B < C), D)
1010 define void @hoist_inner_loop5(i32* %ptr) {
1011 ; CHECK-LABEL: define void @hoist_inner_loop5(
1012 entry:
1013 br label %a.header
1014 ; CHECK: entry:
1015 ; CHECK-NEXT: br label %a.header
1016
1017 a.header:
1018 %x.a = load i32, i32* %ptr
1019 br label %b.header
1020 ; CHECK: a.header:
1021 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
1022 ; CHECK-NEXT: br label %b.header
1023
1024 b.header:
1025 %x.b = load i32, i32* %ptr
1026 br label %c.header
1027 ; CHECK: b.header:
1028 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
1029 ; CHECK-NEXT: br label %c.header
1030
1031 c.header:
1032 %x.c = load i32, i32* %ptr
1033 %v1 = call i1 @cond()
1034 br label %d.header
1035 ; CHECK: c.header:
1036 ; CHECK-NEXT: %x.c = load i32, i32* %ptr
1037 ; CHECK-NEXT: %v1 = call i1 @cond()
1038 ; CHECK-NEXT: br i1 %v1, label %c.latch, label %[[C_HEADER_SPLIT:.*]]
1039 ;
1040 ; CHECK: [[C_HEADER_SPLIT]]:
1041 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %c.header ]
1042 ; CHECK-NEXT: %[[X_C_LCSSA:.*]] = phi i32 [ %x.c, %c.header ]
1043 ; CHECK-NEXT: br label %d.header
1044
1045 d.header:
1046 br i1 %v1, label %c.latch, label %d.latch
1047 ; CHECK: d.header:
1048 ; CHECK-NEXT: br label %d.latch
1049
1050 d.latch:
1051 ; Use values from other loops to check LCSSA form.
1052 store i32 %x.a, i32* %ptr
1053 store i32 %x.b, i32* %ptr
1054 store i32 %x.c, i32* %ptr
1055 %v2 = call i1 @cond()
1056 br i1 %v2, label %d.header, label %a.latch
1057 ; CHECK: d.latch:
1058 ; CHECK-NEXT: store i32 %x.a, i32* %ptr
1059 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
1060 ; CHECK-NEXT: store i32 %[[X_C_LCSSA]], i32* %ptr
1061 ; CHECK-NEXT: %v2 = call i1 @cond()
1062 ; CHECK-NEXT: br i1 %v2, label %d.header, label %a.latch
1063
1064 c.latch:
1065 %v3 = call i1 @cond()
1066 br i1 %v3, label %c.header, label %b.latch
1067 ; CHECK: c.latch:
1068 ; CHECK-NEXT: %v3 = call i1 @cond()
1069 ; CHECK-NEXT: br i1 %v3, label %c.header, label %b.latch
1070
1071 b.latch:
1072 br label %b.header
1073 ; CHECK: b.latch:
1074 ; CHECK-NEXT: br label %b.header
1075
1076 a.latch:
1077 br label %a.header
1078 ; CHECK: a.latch:
1079 ; CHECK-NEXT: br label %a.header
1080
1081 exit:
1082 ret void
1083 ; CHECK: exit:
1084 ; CHECK-NEXT: ret void
1085 }
1086
1087 ; Same as `@hoist_inner_loop2` but using a switch.
1088 ; Unswitch will transform the loop nest from:
1089 ; A < B < C
1090 ; into
1091 ; (A < B), C
1092 define void @hoist_inner_loop_switch(i32* %ptr) {
1093 ; CHECK-LABEL: define void @hoist_inner_loop_switch(
1094 entry:
1095 br label %a.header
1096 ; CHECK: entry:
1097 ; CHECK-NEXT: br label %a.header
1098
1099 a.header:
1100 %x.a = load i32, i32* %ptr
1101 br label %b.header
1102 ; CHECK: a.header:
1103 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
1104 ; CHECK-NEXT: br label %b.header
1105
1106 b.header:
1107 %x.b = load i32, i32* %ptr
1108 %v1 = call i32 @cond.i32()
1109 br label %c.header
1110 ; CHECK: b.header:
1111 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
1112 ; CHECK-NEXT: %v1 = call i32 @cond.i32()
1113 ; CHECK-NEXT: switch i32 %v1, label %[[B_HEADER_SPLIT:.*]] [
1114 ; CHECK-NEXT: i32 1, label %b.latch
1115 ; CHECK-NEXT: i32 2, label %b.latch
1116 ; CHECK-NEXT: i32 3, label %b.latch
1117 ; CHECK-NEXT: ]
1118 ;
1119 ; CHECK: [[B_HEADER_SPLIT]]:
1120 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
1121 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
1122 ; CHECK-NEXT: br label %c.header
1123
1124 c.header:
1125 switch i32 %v1, label %c.latch [
1126 i32 1, label %b.latch
1127 i32 2, label %b.latch
1128 i32 3, label %b.latch
1129 ]
1130 ; CHECK: c.header:
1131 ; CHECK-NEXT: br label %c.latch
1132
1133 c.latch:
1134 ; Use values from other loops to check LCSSA form.
1135 store i32 %x.a, i32* %ptr
1136 store i32 %x.b, i32* %ptr
1137 %v2 = call i1 @cond()
1138 br i1 %v2, label %c.header, label %exit
1139 ; CHECK: c.latch:
1140 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
1141 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
1142 ; CHECK-NEXT: %v2 = call i1 @cond()
1143 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
1144
1145 b.latch:
1146 %v3 = call i1 @cond()
1147 br i1 %v3, label %b.header, label %a.latch
1148 ; CHECK: b.latch:
1149 ; CHECK-NEXT: %v3 = call i1 @cond()
1150 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
1151
1152 a.latch:
1153 br label %a.header
1154 ; CHECK: a.latch:
1155 ; CHECK-NEXT: br label %a.header
1156
1157 exit:
1158 ret void
1159 ; CHECK: exit:
1160 ; CHECK-NEXT: ret void
1161 }