xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/codegen-prepare-extload.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-win64 | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S | FileCheck %s --check-prefix=OPTALL --check-prefix=OPT --check-prefix=NONSTRESS
4*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S -stress-cgp-ext-ld-promotion | FileCheck %s --check-prefix=OPTALL --check-prefix=OPT --check-prefix=STRESS
5*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S -disable-cgp-ext-ld-promotion | FileCheck %s --check-prefix=OPTALL --check-prefix=DISABLE
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker; rdar://7304838
8*9880d681SAndroid Build Coastguard Worker; CodeGenPrepare should move the zext into the block with the load
9*9880d681SAndroid Build Coastguard Worker; so that SelectionDAG can select it with the load.
10*9880d681SAndroid Build Coastguard Worker;
11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo:
12*9880d681SAndroid Build Coastguard Worker; CHECK: movsbl ({{%rdi|%rcx}}), %eax
13*9880d681SAndroid Build Coastguard Worker;
14*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @foo
15*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
16*9880d681SAndroid Build Coastguard Worker; OPTALL-NEXT: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
17*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[ZEXT]], i32* %q
18*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
19*9880d681SAndroid Build Coastguard Workerdefine void @foo(i8* %p, i32* %q) {
20*9880d681SAndroid Build Coastguard Workerentry:
21*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
22*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
23*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
24*9880d681SAndroid Build Coastguard Workertrue:
25*9880d681SAndroid Build Coastguard Worker  %s = zext i8 %t to i32
26*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
27*9880d681SAndroid Build Coastguard Worker  ret void
28*9880d681SAndroid Build Coastguard Workerfalse:
29*9880d681SAndroid Build Coastguard Worker  ret void
30*9880d681SAndroid Build Coastguard Worker}
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a zextload is an operation with only one
33*9880d681SAndroid Build Coastguard Worker; argument to explicitly extend is in the way.
34*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteOneArg
35*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
36*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
37*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT]], 2
38*9880d681SAndroid Build Coastguard Worker; Make sure the operation is not promoted when the promotion pass is disabled.
39*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], 2
40*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
41*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q
42*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
43*9880d681SAndroid Build Coastguard Workerdefine void @promoteOneArg(i8* %p, i32* %q) {
44*9880d681SAndroid Build Coastguard Workerentry:
45*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
46*9880d681SAndroid Build Coastguard Worker  %add = add nuw i8 %t, 2
47*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
48*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
49*9880d681SAndroid Build Coastguard Workertrue:
50*9880d681SAndroid Build Coastguard Worker  %s = zext i8 %add to i32
51*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
52*9880d681SAndroid Build Coastguard Worker  ret void
53*9880d681SAndroid Build Coastguard Workerfalse:
54*9880d681SAndroid Build Coastguard Worker  ret void
55*9880d681SAndroid Build Coastguard Worker}
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a sextload is an operation with only one
58*9880d681SAndroid Build Coastguard Worker; argument to explicitly extend is in the way.
59*9880d681SAndroid Build Coastguard Worker; Version with sext.
60*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteOneArgSExt
61*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
62*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXT:%[a-zA-Z_0-9-]+]] = sext i8 [[LD]] to i32
63*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[SEXT]], 2
64*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], 2
65*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32
66*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q
67*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
68*9880d681SAndroid Build Coastguard Workerdefine void @promoteOneArgSExt(i8* %p, i32* %q) {
69*9880d681SAndroid Build Coastguard Workerentry:
70*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
71*9880d681SAndroid Build Coastguard Worker  %add = add nsw i8 %t, 2
72*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
73*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
74*9880d681SAndroid Build Coastguard Workertrue:
75*9880d681SAndroid Build Coastguard Worker  %s = sext i8 %add to i32
76*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
77*9880d681SAndroid Build Coastguard Worker  ret void
78*9880d681SAndroid Build Coastguard Workerfalse:
79*9880d681SAndroid Build Coastguard Worker  ret void
80*9880d681SAndroid Build Coastguard Worker}
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a zextload is an operation with two
83*9880d681SAndroid Build Coastguard Worker; arguments to explicitly extend is in the way.
84*9880d681SAndroid Build Coastguard Worker; Extending %add will create two extensions:
85*9880d681SAndroid Build Coastguard Worker; 1. One for %b.
86*9880d681SAndroid Build Coastguard Worker; 2. One for %t.
87*9880d681SAndroid Build Coastguard Worker; #1 will not be removed as we do not know anything about %b.
88*9880d681SAndroid Build Coastguard Worker; #2 may not be merged with the load because %t is used in a comparison.
89*9880d681SAndroid Build Coastguard Worker; Since two extensions may be emitted in the end instead of one before the
90*9880d681SAndroid Build Coastguard Worker; transformation, the regular heuristic does not apply the optimization.
91*9880d681SAndroid Build Coastguard Worker;
92*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteTwoArgZext
93*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
94*9880d681SAndroid Build Coastguard Worker;
95*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
96*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i8 %b to i32
97*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]]
98*9880d681SAndroid Build Coastguard Worker;
99*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b
100*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
101*9880d681SAndroid Build Coastguard Worker;
102*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b
103*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
104*9880d681SAndroid Build Coastguard Worker;
105*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q
106*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
107*9880d681SAndroid Build Coastguard Workerdefine void @promoteTwoArgZext(i8* %p, i32* %q, i8 %b) {
108*9880d681SAndroid Build Coastguard Workerentry:
109*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
110*9880d681SAndroid Build Coastguard Worker  %add = add nuw i8 %t, %b
111*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
112*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
113*9880d681SAndroid Build Coastguard Workertrue:
114*9880d681SAndroid Build Coastguard Worker  %s = zext i8 %add to i32
115*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
116*9880d681SAndroid Build Coastguard Worker  ret void
117*9880d681SAndroid Build Coastguard Workerfalse:
118*9880d681SAndroid Build Coastguard Worker  ret void
119*9880d681SAndroid Build Coastguard Worker}
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a sextload is an operation with two
122*9880d681SAndroid Build Coastguard Worker; arguments to explicitly extend is in the way.
123*9880d681SAndroid Build Coastguard Worker; Version with sext.
124*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteTwoArgSExt
125*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
126*9880d681SAndroid Build Coastguard Worker;
127*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[SEXTLD:%[a-zA-Z_0-9-]+]] = sext i8 [[LD]] to i32
128*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[SEXTB:%[a-zA-Z_0-9-]+]] = sext i8 %b to i32
129*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[SEXTLD]], [[SEXTB]]
130*9880d681SAndroid Build Coastguard Worker;
131*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], %b
132*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32
133*9880d681SAndroid Build Coastguard Worker;
134*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], %b
135*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32
136*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q
137*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
138*9880d681SAndroid Build Coastguard Workerdefine void @promoteTwoArgSExt(i8* %p, i32* %q, i8 %b) {
139*9880d681SAndroid Build Coastguard Workerentry:
140*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
141*9880d681SAndroid Build Coastguard Worker  %add = add nsw i8 %t, %b
142*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
143*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
144*9880d681SAndroid Build Coastguard Workertrue:
145*9880d681SAndroid Build Coastguard Worker  %s = sext i8 %add to i32
146*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
147*9880d681SAndroid Build Coastguard Worker  ret void
148*9880d681SAndroid Build Coastguard Workerfalse:
149*9880d681SAndroid Build Coastguard Worker  ret void
150*9880d681SAndroid Build Coastguard Worker}
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker; Check that we do not a zextload if we need to introduce more than
153*9880d681SAndroid Build Coastguard Worker; one additional extension.
154*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteThreeArgZext
155*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
156*9880d681SAndroid Build Coastguard Worker;
157*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
158*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i8 %b to i32
159*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[TMP:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]]
160*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTC:%[a-zA-Z_0-9-]+]] = zext i8 %c to i32
161*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[TMP]], [[ZEXTC]]
162*9880d681SAndroid Build Coastguard Worker;
163*9880d681SAndroid Build Coastguard Worker; NONSTRESS-NEXT: [[TMP:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b
164*9880d681SAndroid Build Coastguard Worker; NONSTRESS-NEXT: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[TMP]], %c
165*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
166*9880d681SAndroid Build Coastguard Worker;
167*9880d681SAndroid Build Coastguard Worker; DISABLE: add nuw i8
168*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8
169*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
170*9880d681SAndroid Build Coastguard Worker;
171*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q
172*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
173*9880d681SAndroid Build Coastguard Workerdefine void @promoteThreeArgZext(i8* %p, i32* %q, i8 %b, i8 %c) {
174*9880d681SAndroid Build Coastguard Workerentry:
175*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
176*9880d681SAndroid Build Coastguard Worker  %tmp = add nuw i8 %t, %b
177*9880d681SAndroid Build Coastguard Worker  %add = add nuw i8 %tmp, %c
178*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
179*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
180*9880d681SAndroid Build Coastguard Workertrue:
181*9880d681SAndroid Build Coastguard Worker  %s = zext i8 %add to i32
182*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
183*9880d681SAndroid Build Coastguard Worker  ret void
184*9880d681SAndroid Build Coastguard Workerfalse:
185*9880d681SAndroid Build Coastguard Worker  ret void
186*9880d681SAndroid Build Coastguard Worker}
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a zextload after promoting and merging
189*9880d681SAndroid Build Coastguard Worker; two extensions.
190*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteMergeExtArgZExt
191*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
192*9880d681SAndroid Build Coastguard Worker;
193*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
194*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i16 %b to i32
195*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]]
196*9880d681SAndroid Build Coastguard Worker;
197*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
198*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i16 [[ZEXTLD]], %b
199*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i16 [[ADD]] to i32
200*9880d681SAndroid Build Coastguard Worker;
201*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
202*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i16 [[ZEXTLD]], %b
203*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i16 [[ADD]] to i32
204*9880d681SAndroid Build Coastguard Worker;
205*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q
206*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
207*9880d681SAndroid Build Coastguard Workerdefine void @promoteMergeExtArgZExt(i8* %p, i32* %q, i16 %b) {
208*9880d681SAndroid Build Coastguard Workerentry:
209*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
210*9880d681SAndroid Build Coastguard Worker  %ext = zext i8 %t to i16
211*9880d681SAndroid Build Coastguard Worker  %add = add nuw i16 %ext, %b
212*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
213*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
214*9880d681SAndroid Build Coastguard Workertrue:
215*9880d681SAndroid Build Coastguard Worker  %s = zext i16 %add to i32
216*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
217*9880d681SAndroid Build Coastguard Worker  ret void
218*9880d681SAndroid Build Coastguard Workerfalse:
219*9880d681SAndroid Build Coastguard Worker  ret void
220*9880d681SAndroid Build Coastguard Worker}
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a sextload after promoting and merging
223*9880d681SAndroid Build Coastguard Worker; two extensions.
224*9880d681SAndroid Build Coastguard Worker; Version with sext.
225*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteMergeExtArgSExt
226*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
227*9880d681SAndroid Build Coastguard Worker;
228*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
229*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = sext i16 %b to i32
230*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[ZEXTLD]], [[ZEXTB]]
231*9880d681SAndroid Build Coastguard Worker;
232*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
233*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i16 [[ZEXTLD]], %b
234*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32
235*9880d681SAndroid Build Coastguard Worker;
236*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
237*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i16 [[ZEXTLD]], %b
238*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32
239*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q
240*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
241*9880d681SAndroid Build Coastguard Workerdefine void @promoteMergeExtArgSExt(i8* %p, i32* %q, i16 %b) {
242*9880d681SAndroid Build Coastguard Workerentry:
243*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
244*9880d681SAndroid Build Coastguard Worker  %ext = zext i8 %t to i16
245*9880d681SAndroid Build Coastguard Worker  %add = add nsw i16 %ext, %b
246*9880d681SAndroid Build Coastguard Worker  %a = icmp slt i8 %t, 20
247*9880d681SAndroid Build Coastguard Worker  br i1 %a, label %true, label %false
248*9880d681SAndroid Build Coastguard Workertrue:
249*9880d681SAndroid Build Coastguard Worker  %s = sext i16 %add to i32
250*9880d681SAndroid Build Coastguard Worker  store i32 %s, i32* %q
251*9880d681SAndroid Build Coastguard Worker  ret void
252*9880d681SAndroid Build Coastguard Workerfalse:
253*9880d681SAndroid Build Coastguard Worker  ret void
254*9880d681SAndroid Build Coastguard Worker}
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker; Check that we manage to catch all the extload opportunities that are exposed
257*9880d681SAndroid Build Coastguard Worker; by the different iterations of codegen prepare.
258*9880d681SAndroid Build Coastguard Worker; Moreover, check that we do not promote more than we need to.
259*9880d681SAndroid Build Coastguard Worker; Here is what is happening in this test (not necessarly in this order):
260*9880d681SAndroid Build Coastguard Worker; 1. We try to promote the operand of %sextadd.
261*9880d681SAndroid Build Coastguard Worker;    a. This creates one sext of %ld2 and one of %zextld
262*9880d681SAndroid Build Coastguard Worker;    b. The sext of %ld2 can be combine with %ld2, so we remove one sext but
263*9880d681SAndroid Build Coastguard Worker;       introduced one. This is fine with the current heuristic: neutral.
264*9880d681SAndroid Build Coastguard Worker;    => We have one zext of %zextld left and we created one sext of %ld2.
265*9880d681SAndroid Build Coastguard Worker; 2. We try to promote the operand of %sextaddza.
266*9880d681SAndroid Build Coastguard Worker;    a. This creates one sext of %zexta and one of %zextld
267*9880d681SAndroid Build Coastguard Worker;    b. The sext of %zexta does not lead to any load, it stays here, even if it
268*9880d681SAndroid Build Coastguard Worker;       could have been combine with the zext of %a.
269*9880d681SAndroid Build Coastguard Worker;    c. The sext of %zextld leads to %ld and can be combined with it. This is
270*9880d681SAndroid Build Coastguard Worker;       done by promoting %zextld. This is fine with the current heuristic:
271*9880d681SAndroid Build Coastguard Worker;       neutral.
272*9880d681SAndroid Build Coastguard Worker;    => We have created a new zext of %ld and we created one sext of %zexta.
273*9880d681SAndroid Build Coastguard Worker; 3. We try to promote the operand of %sextaddb.
274*9880d681SAndroid Build Coastguard Worker;    a. This creates one sext of %b and one of %zextld
275*9880d681SAndroid Build Coastguard Worker;    b. The sext of %b is a dead-end, nothing to be done.
276*9880d681SAndroid Build Coastguard Worker;    c. Same thing as 2.c. happens.
277*9880d681SAndroid Build Coastguard Worker;    => We have created a new zext of %ld and we created one sext of %b.
278*9880d681SAndroid Build Coastguard Worker; 4. We try to promote the operand of the zext of %zextld introduced in #1.
279*9880d681SAndroid Build Coastguard Worker;    a. Same thing as 2.c. happens.
280*9880d681SAndroid Build Coastguard Worker;    b. %zextld does not have any other uses. It is dead coded.
281*9880d681SAndroid Build Coastguard Worker;    => We have created a new zext of %ld and we removed a zext of %zextld and
282*9880d681SAndroid Build Coastguard Worker;       a zext of %ld.
283*9880d681SAndroid Build Coastguard Worker; Currently we do not try to reuse existing extensions, so in the end we have
284*9880d681SAndroid Build Coastguard Worker; 3 identical zext of %ld. The extensions will be CSE'ed by SDag.
285*9880d681SAndroid Build Coastguard Worker;
286*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @severalPromotions
287*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %addr1
288*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTLD1_1:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64
289*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTLD1_2:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64
290*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTLD1_3:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64
291*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[LD2:%[a-zA-Z_0-9-]+]] = load i32, i32* %addr2
292*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXTLD2:%[a-zA-Z_0-9-]+]] = sext i32 [[LD2]] to i64
293*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTLD2]], [[ZEXTLD1_1]]
294*9880d681SAndroid Build Coastguard Worker; We do not combine this one: see 2.b.
295*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTA:%[a-zA-Z_0-9-]+]] = zext i8 %a to i32
296*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXTZEXTA:%[a-zA-Z_0-9-]+]] = sext i32 [[ZEXTA]] to i64
297*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RESZA:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTZEXTA]], [[ZEXTLD1_3]]
298*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXTB:%[a-zA-Z_0-9-]+]] = sext i32 %b to i64
299*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RESB:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTB]], [[ZEXTLD1_2]]
300*9880d681SAndroid Build Coastguard Worker;
301*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i32
302*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]]  = sext i32 [[ADD]] to i64
303*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADDZA:%[a-zA-Z_0-9-]+]] = add nsw i32
304*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RESZA:%[a-zA-Z_0-9-]+]]  = sext i32 [[ADDZA]] to i64
305*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADDB:%[a-zA-Z_0-9-]+]] = add nsw i32
306*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RESB:%[a-zA-Z_0-9-]+]]  = sext i32 [[ADDB]] to i64
307*9880d681SAndroid Build Coastguard Worker;
308*9880d681SAndroid Build Coastguard Worker; OPTALL: call void @dummy(i64 [[RES]], i64 [[RESZA]], i64 [[RESB]])
309*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
310*9880d681SAndroid Build Coastguard Workerdefine void @severalPromotions(i8* %addr1, i32* %addr2, i8 %a, i32 %b) {
311*9880d681SAndroid Build Coastguard Worker  %ld = load i8, i8* %addr1
312*9880d681SAndroid Build Coastguard Worker  %zextld = zext i8 %ld to i32
313*9880d681SAndroid Build Coastguard Worker  %ld2 = load i32, i32* %addr2
314*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %ld2, %zextld
315*9880d681SAndroid Build Coastguard Worker  %sextadd = sext i32 %add to i64
316*9880d681SAndroid Build Coastguard Worker  %zexta = zext i8 %a to i32
317*9880d681SAndroid Build Coastguard Worker  %addza = add nsw i32 %zexta, %zextld
318*9880d681SAndroid Build Coastguard Worker  %sextaddza = sext i32 %addza to i64
319*9880d681SAndroid Build Coastguard Worker  %addb = add nsw i32 %b, %zextld
320*9880d681SAndroid Build Coastguard Worker  %sextaddb = sext i32 %addb to i64
321*9880d681SAndroid Build Coastguard Worker  call void @dummy(i64 %sextadd, i64 %sextaddza, i64 %sextaddb)
322*9880d681SAndroid Build Coastguard Worker  ret void
323*9880d681SAndroid Build Coastguard Worker}
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Workerdeclare void @dummy(i64, i64, i64)
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker; Make sure we do not try to promote vector types since the type promotion
328*9880d681SAndroid Build Coastguard Worker; helper does not support them for now.
329*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @vectorPromotion
330*9880d681SAndroid Build Coastguard Worker; OPTALL: [[SHL:%[a-zA-Z_0-9-]+]] = shl nuw nsw <2 x i32> zeroinitializer, <i32 8, i32 8>
331*9880d681SAndroid Build Coastguard Worker; OPTALL: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext <2 x i32> [[SHL]] to <2 x i64>
332*9880d681SAndroid Build Coastguard Worker; OPTALL: ret
333*9880d681SAndroid Build Coastguard Workerdefine void @vectorPromotion() {
334*9880d681SAndroid Build Coastguard Workerentry:
335*9880d681SAndroid Build Coastguard Worker  %a = shl nuw nsw <2 x i32> zeroinitializer, <i32 8, i32 8>
336*9880d681SAndroid Build Coastguard Worker  %b = zext <2 x i32> %a to <2 x i64>
337*9880d681SAndroid Build Coastguard Worker  ret void
338*9880d681SAndroid Build Coastguard Worker}
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker@a = common global i32 0, align 4
341*9880d681SAndroid Build Coastguard Worker@c = common global [2 x i32] zeroinitializer, align 4
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker; PR21978.
344*9880d681SAndroid Build Coastguard Worker; Make sure we support promotion of operands that produces a Value as opposed
345*9880d681SAndroid Build Coastguard Worker; to an instruction.
346*9880d681SAndroid Build Coastguard Worker; This used to cause a crash.
347*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promotionOfArgEndsUpInValue
348*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i16, i16* %addr
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXT:%[a-zA-Z_0-9-]+]] = sext i16 [[LD]] to i32
351*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw nsw i32 [[SEXT]], zext (i1 icmp ne (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @c, i64 0, i64 1), i32* @a) to i32)
352*9880d681SAndroid Build Coastguard Worker;
353*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw nsw i16 [[LD]], zext (i1 icmp ne (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @c, i64 0, i64 1), i32* @a) to i16)
354*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32
355*9880d681SAndroid Build Coastguard Worker;
356*9880d681SAndroid Build Coastguard Worker; OPTALL-NEXT: ret i32 [[RES]]
357*9880d681SAndroid Build Coastguard Workerdefine i32 @promotionOfArgEndsUpInValue(i16* %addr) {
358*9880d681SAndroid Build Coastguard Workerentry:
359*9880d681SAndroid Build Coastguard Worker  %val = load i16, i16* %addr
360*9880d681SAndroid Build Coastguard Worker  %add = add nuw nsw i16 %val, zext (i1 icmp ne (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @c, i64 0, i64 1), i32* @a) to i16)
361*9880d681SAndroid Build Coastguard Worker  %conv3 = sext i16 %add to i32
362*9880d681SAndroid Build Coastguard Worker  ret i32 %conv3
363*9880d681SAndroid Build Coastguard Worker}
364*9880d681SAndroid Build Coastguard Worker
365*9880d681SAndroid Build Coastguard Worker; Check that we see that one zext can be derived from the other for free.
366*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteTwoArgZextWithSourceExtendedTwice
367*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXT64:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64
370*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXT32:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
371*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES32:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT32]], %b
372*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES64:%[a-zA-Z_0-9-]+]] = add nuw i64 [[ZEXT64]], 12
373*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: store i32 [[RES32]], i32* %addr
374*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: store i64 [[RES64]], i64* %q
375*9880d681SAndroid Build Coastguard Worker;
376*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[ZEXT32:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
377*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[RES32:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT32]], %b
378*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[RES2_32:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT32]], 12
379*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: store i32 [[RES32]], i32* %addr
380*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[ZEXT64:%[a-zA-Z_0-9-]+]] = zext i32 [[RES2_32]] to i64
381*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: store i64 [[ZEXT64]], i64* %q
382*9880d681SAndroid Build Coastguard Worker;
383*9880d681SAndroid Build Coastguard Worker; OPTALL-NEXT: ret void
384*9880d681SAndroid Build Coastguard Workerdefine void @promoteTwoArgZextWithSourceExtendedTwice(i8* %p, i64* %q, i32 %b, i32* %addr) {
385*9880d681SAndroid Build Coastguard Workerentry:
386*9880d681SAndroid Build Coastguard Worker  %t = load i8, i8* %p
387*9880d681SAndroid Build Coastguard Worker  %zextt = zext i8 %t to i32
388*9880d681SAndroid Build Coastguard Worker  %add = add nuw i32 %zextt, %b
389*9880d681SAndroid Build Coastguard Worker  %add2 = add nuw i32 %zextt, 12
390*9880d681SAndroid Build Coastguard Worker  store i32 %add, i32 *%addr
391*9880d681SAndroid Build Coastguard Worker  %s = zext i32 %add2 to i64
392*9880d681SAndroid Build Coastguard Worker  store i64 %s, i64* %q
393*9880d681SAndroid Build Coastguard Worker  ret void
394*9880d681SAndroid Build Coastguard Worker}
395