Skip to content

Commit fb7d114

Browse files
authored
1 parent 4ae529b commit fb7d114

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ static void buildPartialInvariantUnswitchConditionalBranch(
297297
for (auto *Val : reverse(ToDuplicate)) {
298298
Instruction *Inst = cast<Instruction>(Val);
299299
Instruction *NewInst = Inst->clone();
300+
301+
if (const DebugLoc &DL = Inst->getDebugLoc())
302+
mapAtomInstance(DL, VMap);
303+
300304
NewInst->insertInto(&BB, BB.end());
301305
RemapInstruction(NewInst, VMap,
302306
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
; RUN: opt %s -S --passes="loop-mssa(simple-loop-unswitch<nontrivial>)" -o - \
2+
; RUN: | FileCheck %s
3+
4+
;; Unswitch from:
5+
;; +- noclobber -+
6+
;; | v
7+
;; entry -> loop.header loop.latch -> exit.
8+
;; ^ | ^ |
9+
;; | +- clobber ---+ |
10+
;; +--------------------------------+
11+
;;
12+
;; To (unswitched loop unconditionally branches to noclobber.us):
13+
;; +---------------------------------------------+
14+
;; V |
15+
;; +- entry.split.us -> loop.header.us -> noclobber.us -> loop.latch.us -> exit.split.us -+
16+
;; | |
17+
;; entry |
18+
;; | v
19+
;; +- entry.split -> loop.header -> noclobber -> loop.latch -> exit.split --------------> exit.
20+
;; ^ | ^ |
21+
;; | +--> clobber -----+ |
22+
;; +------------------------------------+
23+
;;
24+
;; Check the duplicated instructions get remapped source atoms. Note some
25+
;; instructions get duplicated from loop.header into entry too.
26+
27+
; CHECK-LABEL: define i32 @partial_unswitch_true_successor_hoist_invariant(
28+
; CHECK-SAME: ptr [[PTR:%.*]], i32 [[N:%.*]]) !dbg [[DBG5:![0-9]+]] {
29+
30+
;; Instructions duplicated from loop.header need remapped atoms.
31+
; CHECK-NEXT: [[ENTRY:.*:]]
32+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[PTR]], i64 1, !dbg [[DBG8:![0-9]+]]
33+
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4, !dbg [[DBG9:![0-9]+]]
34+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 100, !dbg [[DBG10:![0-9]+]]
35+
; CHECK-NEXT: br i1 [[TMP2]], label %[[ENTRY_SPLIT_US:.*]], label %[[ENTRY_SPLIT:.*]]
36+
37+
;; Same source location as entry's original br, with remapped atom group.
38+
; CHECK: [[ENTRY_SPLIT_US]]:
39+
; CHECK-NEXT: br label %[[LOOP_HEADER_US:.*]], !dbg [[DBG11:![0-9]+]]
40+
41+
;; Instructions duplicated from loop.header need remapped atoms.
42+
; CHECK: [[LOOP_HEADER_US]]:
43+
; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, %[[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], %[[LOOP_LATCH_US:.*]] ], !dbg [[DBG12:![0-9]+]]
44+
; CHECK-NEXT: br label %[[NOCLOBBER_US:.*]], !dbg [[DBG13:![0-9]+]]
45+
46+
;; Instructions duplicated from noclobber need remapped atoms.
47+
; CHECK: [[NOCLOBBER_US]]:
48+
; CHECK-NEXT: br label %[[LOOP_LATCH_US]], !dbg [[DBG14:![0-9]+]]
49+
50+
; CHECK: [[LOOP_LATCH_US]]:
51+
; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N]], !dbg [[DBG15:![0-9]+]]
52+
; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1, !dbg [[DBG16:![0-9]+]]
53+
; CHECK-NEXT: br i1 [[C_US]], label %[[LOOP_HEADER_US]], label %[[EXIT_SPLIT_US:.*]], !dbg [[DBG17:![0-9]+]]
54+
55+
;; Split from exit, this DILocation shouldn't have source atom info.
56+
; CHECK: [[EXIT_SPLIT_US]]:
57+
; CHECK-NEXT: br label %[[EXIT:.*]], !dbg [[DBG18:![0-9]+]]
58+
59+
;; Same source location as entry's original br, with remapped atom group.
60+
; CHECK: [[ENTRY_SPLIT]]:
61+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]], !dbg [[DBG19:![0-9]+]]
62+
63+
;; Original loop blocks - the atoms groups should be distinct from those
64+
;; on duplicated instructions in the blocks above.
65+
; CHECK: [[LOOP_HEADER]]:
66+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], !dbg [[DBG20:![0-9]+]]
67+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i64 1, !dbg [[DBG21:![0-9]+]]
68+
; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4, !dbg [[DBG22:![0-9]+]]
69+
; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100, !dbg [[DBG23:![0-9]+]]
70+
; CHECK-NEXT: br i1 [[SC]], label %[[NOCLOBBER:.*]], label %[[CLOBBER:.*]], !dbg [[DBG24:![0-9]+]]
71+
; CHECK: [[NOCLOBBER]]:
72+
; CHECK-NEXT: br label %[[LOOP_LATCH]], !dbg [[DBG25:![0-9]+]]
73+
; CHECK: [[CLOBBER]]:
74+
; CHECK-NEXT: call void @clobber(), !dbg [[DBG26:![0-9]+]]
75+
; CHECK-NEXT: br label %[[LOOP_LATCH]], !dbg [[DBG27:![0-9]+]]
76+
; CHECK: [[LOOP_LATCH]]:
77+
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]], !dbg [[DBG28:![0-9]+]]
78+
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1, !dbg [[DBG29:![0-9]+]]
79+
; CHECK-NEXT: br i1 [[C]], label %[[LOOP_HEADER]], label %[[EXIT_SPLIT:.*]], !dbg [[DBG30:![0-9]+]]
80+
81+
;; Split from exit, this DILocation shouldn't have source atom info.
82+
; CHECK: [[EXIT_SPLIT]]:
83+
; CHECK-NEXT: br label %[[EXIT]], !dbg [[DBG18]]
84+
85+
;; exit.split and exit.split.us take the source location from here but drop its
86+
;; source atom info.
87+
; CHECK: [[EXIT]]:
88+
; CHECK-NEXT: ret i32 10, !dbg [[DBG33:![0-9]+]]
89+
90+
define i32 @partial_unswitch_true_successor_hoist_invariant(ptr %ptr, i32 %N) !dbg !5 {
91+
entry:
92+
br label %loop.header, !dbg !8
93+
94+
loop.header: ; preds = %loop.latch, %entry
95+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ], !dbg !9
96+
%gep = getelementptr i32, ptr %ptr, i64 1, !dbg !10
97+
%lv = load i32, ptr %gep, align 4, !dbg !11
98+
%sc = icmp eq i32 %lv, 100, !dbg !12
99+
br i1 %sc, label %noclobber, label %clobber, !dbg !13
100+
101+
noclobber: ; preds = %loop.header
102+
br label %loop.latch, !dbg !14
103+
104+
clobber: ; preds = %loop.header
105+
call void @clobber(), !dbg !15
106+
br label %loop.latch, !dbg !16
107+
108+
loop.latch: ; preds = %clobber, %noclobber
109+
%c = icmp ult i32 %iv, %N, !dbg !17
110+
%iv.next = add i32 %iv, 1, !dbg !18
111+
br i1 %c, label %loop.header, label %exit, !dbg !19
112+
113+
exit: ; preds = %loop.latch
114+
ret i32 10, !dbg !20
115+
}
116+
117+
declare void @clobber()
118+
119+
!llvm.dbg.cu = !{!0}
120+
!llvm.debugify = !{!2, !3}
121+
!llvm.module.flags = !{!4}
122+
123+
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
124+
!1 = !DIFile(filename: "test.ll", directory: "/")
125+
!2 = !{i32 13}
126+
!3 = !{i32 0}
127+
!4 = !{i32 2, !"Debug Info Version", i32 3}
128+
!5 = distinct !DISubprogram(name: "partial_unswitch_true_successor_hoist_invariant", linkageName: "partial_unswitch_true_successor_hoist_invariant", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
129+
!6 = !DISubroutineType(types: !7)
130+
!7 = !{}
131+
!8 = !DILocation(line: 1, scope: !5, atomGroup: 1, atomRank: 1)
132+
!9 = !DILocation(line: 2, scope: !5, atomGroup: 2, atomRank: 1)
133+
!10 = !DILocation(line: 3, scope: !5, atomGroup: 3, atomRank: 1)
134+
!11 = !DILocation(line: 4, scope: !5, atomGroup: 4, atomRank: 1)
135+
!12 = !DILocation(line: 5, scope: !5, atomGroup: 5, atomRank: 1)
136+
!13 = !DILocation(line: 6, scope: !5, atomGroup: 6, atomRank: 1)
137+
!14 = !DILocation(line: 7, scope: !5, atomGroup: 7, atomRank: 1)
138+
!15 = !DILocation(line: 8, scope: !5, atomGroup: 8, atomRank: 1)
139+
!16 = !DILocation(line: 9, scope: !5, atomGroup: 9, atomRank: 1)
140+
!17 = !DILocation(line: 10, scope: !5, atomGroup: 10, atomRank: 1)
141+
!18 = !DILocation(line: 11, scope: !5, atomGroup: 11, atomRank: 1)
142+
!19 = !DILocation(line: 12, scope: !5, atomGroup: 12, atomRank: 1)
143+
!20 = !DILocation(line: 13, scope: !5, atomGroup: 13, atomRank: 1)
144+
;.
145+
; CHECK: [[DBG8]] = !DILocation(line: 3{{.*}}, atomGroup: 24, atomRank: 1)
146+
; CHECK: [[DBG9]] = !DILocation(line: 4{{.*}}, atomGroup: 25, atomRank: 1)
147+
; CHECK: [[DBG10]] = !DILocation(line: 5{{.*}}, atomGroup: 26, atomRank: 1)
148+
; CHECK: [[DBG11]] = !DILocation(line: 1{{.*}}, atomGroup: 14, atomRank: 1)
149+
; CHECK: [[DBG12]] = !DILocation(line: 2{{.*}}, atomGroup: 15, atomRank: 1)
150+
; CHECK: [[DBG13]] = !DILocation(line: 6{{.*}}, atomGroup: 19, atomRank: 1)
151+
; CHECK: [[DBG14]] = !DILocation(line: 7{{.*}}, atomGroup: 20, atomRank: 1)
152+
; CHECK: [[DBG15]] = !DILocation(line: 10{{.*}}, atomGroup: 21, atomRank: 1)
153+
; CHECK: [[DBG16]] = !DILocation(line: 11{{.*}}, atomGroup: 22, atomRank: 1)
154+
; CHECK: [[DBG17]] = !DILocation(line: 12{{.*}}, atomGroup: 23, atomRank: 1)
155+
; CHECK: [[DBG18]] = !DILocation(line: 13, scope: ![[#]])
156+
; CHECK: [[DBG19]] = !DILocation(line: 1{{.*}}, atomGroup: 1, atomRank: 1)
157+
; CHECK: [[DBG20]] = !DILocation(line: 2{{.*}}, atomGroup: 2, atomRank: 1)
158+
; CHECK: [[DBG21]] = !DILocation(line: 3{{.*}}, atomGroup: 3, atomRank: 1)
159+
; CHECK: [[DBG22]] = !DILocation(line: 4{{.*}}, atomGroup: 4, atomRank: 1)
160+
; CHECK: [[DBG23]] = !DILocation(line: 5{{.*}}, atomGroup: 5, atomRank: 1)
161+
; CHECK: [[DBG24]] = !DILocation(line: 6{{.*}}, atomGroup: 6, atomRank: 1)
162+
; CHECK: [[DBG25]] = !DILocation(line: 7{{.*}}, atomGroup: 7, atomRank: 1)
163+
; CHECK: [[DBG26]] = !DILocation(line: 8{{.*}}, atomGroup: 8, atomRank: 1)
164+
; CHECK: [[DBG27]] = !DILocation(line: 9{{.*}}, atomGroup: 9, atomRank: 1)
165+
; CHECK: [[DBG28]] = !DILocation(line: 10{{.*}}, atomGroup: 10, atomRank: 1)
166+
; CHECK: [[DBG29]] = !DILocation(line: 11{{.*}}, atomGroup: 11, atomRank: 1)
167+
; CHECK: [[DBG30]] = !DILocation(line: 12{{.*}}, atomGroup: 12, atomRank: 1)
168+
; CHECK: [[DBG33]] = !DILocation(line: 13{{.*}}, atomGroup: 13, atomRank: 1)
169+
;.

0 commit comments

Comments
 (0)