1; RUN: opt -consthoist -S %s -o - | FileCheck %s --check-prefix=OPT
2; RUN: opt -consthoist -S -consthoist-min-num-to-rebase=1 %s -o - | FileCheck %s --check-prefix=OPT --check-prefix=OPT-1
3; RUN: opt -consthoist -S -consthoist-min-num-to-rebase=2 %s -o - | FileCheck %s --check-prefix=OPT --check-prefix=OPT-2
4; RUN: opt -consthoist -S -consthoist-min-num-to-rebase=3 %s -o - | FileCheck %s --check-prefix=OPT --check-prefix=OPT-3
5
6; RUN: llc -consthoist-min-num-to-rebase=2 %s -o - | FileCheck %s --check-prefix=LLC
7
8target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
9target triple = "thumbv6m-none-unknown-musleabi"
10
11; Test that constant 0 and 1 of i1 type is NOT hoisted due low
12; materializing cost.
13
14; OPT-LABEL: avalon
15; OPT: bb1:
16; OPT: store i1 true
17; OPT: bb2:
18; OPT: store i1 false
19; OPT: bb3:
20; OPT: store i1 false
21; OPT: store i1 false
22; OPT-NOT: add
23
24; LLC-LABEL: avalon
25; LLC-DAG: movs r{{[0-9]+}}, #0
26; LLC-DAG: movs r{{[0-9]+}}, #1
27; LLC-NOT: add
28
29@global = local_unnamed_addr global i1 undef, align 1
30@global.0 = local_unnamed_addr global i1 undef, align 1
31
32define void @avalon() #0 {
33bb:
34  switch i8 undef, label %bb5 [
35    i8 0, label %bb1
36    i8 -1, label %bb2
37    i8 1, label %bb3
38  ]
39
40bb1:
41  store i1 1, i1* @global, align 1
42  unreachable
43
44bb2:
45  store i1 0, i1* @global, align 1
46  unreachable
47
48bb3:
49  store i1 0, i1* @global.0, align 1
50  store i1 0, i1* @global, align 1
51  unreachable
52
53bb5:
54  ret void
55}
56
57; Test that for i8 type, constant -1 is not rebased since it's the only
58; dependent of base constant -2.
59; This test is also covered by r342898, see
60; test/CodeGen/Thumb/consthoist-imm8-costs-1.ll
61
62; OPT-2-LABEL: barney
63; OPT-2: bb1:
64; OPT-2: store i8 -1
65; OPT-2: bb2:
66; OPT-2: store i8 -2
67; OPT-2: bb3:
68; OPT-2: store i8 -2
69; OPT-2: store i8 -2
70; OPT-2-NOT: add
71
72; LLC-LABEL: barney
73; LLC-DAG: movs r{{[0-9]+}}, #254
74; LLC-DAG: movs r{{[0-9]+}}, #255
75; LLC-NOT: mvn
76; LLC-NOT: add
77
78@global.1 = local_unnamed_addr global i8 undef, align 1
79@global.2 = local_unnamed_addr global i8 undef, align 1
80
81define void @barney() #0 {
82bb:
83  switch i8 undef, label %bb5 [
84    i8 0, label %bb1
85    i8 -1, label %bb2
86    i8 1, label %bb3
87  ]
88
89bb1:                                              ; preds = %bb
90  store i8 -1, i8* @global.1, align 1
91  unreachable
92
93bb2:                                              ; preds = %bb
94  store i8 -2, i8* @global.1, align 1
95  unreachable
96
97bb3:                                              ; preds = %bb
98  store i8 -2, i8* @global.2, align 1
99  store i8 -2, i8* @global.1, align 1
100  unreachable
101
102bb5:                                              ; preds = %bb
103  ret void
104}
105
106; Test that for i16 type constant 65532 is not rebased if it's the only
107; dependent of base constant 65531. Cost would be the same if rebased.
108; If rebased, 3 two-byte instructions:
109;   movs    r0, #4
110;   mvns    r0, r0
111;   adds    r0, r0, #1
112; If NOT rebased, 1 two-byte instruction plus 1 four-byte CP entry:
113;           ldr     r1, .LCPI2_3
114;           ...
115;   .LCPI2_3:
116;           .long   65532
117
118; OPT-LABEL: carla
119
120; -consthoist-min-num-to-rebase=1, check that 65532 and single use of 65531
121; in bb2 is rebased
122; OPT-1: bb1:
123; OPT-1: %[[C1:const[0-9]?]] = bitcast i16 -5 to i16
124; OPT-1-NEXT: %const_mat = add i16 %[[C1]], 1
125; OPT-1-NEXT: store i16 %const_mat, i16* @global.3, align 1
126; OPT-1: bb2:
127; OPT-1-NEXT: %[[C2:const[0-9]?]] = bitcast i16 -5 to i16
128; OPT-1-NEXT: store i16 %[[C2]], i16* @global.3, align 1
129; OPT-1: bb3:
130; OPT-1-NEXT: %[[C3:const[0-9]?]] = bitcast i16 -5 to i16
131; OPT-1-NEXT: store i16 %[[C3]], i16* @global.4, align 1
132; OPT-1-NEXT: store i16 %[[C3]], i16* @global.3, align 1
133
134; -consthoist-min-num-to-rebase=2, check that 65532 and single use of 65531
135; in bb2 is not rebased
136; OPT-2: bb1:
137; OPT-2-NEXT: store i16 -4, i16* @global.3, align 1
138; OPT-2: bb2:
139; OPT-2-NEXT: store i16 -5, i16* @global.3, align 1
140; OPT-2: bb3:
141; OPT-2-NEXT:   %[[C4:const[0-9]?]] = bitcast i16 -5 to i16
142; OPT-2-NEXT:   store i16 %[[C4]], i16* @global.4, align 1
143; OPT-2-NEXT:   store i16 %[[C4]], i16* @global.3, align 1
144; OPT-2-NOT: add
145
146; -consthoist-min-num-to-rebase=3, check that dual uses of 65531 in bb3 are
147; not rebase
148; OPT-3: bb1:
149; OPT-3-NEXT: store i16 -4, i16* @global.3, align 1
150; OPT-3: bb2:
151; OPT-3-NEXT: store i16 -5, i16* @global.3, align 1
152; OPT-3: bb3:
153; OPT-3-NEXT:   store i16 -5, i16* @global.4, align 1
154; OPT-3-NEXT:   store i16 -5, i16* @global.3, align 1
155; OPT-3-NOT: add
156; OPT-3-NOT: bitcast
157
158; LLC-LABEL: carla
159; LLC-DAG: ldr r{{[0-9]+}}, .LCPI2_1
160; LLC-DAG: ldr r{{[0-9]+}}, .LCPI2_3
161; LLC-NOT: mvn
162; LLC-NOT: add
163
164@global.3 = local_unnamed_addr global i16 undef, align 2
165@global.4 = local_unnamed_addr global i16 undef, align 2
166
167define void @carla() {
168bb:
169  switch i8 undef, label %bb5 [
170    i8 0, label %bb1
171    i8 -1, label %bb2
172    i8 1, label %bb3
173  ]
174
175bb1:                                              ; preds = %bb
176  store i16 65532, i16* @global.3, align 1
177  unreachable
178
179bb2:                                              ; preds = %bb
180  store i16 65531, i16* @global.3, align 1
181  unreachable
182
183bb3:                                              ; preds = %bb
184  store i16 65531, i16* @global.4, align 1
185  store i16 65531, i16* @global.3, align 1
186  unreachable
187
188bb5:                                              ; preds = %bb
189  ret void
190}
191