File: local-cse.ll

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 1,998,492 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (160 lines) | stat: -rw-r--r-- 7,553 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; Check that the default heuristic use the local cse constraints.
; RUN: opt -S -passes=reassociate,early-cse %s -o - | FileCheck %s -check-prefix=LOCAL_CSE
; RUN: opt -S -passes=reassociate,early-cse %s -reassociate-use-cse-local=true -o - | FileCheck %s -check-prefix=LOCAL_CSE
; RUN: opt -S -passes=reassociate,early-cse %s -reassociate-use-cse-local=false -o - | FileCheck %s -check-prefix=CSE


; Check that when we use the heuristic to expose only local (to the first
; encountered block) CSE opportunities, we choose the right sub expression
; to expose.
;
; In these example we have three chains of expressions:
; chain a: inv1, val_bb2, inv2, inv4
; chain b: inv1, val_bb2, inv2, inv5
; chain c: inv1, val_bb2, inv3
;
; The CSE-able pairs with there respective occurrences are:
; inv1, val_bb2: 3
; inv1, inv2: 2
;
; val_bb2 is anchored in bb2 but inv1 and inv2 can start in bb1.
; With the local heuristic we will push inv1, inv2 at the beginning
; of chain_a and chain_b.
; With the non-local heuristic we will push inv1, val_bb2.
define void @chain_spanning_several_blocks(i64 %inv1, i64 %inv2, i64 %inv3, i64 %inv4, i64 %inv5) {
; LOCAL_CSE-LABEL: define void @chain_spanning_several_blocks
; LOCAL_CSE-SAME: (i64 [[INV1:%.*]], i64 [[INV2:%.*]], i64 [[INV3:%.*]], i64 [[INV4:%.*]], i64 [[INV5:%.*]]) {
; LOCAL_CSE-NEXT:  bb1:
; LOCAL_CSE-NEXT:    [[CHAIN_A0:%.*]] = add nuw nsw i64 [[INV2]], [[INV1]]
; LOCAL_CSE-NEXT:    br label [[BB2:%.*]]
; LOCAL_CSE:       bb2:
; LOCAL_CSE-NEXT:    [[VAL_BB2:%.*]] = call i64 @get_val()
; LOCAL_CSE-NEXT:    [[CHAIN_A1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV4]]
; LOCAL_CSE-NEXT:    [[CHAIN_A2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[VAL_BB2]]
; LOCAL_CSE-NEXT:    [[CHAIN_B1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV5]]
; LOCAL_CSE-NEXT:    [[CHAIN_B2:%.*]] = add nuw nsw i64 [[CHAIN_B1]], [[VAL_BB2]]
; LOCAL_CSE-NEXT:    [[CHAIN_C0:%.*]] = add nuw nsw i64 [[INV3]], [[INV1]]
; LOCAL_CSE-NEXT:    [[CHAIN_C1:%.*]] = add nuw nsw i64 [[CHAIN_C0]], [[VAL_BB2]]
; LOCAL_CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_A2]])
; LOCAL_CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_B2]])
; LOCAL_CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_C1]])
; LOCAL_CSE-NEXT:    ret void
;
; CSE-LABEL: define void @chain_spanning_several_blocks
; CSE-SAME: (i64 [[INV1:%.*]], i64 [[INV2:%.*]], i64 [[INV3:%.*]], i64 [[INV4:%.*]], i64 [[INV5:%.*]]) {
; CSE-NEXT:  bb1:
; CSE-NEXT:    br label [[BB2:%.*]]
; CSE:       bb2:
; CSE-NEXT:    [[VAL_BB2:%.*]] = call i64 @get_val()
; CSE-NEXT:    [[CHAIN_A0:%.*]] = add nuw nsw i64 [[VAL_BB2]], [[INV1]]
; CSE-NEXT:    [[CHAIN_A1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV2]]
; CSE-NEXT:    [[CHAIN_A2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV4]]
; CSE-NEXT:    [[CHAIN_B2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV5]]
; CSE-NEXT:    [[CHAIN_C1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV3]]
; CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_A2]])
; CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_B2]])
; CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_C1]])
; CSE-NEXT:    ret void
;
bb1:
  %chain_a0 = add nuw nsw i64 %inv1, %inv2
  br label %bb2

bb2:
  %val_bb2 = call i64 @get_val()
  %chain_a1 = add nuw nsw i64 %chain_a0, %val_bb2
  %chain_a2 = add nuw nsw i64 %chain_a1, %inv4
  %chain_b0 = add nuw nsw i64 %val_bb2, %inv1
  %chain_b1 = add nuw nsw i64 %chain_b0, %inv2
  %chain_b2 = add nuw nsw i64 %chain_b1, %inv5
  %chain_c0 = add nuw nsw i64 %val_bb2, %inv3
  %chain_c1 = add nuw nsw i64 %chain_c0, %inv1
  call void @keep_alive(i64 %chain_a2)
  call void @keep_alive(i64 %chain_b2)
  call void @keep_alive(i64 %chain_c1)
  ret void
}

