@@ -61,13 +61,13 @@ define void @loop_1_callbr(i1 %PredEntry, i1 %PredB, i1 %PredC, i1 %PredD) {
6161; CHECK-NEXT: br label [[B:%.*]]
6262; CHECK: B:
6363; CHECK-NEXT: callbr void asm "", "r,!i"(i1 [[PREDB:%.*]])
64- ; CHECK-NEXT: to label [[C:%.*]] [label %B.target.E ]
64+ ; CHECK-NEXT: to label [[C:%.*]] [label [[B_TARGET_E:%.*]] ]
6565; CHECK: C:
6666; CHECK-NEXT: callbr void asm "", "r,!i"(i1 [[PREDC:%.*]])
67- ; CHECK-NEXT: to label [[D:%.*]] [label %C.target.F ]
67+ ; CHECK-NEXT: to label [[D:%.*]] [label [[C_TARGET_F:%.*]] ]
6868; CHECK: D:
6969; CHECK-NEXT: callbr void asm "", "r,!i"(i1 [[PREDD:%.*]])
70- ; CHECK-NEXT: to label [[A]] [label %D.target.F ]
70+ ; CHECK-NEXT: to label [[A]] [label [[D_TARGET_F:%.*]] ]
7171; CHECK: E:
7272; CHECK-NEXT: br label [[EXIT:%.*]]
7373; CHECK: F:
@@ -83,7 +83,7 @@ define void @loop_1_callbr(i1 %PredEntry, i1 %PredB, i1 %PredC, i1 %PredD) {
8383; CHECK: D.target.F:
8484; CHECK-NEXT: br label [[LOOP_EXIT_GUARD]]
8585; CHECK: loop.exit.guard:
86- ; CHECK-NEXT: [[GUARD_X:%.*]] = phi i1 [ true, [[B_TARGET_E:%.* ]] ], [ false, [[C_TARGET_F:%.* ]] ], [ false, [[D_TARGET_F:%.* ]] ]
86+ ; CHECK-NEXT: [[GUARD_X:%.*]] = phi i1 [ true, [[B_TARGET_E]] ], [ false, [[C_TARGET_F]] ], [ false, [[D_TARGET_F]] ]
8787; CHECK-NEXT: br i1 [[GUARD_X]], label [[X:%.*]], label [[Y]]
8888;
8989entry:
@@ -175,13 +175,13 @@ define void @loop_2_callbr(i1 %PredA, i1 %PredB, i1 %PredC) {
175175; CHECK-NEXT: br label [[A:%.*]]
176176; CHECK: A:
177177; CHECK-NEXT: callbr void asm "", "r,!i"(i1 [[PREDA:%.*]])
178- ; CHECK-NEXT: to label [[B:%.*]] [label %A.target.X ]
178+ ; CHECK-NEXT: to label [[B:%.*]] [label [[A_TARGET_X:%.*]] ]
179179; CHECK: B:
180180; CHECK-NEXT: callbr void asm "", "r,!i"(i1 [[PREDB:%.*]])
181- ; CHECK-NEXT: to label [[C:%.*]] [label %B.target.Y ]
181+ ; CHECK-NEXT: to label [[C:%.*]] [label [[B_TARGET_Y:%.*]] ]
182182; CHECK: C:
183183; CHECK-NEXT: callbr void asm "", "r,!i"(i1 [[PREDC:%.*]])
184- ; CHECK-NEXT: to label [[D:%.*]] [label %C.target.Z ]
184+ ; CHECK-NEXT: to label [[D:%.*]] [label [[C_TARGET_Z:%.*]] ]
185185; CHECK: D:
186186; CHECK-NEXT: br label [[A]]
187187; CHECK: X:
@@ -199,7 +199,7 @@ define void @loop_2_callbr(i1 %PredA, i1 %PredB, i1 %PredC) {
199199; CHECK: C.target.Z:
200200; CHECK-NEXT: br label [[LOOP_EXIT_GUARD]]
201201; CHECK: loop.exit.guard:
202- ; CHECK-NEXT: [[GUARD_X:%.*]] = phi i1 [ true, [[A_TARGET_X:%.* ]] ], [ false, [[B_TARGET_Y:%.* ]] ], [ false, [[C_TARGET_Z:%.* ]] ]
202+ ; CHECK-NEXT: [[GUARD_X:%.*]] = phi i1 [ true, [[A_TARGET_X]] ], [ false, [[B_TARGET_Y]] ], [ false, [[C_TARGET_Z]] ]
203203; CHECK-NEXT: [[GUARD_Y:%.*]] = phi i1 [ false, [[A_TARGET_X]] ], [ true, [[B_TARGET_Y]] ], [ false, [[C_TARGET_Z]] ]
204204; CHECK-NEXT: br i1 [[GUARD_X]], label [[X:%.*]], label [[LOOP_EXIT_GUARD1:%.*]]
205205; CHECK: loop.exit.guard1:
232232exit:
233233 ret void
234234}
235+
236+ ; Test that UnifyLoopExits handles callbr with duplicate successors correctly.
237+ ; The exit block appears twice as a successor of the callbr instruction.
238+ define void @callbr_duplicate_successors () {
239+ ; CHECK-LABEL: @callbr_duplicate_successors(
240+ ; CHECK-NEXT: entry:
241+ ; CHECK-NEXT: br label [[LOOP:%.*]]
242+ ; CHECK: loop:
243+ ; CHECK-NEXT: callbr void asm sideeffect "", "!i,!i"()
244+ ; CHECK-NEXT: to label [[LOOP_TARGET_EXIT:%.*]] [label [[LOOP]], label [[LOOP_TARGET_EXIT1:%.*]]]
245+ ; CHECK: exit:
246+ ; CHECK-NEXT: ret void
247+ ; CHECK: loop.target.exit:
248+ ; CHECK-NEXT: br label [[EXIT:%.*]]
249+ ; CHECK: loop.target.exit1:
250+ ; CHECK-NEXT: br label [[EXIT]]
251+ ;
252+ entry:
253+ br label %loop
254+
255+ loop:
256+ callbr void asm sideeffect "" , "!i,!i" ()
257+ to label %exit [label %loop , label %exit ]
258+
259+ exit:
260+ ret void
261+ }
0 commit comments