; Same as @chain_spanning_several_blocks, but with values that are all anchored
; on the non-entry block.
; I.e., same pair map as previous but with invX_bbY instead of invX.
; Note: Although %inv1_bb0 is anchored in the entry block, it doesn't constrain
; the sub expressions on the entry block because we need to see at least two
; values to be able to form a sub-expression and thus only the second one
; add a constraint.
define void @chain_spanning_several_blocks_no_entry_anchor() {
; LOCAL_CSE-LABEL: define void @chain_spanning_several_blocks_no_entry_anchor() {
; LOCAL_CSE-NEXT:  bb0:
; LOCAL_CSE-NEXT:    [[INV2_BB0:%.*]] = call i64 @get_val()
; LOCAL_CSE-NEXT:    br label [[BB1:%.*]]
; LOCAL_CSE:       bb1:
; LOCAL_CSE-NEXT:    [[INV1_BB1:%.*]] = call i64 @get_val()
; LOCAL_CSE-NEXT:    [[CHAIN_A0:%.*]] = add nuw nsw i64 [[INV1_BB1]], [[INV2_BB0]]
; LOCAL_CSE-NEXT:    br label [[BB2:%.*]]
; LOCAL_CSE:       bb2:
; LOCAL_CSE-NEXT:    [[INV3_BB2:%.*]] = call i64 @get_val()
; LOCAL_CSE-NEXT:    [[INV4_BB2:%.*]] = call i64 @get_val()
; LOCAL_CSE-NEXT:    [[INV5_BB2:%.*]] = call i64 @get_val()
; LOCAL_CSE-NEXT:    [[VAL_BB2:%.*]] = call i64 @get_val()
; LOCAL_CSE-NEXT:    [[CHAIN_A1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV4_BB2]]
; LOCAL_CSE-NEXT:    [[CHAIN_A2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[VAL_BB2]]
; LOCAL_CSE-NEXT:    [[CHAIN_B1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV5_BB2]]
; LOCAL_CSE-NEXT:    [[CHAIN_B2:%.*]] = add nuw nsw i64 [[CHAIN_B1]], [[VAL_BB2]]
; LOCAL_CSE-NEXT:    [[CHAIN_C0:%.*]] = add nuw nsw i64 [[VAL_BB2]], [[INV1_BB1]]
; LOCAL_CSE-NEXT:    [[CHAIN_C1:%.*]] = add nuw nsw i64 [[CHAIN_C0]], [[INV3_BB2]]
; LOCAL_CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_A2]])
; LOCAL_CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_B2]])
; LOCAL_CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_C1]])
; LOCAL_CSE-NEXT:    ret void
;
; CSE-LABEL: define void @chain_spanning_several_blocks_no_entry_anchor() {
; CSE-NEXT:  bb0:
; CSE-NEXT:    [[INV2_BB0:%.*]] = call i64 @get_val()
; CSE-NEXT:    br label [[BB1:%.*]]
; CSE:       bb1:
; CSE-NEXT:    [[INV1_BB1:%.*]] = call i64 @get_val()
; CSE-NEXT:    br label [[BB2:%.*]]
; CSE:       bb2:
; CSE-NEXT:    [[INV3_BB2:%.*]] = call i64 @get_val()
; CSE-NEXT:    [[INV4_BB2:%.*]] = call i64 @get_val()
; CSE-NEXT:    [[INV5_BB2:%.*]] = call i64 @get_val()
; CSE-NEXT:    [[VAL_BB2:%.*]] = call i64 @get_val()
; CSE-NEXT:    [[CHAIN_A0:%.*]] = add nuw nsw i64 [[VAL_BB2]], [[INV1_BB1]]
; CSE-NEXT:    [[CHAIN_A1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV2_BB0]]
; CSE-NEXT:    [[CHAIN_A2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV4_BB2]]
; CSE-NEXT:    [[CHAIN_B2:%.*]] = add nuw nsw i64 [[CHAIN_A1]], [[INV5_BB2]]
; CSE-NEXT:    [[CHAIN_C1:%.*]] = add nuw nsw i64 [[CHAIN_A0]], [[INV3_BB2]]
; CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_A2]])
; CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_B2]])
; CSE-NEXT:    call void @keep_alive(i64 [[CHAIN_C1]])
; CSE-NEXT:    ret void
;
bb0:
  %inv2_bb0 = call i64 @get_val()
  br label %bb1

bb1:
  %inv1_bb1 = call i64 @get_val()
  %chain_a0 = add nuw nsw i64 %inv1_bb1, %inv2_bb0
  br label %bb2

bb2:
  %inv3_bb2 = call i64 @get_val()
  %inv4_bb2 = call i64 @get_val()
  %inv5_bb2 = call i64 @get_val()
  %val_bb2 = call i64 @get_val()
  %chain_a1 = add nuw nsw i64 %chain_a0, %val_bb2
  %chain_a2 = add nuw nsw i64 %chain_a1, %inv4_bb2
  %chain_b0 = add nuw nsw i64 %val_bb2, %inv1_bb1
  %chain_b1 = add nuw nsw i64 %chain_b0, %inv2_bb0
  %chain_b2 = add nuw nsw i64 %chain_b1, %inv5_bb2
  %chain_c0 = add nuw nsw i64 %val_bb2, %inv3_bb2
  %chain_c1 = add nuw nsw i64 %chain_c0, %inv1_bb1
  call void @keep_alive(i64 %chain_a2)
  call void @keep_alive(i64 %chain_b2)
  call void @keep_alive(i64 %chain_c1)
  ret void
}
declare i64 @get_val()
declare void @keep_alive(i64)