1; This tries to be a comprehensive test of i64 operations, in
2; particular the patterns for lowering i64 operations into constituent
3; i32 operations on x86-32.
4
5; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
6; RUN:   --target x8632 -i %s --args -O2 -allow-externally-defined-symbols \
7; RUN:   | %if --need=target_X8632 --command FileCheck %s
8
9; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
10; RUN:   --target x8632 -i %s --args -Om1 -allow-externally-defined-symbols \
11; RUN:   | %if --need=target_X8632 --command FileCheck --check-prefix=OPTM1 %s
12
13; RUN: %if --need=target_ARM32 \
14; RUN:   --command %p2i --filetype=obj \
15; RUN:   --disassemble --target arm32 -i %s --args -O2 \
16; RUN:   -allow-externally-defined-symbols \
17; RUN:   | %if --need=target_ARM32 \
18; RUN:   --command FileCheck --check-prefix ARM32 --check-prefix ARM32-O2 %s
19; RUN: %if --need=target_ARM32 \
20; RUN:   --command %p2i --filetype=obj --disassemble --target arm32 \
21; RUN:   -i %s --args -Om1 \
22; RUN:   -allow-externally-defined-symbols \
23; RUN:   | %if --need=target_ARM32 \
24; RUN:   --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OM1 %s
25
26; TODO: Switch to --filetype=obj when possible.
27; RUN: %if --need=target_MIPS32 --need=allow_dump \
28; RUN:   --command %p2i --filetype=asm --assemble \
29; RUN:   --disassemble --target mips32 -i %s --args -O2 \
30; RUN:   -allow-externally-defined-symbols \
31; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
32; RUN:   --command FileCheck --check-prefix MIPS32 --check-prefix MIPS32-O2 %s
33
34; RUN: %if --need=target_MIPS32 --need=allow_dump \
35; RUN:   --command %p2i --filetype=asm --assemble \
36; RUN:   --disassemble --target mips32 -i %s --args -Om1 \
37; RUN:   -allow-externally-defined-symbols \
38; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
39; RUN:   --command FileCheck --check-prefix MIPS32 --check-prefix MIPS32-OM1 %s
40
41@__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
42@__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
43@__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8
44@__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4
45
46define internal i32 @ignore64BitArg(i64 %a, i32 %b, i64 %c) {
47entry:
48  ret i32 %b
49}
50
51; MIPS32-LABEL: ignore64BitArg
52; MIPS32-O2: move v0,a2
53; MIPS32-OM1: sw a2,[[MEM:.*]]
54; MIPS32-OM1: lw v0,[[MEM]]
55
56define internal i32 @pass64BitArg(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f) {
57entry:
58  %call = call i32 @ignore64BitArgNoInline(i64 %a, i32 123, i64 %b)
59  %call1 = call i32 @ignore64BitArgNoInline(i64 %c, i32 123, i64 %d)
60  %call2 = call i32 @ignore64BitArgNoInline(i64 %e, i32 123, i64 %f)
61  %add = add i32 %call1, %call
62  %add3 = add i32 %add, %call2
63  ret i32 %add3
64}
65; CHECK-LABEL: pass64BitArg
66; CHECK:      sub     esp
67; CHECK:      mov     DWORD PTR [esp+0x4]
68; CHECK:      mov     DWORD PTR [esp]
69; CHECK:      mov     DWORD PTR [esp+0x8],0x7b
70; CHECK:      mov     DWORD PTR [esp+0x10]
71; CHECK:      mov     DWORD PTR [esp+0xc]
72; CHECK:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
73; CHECK:      mov     DWORD PTR [esp+0x4]
74; CHECK:      mov     DWORD PTR [esp]
75; CHECK:      mov     DWORD PTR [esp+0x8],0x7b
76; CHECK:      mov     DWORD PTR [esp+0x10]
77; CHECK:      mov     DWORD PTR [esp+0xc]
78; CHECK:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
79; CHECK:      mov     DWORD PTR [esp+0x4]
80; CHECK:      mov     DWORD PTR [esp]
81; CHECK:      mov     DWORD PTR [esp+0x8],0x7b
82; CHECK:      mov     DWORD PTR [esp+0x10]
83; CHECK:      mov     DWORD PTR [esp+0xc]
84; CHECK:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
85;
86; OPTM1-LABEL: pass64BitArg
87; OPTM1:      sub     esp
88; OPTM1:      mov     DWORD PTR [esp+0x4]
89; OPTM1:      mov     DWORD PTR [esp]
90; OPTM1:      mov     DWORD PTR [esp+0x8],0x7b
91; OPTM1:      mov     DWORD PTR [esp+0x10]
92; OPTM1:      mov     DWORD PTR [esp+0xc]
93; OPTM1:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
94; OPTM1:      mov     DWORD PTR [esp+0x4]
95; OPTM1:      mov     DWORD PTR [esp]
96; OPTM1:      mov     DWORD PTR [esp+0x8],0x7b
97; OPTM1:      mov     DWORD PTR [esp+0x10]
98; OPTM1:      mov     DWORD PTR [esp+0xc]
99; OPTM1:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
100; OPTM1:      mov     DWORD PTR [esp+0x4]
101; OPTM1:      mov     DWORD PTR [esp]
102; OPTM1:      mov     DWORD PTR [esp+0x8],0x7b
103; OPTM1:      mov     DWORD PTR [esp+0x10]
104; OPTM1:      mov     DWORD PTR [esp+0xc]
105; OPTM1:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
106
107; ARM32-LABEL: pass64BitArg
108; ARM32:      str     {{.*}}, [sp]
109; ARM32:      mov     r2, #123
110; ARM32:      bl      {{.*}} ignore64BitArgNoInline
111; ARM32:      str     {{.*}}, [sp]
112; ARM32:      {{mov|ldr}} r0
113; ARM32:      {{mov|ldr}} r1
114; ARM32:      mov     r2, #123
115; ARM32:      bl      {{.*}} ignore64BitArgNoInline
116; ARM32:      str     {{.*}}, [sp]
117; ARM32:      {{mov|ldr}} r0
118; ARM32:      {{mov|ldr}} r1
119; ARM32:      mov     r2, #123
120; ARM32:      bl      {{.*}} ignore64BitArgNoInline
121
122; MIPS32-LABEL: pass64BitArg
123; MIPS32-O2: 	sw	a3,{{.*}}(sp)
124; MIPS32-O2: 	sw	a2,{{.*}}(sp)
125; MIPS32-O2: 	li	a2,123
126; MIPS32-O2: 	jal	{{.*}}	ignore64BitArgNoInline
127; MIPS32-O2: 	nop
128; MIPS32-O2: 	move	s0,v0
129; MIPS32-O2: 	sw	s3,{{.*}}(sp)
130; MIPS32-O2: 	sw	s2,{{.*}}(sp)
131; MIPS32-O2: 	lw	a0,{{.*}}(sp)
132; MIPS32-O2: 	move	a1,s1
133; MIPS32-O2: 	li	a2,123
134; MIPS32-O2: 	jal	{{.*}}	ignore64BitArgNoInline
135; MIPS32-O2: 	nop
136; MIPS32-O2: 	move	s1,v0
137; MIPS32-O2: 	sw	s7,{{.*}}(sp)
138; MIPS32-O2: 	sw	s6,{{.*}}(sp)
139; MIPS32-O2: 	move	a0,s4
140; MIPS32-O2: 	move	a1,s5
141; MIPS32-O2: 	li	a2,123
142; MIPS32-O2: 	jal	{{.*}}	ignore64BitArgNoInline
143; MIPS32-O2: 	nop
144
145
146declare i32 @ignore64BitArgNoInline(i64, i32, i64)
147
148define internal i32 @pass64BitConstArg(i64 %a, i64 %b) {
149entry:
150  %call = call i32 @ignore64BitArgNoInline(i64 %b, i32 123, i64 -2401053092306725256)
151  ret i32 %call
152}
153; CHECK-LABEL: pass64BitConstArg
154; CHECK:      sub     esp
155; CHECK:      mov     DWORD PTR [esp+0x4]
156; CHECK-NEXT: mov     DWORD PTR [esp]
157; CHECK-NEXT: mov     DWORD PTR [esp+0x8],0x7b
158; Bundle padding might be added (so not using -NEXT).
159; CHECK:      mov     DWORD PTR [esp+0x10],0xdeadbeef
160; CHECK-NEXT: mov     DWORD PTR [esp+0xc],0x12345678
161; Bundle padding will push the call down.
162; CHECK-NOT:  mov
163; CHECK:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
164;
165; OPTM1-LABEL: pass64BitConstArg
166; OPTM1:      sub     esp
167; OPTM1:      mov     DWORD PTR [esp+0x4]
168; OPTM1:      mov     DWORD PTR [esp]
169; OPTM1-NEXT: mov     DWORD PTR [esp+0x8],0x7b
170; Bundle padding might be added (so not using -NEXT).
171; OPTM1:      mov     DWORD PTR [esp+0x10],0xdeadbeef
172; OPTM1-NEXT: mov     DWORD PTR [esp+0xc],0x12345678
173; OPTM1-NOT:  mov
174; OPTM1:      call {{.*}} R_{{.*}}    ignore64BitArgNoInline
175
176; ARM32-LABEL: pass64BitConstArg
177; ARM32:      movw    [[REG1:r.*]], {{.*}} ; 0xbeef
178; ARM32:      movt    [[REG1]], {{.*}}     ; 0xdead
179; ARM32:      movw    [[REG2:r.*]], {{.*}} ; 0x5678
180; ARM32:      movt    [[REG2]], {{.*}}     ; 0x1234
181; ARM32:      str     [[REG1]], [sp, #4]
182; ARM32:      str     [[REG2]], [sp]
183; ARM32:      {{mov|ldr}} r0
184; ARM32:      {{mov|ldr}} r1
185; ARM32:      mov     r2, #123
186; ARM32:      bl      {{.*}} ignore64BitArgNoInline
187
188; MIPS32-LABEL: pass64BitConstArg
189; MIPS32-O2: 	lui	[[REG:.*]],0xdead
190; MIPS32-O2: 	ori	[[REG1:.*]],[[REG]],0xbeef
191; MIPS32-O2: 	lui	[[REG:.*]],0x1234
192; MIPS32-O2: 	ori	[[REG2:.*]],[[REG]],0x5678
193; MIPS32-O2: 	sw	[[REG1]],{{.*}}(sp)
194; MIPS32-O2: 	sw	[[REG2]],{{.*}}(sp)
195; MIPS32-O2: 	move	a0,a2
196; MIPS32-O2: 	move	a1,a3
197; MIPS32-O2: 	li	a2,123
198; MIPS32-O2: 	jal	{{.*}}	ignore64BitArgNoInline
199
200define internal i32 @pass64BitUndefArg() {
201entry:
202  %call = call i32 @ignore64BitArgNoInline(i64 0, i32 123, i64 undef)
203  ret i32 %call
204}
205; CHECK-LABEL: pass64BitUndefArg
206; CHECK: sub esp
207; CHECK: mov DWORD PTR{{.*}},0x7b
208; CHECK: mov DWORD PTR{{.*}},0x0
209; CHECK: call {{.*}} R_{{.*}} ignore64BitArgNoInline
210; OPTM1-LABEL: pass64BitUndefArg
211; OPTM1: sub esp
212; OPTM1: mov DWORD PTR{{.*}},0x7b
213; OPTM1: mov DWORD PTR{{.*}},0x0
214; OPTM1: call {{.*}} R_{{.*}} ignore64BitArgNoInline
215; ARM32-LABEL: pass64BitUndefArg
216; ARM32: sub sp
217; ARM32: mov {{.*}}, #0
218; ARM32: str
219; ARM32: mov {{.*}}, #123
220; ARM32: bl {{.*}} ignore64BitArgNoInline
221
222; MIPS32-LABEL: pass64BitUndefArg
223; MIPS32: jr  ra
224
225define internal i64 @return64BitArg(i64 %padding, i64 %a) {
226entry:
227  ret i64 %a
228}
229; CHECK-LABEL: return64BitArg
230; CHECK: mov     {{.*}},DWORD PTR [esp+0xc]
231; CHECK: mov     {{.*}},DWORD PTR [esp+0x10]
232;
233; OPTM1-LABEL: return64BitArg
234; OPTM1: mov     {{.*}},DWORD PTR [esp+0xc]
235; OPTM1: mov     {{.*}},DWORD PTR [esp+0x10]
236
237; ARM32-LABEL: return64BitArg
238; ARM32: mov {{.*}}, r2
239; ARM32: mov {{.*}}, r3
240; ARM32: bx lr
241
242; MIPS32-LABEL; return64BitArg
243; MIPS32-O2: move v0,a2
244; MIPS32-O2: move v1,a3
245; MIPS32-OM1: move [[T1:.*]],a2
246; MIPS32-OM1: sw [[T1]],[[MEM1:.*]]
247; MIPS32-OM1: move [[T2:.*]],a3
248; MIPS32-OM1: sw [[T2]],[[MEM2:.*]]
249; MIPS32-OM1: lw v0,[[MEM1]]
250; MIPS32-OM1: lw v1,[[MEM2]]
251; MIPS32: jr ra
252
253define internal i64 @return64BitConst() {
254entry:
255  ret i64 -2401053092306725256
256}
257; CHECK-LABEL: return64BitConst
258; CHECK: mov     eax,0x12345678
259; CHECK: mov     edx,0xdeadbeef
260;
261; OPTM1-LABEL: return64BitConst
262; OPTM1: mov     eax,0x12345678
263; OPTM1: mov     edx,0xdeadbeef
264
265; ARM32-LABEL: return64BitConst
266; ARM32: movw r0, #22136 ; 0x5678
267; ARM32: movt r0, #4660  ; 0x1234
268; ARM32: movw r1, #48879 ; 0xbeef
269; ARM32: movt r1, #57005 ; 0xdead
270
271; MIPS32-LABEL: return64BitConst
272; MIPS32: lui v0,0x1234
273; MIPS32: ori v0,v0,0x5678
274; MIPS32: lui v1,0xdead
275; MIPS32: ori v1,v1,0xbeef
276; MIPS32: jr ra
277
278define internal i64 @add64BitSigned(i64 %a, i64 %b) {
279entry:
280  %add = add i64 %b, %a
281  ret i64 %add
282}
283; CHECK-LABEL: add64BitSigned
284; CHECK: add
285; CHECK: adc
286;
287; OPTM1-LABEL: add64BitSigned
288; OPTM1: add
289; OPTM1: adc
290
291; ARM32-LABEL: add64BitSigned
292; ARM32: adds
293; ARM32: adc
294
295; MIPS32-LABEL: add64BitSigned
296; MIPS32: addu
297; MIPS32: sltu
298; MIPS32: addu
299; MIPS32: addu
300
301define internal i64 @add64BitUnsigned(i64 %a, i64 %b) {
302entry:
303  %add = add i64 %b, %a
304  ret i64 %add
305}
306; CHECK-LABEL: add64BitUnsigned
307; CHECK: add
308; CHECK: adc
309;
310; OPTM1-LABEL: add64BitUnsigned
311; OPTM1: add
312; OPTM1: adc
313
314; ARM32-LABEL: add64BitUnsigned
315; ARM32: adds
316; ARM32: adc
317
318; MIPS32-LABEL: add64BitUnsigned
319; MIPS32: addu
320; MIPS32: sltu
321; MIPS32: addu
322; MIPS32: addu
323
324define internal i64 @sub64BitSigned(i64 %a, i64 %b) {
325entry:
326  %sub = sub i64 %a, %b
327  ret i64 %sub
328}
329; CHECK-LABEL: sub64BitSigned
330; CHECK: sub
331; CHECK: sbb
332;
333; OPTM1-LABEL: sub64BitSigned
334; OPTM1: sub
335; OPTM1: sbb
336
337; ARM32-LABEL: sub64BitSigned
338; ARM32: subs
339; ARM32: sbc
340
341; MIPS32-LABEL: sub64BitSigned
342; MIPS32: subu
343; MIPS32: sltu
344; MIPS32: addu
345; MIPS32: subu
346
347define internal i64 @sub64BitUnsigned(i64 %a, i64 %b) {
348entry:
349  %sub = sub i64 %a, %b
350  ret i64 %sub
351}
352; CHECK-LABEL: sub64BitUnsigned
353; CHECK: sub
354; CHECK: sbb
355;
356; OPTM1-LABEL: sub64BitUnsigned
357; OPTM1: sub
358; OPTM1: sbb
359
360; ARM32-LABEL: sub64BitUnsigned
361; ARM32: subs
362; ARM32: sbc
363
364; MIPS32-LABEL: sub64BitUnsigned
365; MIPS32: subu
366; MIPS32: sltu
367; MIPS32: addu
368; MIPS32: subu
369
370define internal i64 @mul64BitSigned(i64 %a, i64 %b) {
371entry:
372  %mul = mul i64 %b, %a
373  ret i64 %mul
374}
375; CHECK-LABEL: mul64BitSigned
376; CHECK: imul
377; CHECK: mul
378; CHECK: add
379; CHECK: imul
380; CHECK: add
381;
382; OPTM1-LABEL: mul64BitSigned
383; OPTM1: imul
384; OPTM1: mul
385; OPTM1: add
386; OPTM1: imul
387; OPTM1: add
388
389; ARM32-LABEL: mul64BitSigned
390; ARM32: mul
391; ARM32: mla
392; ARM32: umull
393; ARM32: add
394
395; MIPS32-LABEL: mul64BitSigned
396; MIPS32: multu
397; MIPS32: mflo
398; MIPS32: mfhi
399; MIPS32: mul
400; MIPS32: mul
401; MIPS32: addu
402; MIPS32: addu
403
404define internal i64 @mul64BitUnsigned(i64 %a, i64 %b) {
405entry:
406  %mul = mul i64 %b, %a
407  ret i64 %mul
408}
409; CHECK-LABEL: mul64BitUnsigned
410; CHECK: imul
411; CHECK: mul
412; CHECK: add
413; CHECK: imul
414; CHECK: add
415;
416; OPTM1-LABEL: mul64BitUnsigned
417; OPTM1: imul
418; OPTM1: mul
419; OPTM1: add
420; OPTM1: imul
421; OPTM1: add
422
423; ARM32-LABEL: mul64BitUnsigned
424; ARM32: mul
425; ARM32: mla
426; ARM32: umull
427; ARM32: add
428
429; MIPS32-LABEL: mul64BitUnsigned
430; MIPS32: multu
431; MIPS32: mflo
432; MIPS32: mfhi
433; MIPS32: mul
434; MIPS32: mul
435; MIPS32: addu
436; MIPS32: addu
437
438define internal i64 @div64BitSigned(i64 %a, i64 %b) {
439entry:
440  %div = sdiv i64 %a, %b
441  ret i64 %div
442}
443; CHECK-LABEL: div64BitSigned
444; CHECK: call {{.*}} R_{{.*}}    __divdi3
445
446; OPTM1-LABEL: div64BitSigned
447; OPTM1: call {{.*}} R_{{.*}}    __divdi3
448;
449; ARM32-LABEL: div64BitSigned
450; ARM32: orrs {{r.*}}, {{r.*}}
451; ARM32: bne
452; ARM32: bl {{.*}} __divdi3
453
454; MIPS32-LABEL: div64BitSigned
455; MIPS32: jal {{.*}} __divdi3
456
457define internal i64 @div64BitSignedConst(i64 %a) {
458entry:
459  %div = sdiv i64 %a, 12345678901234
460  ret i64 %div
461}
462; CHECK-LABEL: div64BitSignedConst
463; CHECK: mov     DWORD PTR [esp+0xc],0xb3a
464; CHECK: mov     DWORD PTR [esp+0x8],0x73ce2ff2
465; CHECK: call {{.*}} R_{{.*}}    __divdi3
466;
467; OPTM1-LABEL: div64BitSignedConst
468; OPTM1: mov     DWORD PTR [esp+0xc],0xb3a
469; OPTM1: mov     DWORD PTR [esp+0x8],0x73ce2ff2
470; OPTM1: call {{.*}} R_{{.*}}    __divdi3
471;
472; ARM32-LABEL: div64BitSignedConst
473; For a constant, we should be able to optimize-out the divide by zero check.
474; ARM32-NOT: orrs
475; ARM32: movw {{.*}} ; 0x2ff2
476; ARM32: movt {{.*}} ; 0x73ce
477; ARM32: movw {{.*}} ; 0xb3a
478; ARM32: bl {{.*}} __divdi3
479
480; MIPS32-LABEL: div64BitSignedConst
481; MIPS32: jal {{.*}} __divdi3
482
483define internal i64 @div64BitUnsigned(i64 %a, i64 %b) {
484entry:
485  %div = udiv i64 %a, %b
486  ret i64 %div
487}
488; CHECK-LABEL: div64BitUnsigned
489; CHECK: call {{.*}} R_{{.*}}    __udivdi3
490;
491; OPTM1-LABEL: div64BitUnsigned
492; OPTM1: call {{.*}} R_{{.*}}    __udivdi3
493;
494; ARM32-LABEL: div64BitUnsigned
495; ARM32: orrs {{r.*}}, {{r.*}}
496; ARM32: bne
497; ARM32: bl {{.*}} __udivdi3
498
499; MIPS32-LABEL: div64BitUnsigned
500; MIPS32: jal {{.*}} __udivdi3
501
502define internal i64 @rem64BitSigned(i64 %a, i64 %b) {
503entry:
504  %rem = srem i64 %a, %b
505  ret i64 %rem
506}
507; CHECK-LABEL: rem64BitSigned
508; CHECK: call {{.*}} R_{{.*}}    __moddi3
509;
510; OPTM1-LABEL: rem64BitSigned
511; OPTM1: call {{.*}} R_{{.*}}    __moddi3
512;
513; ARM32-LABEL: rem64BitSigned
514; ARM32: orrs {{r.*}}, {{r.*}}
515; ARM32: bne
516; ARM32: bl {{.*}} __moddi3
517
518; MIPS32-LABEL: rem64BitSigned
519; MIPS32: jal {{.*}} __moddi3
520
521define internal i64 @rem64BitUnsigned(i64 %a, i64 %b) {
522entry:
523  %rem = urem i64 %a, %b
524  ret i64 %rem
525}
526; CHECK-LABEL: rem64BitUnsigned
527; CHECK: call {{.*}} R_{{.*}}    __umoddi3
528;
529; OPTM1-LABEL: rem64BitUnsigned
530; OPTM1: call {{.*}} R_{{.*}}    __umoddi3
531;
532; ARM32-LABEL: rem64BitUnsigned
533; ARM32: orrs {{r.*}}, {{r.*}}
534; ARM32: bne
535; ARM32: bl {{.*}} __umoddi3
536
537; MIPS32-LABEL: rem64BitUnsigned
538; MIPS32: jal {{.*}} __umoddi3
539
540define internal i64 @shl64BitSigned(i64 %a, i64 %b) {
541entry:
542  %shl = shl i64 %a, %b
543  ret i64 %shl
544}
545; CHECK-LABEL: shl64BitSigned
546; CHECK: shld
547; CHECK: shl e
548; CHECK: test {{.*}},0x20
549; CHECK: je
550;
551; OPTM1-LABEL: shl64BitSigned
552; OPTM1: shld
553; OPTM1: shl e
554; OPTM1: test {{.*}},0x20
555; OPTM1: je
556
557; ARM32-LABEL: shl64BitSigned
558; ARM32: rsb     [[T0:r[0-9]+]], r2, #32
559; ARM32: lsr     [[T1:r[0-9]+]], r0, [[T0]]
560; ARM32: orr     [[T2:r[0-9]+]], [[T1]], r1, lsl r2
561; ARM32: sub     [[T3:r[0-9]+]], r2, #32
562; ARM32: cmp     [[T3]], #0
563; ARM32: lslge   [[T2]], r0, [[T3]]
564; ARM32: lsl     r{{[0-9]+}}, r0, r2
565
566; MIPS32-LABEL: shl64BitSigned
567; MIPS32: sllv	[[T1:.*]],[[A_HI:.*]],[[B_LO:.*]]
568; MIPS32: nor	[[T2:.*]],[[B_LO]],zero
569; MIPS32: srl	[[T3:.*]],[[A_LO:.*]],0x1
570; MIPS32: srlv	[[T4:.*]],[[T3]],[[T2]]
571; MIPS32: or	[[T_HI:.*]],[[T1]],[[T4]]
572; MIPS32: sllv	[[T_LO:.*]],[[A_LO]],[[B_LO]]
573; MIPS32: move	[[T1_LO:.*]],[[T_LO]]
574; MIPS32: andi	[[T5:.*]],[[B_LO]],0x20
575; MIPS32: movn	[[T_HI]],[[T_LO]],[[T5]]
576; MIPS32: movn	[[T1_LO]],zero,[[T5]]
577; MIPS32-O2: move	v1,[[T_HI]]
578; MIPS32-OM1: sw	[[T_HI]],[[MEM:.*]]
579; MIPS32-OM1: lw        v1,[[MEM]]
580
581define internal i32 @shl64BitSignedTrunc(i64 %a, i64 %b) {
582entry:
583  %shl = shl i64 %a, %b
584  %result = trunc i64 %shl to i32
585  ret i32 %result
586}
587; CHECK-LABEL: shl64BitSignedTrunc
588; CHECK: mov
589; CHECK: shl e
590; CHECK: test {{.*}},0x20
591; CHECK: je
592;
593; OPTM1-LABEL: shl64BitSignedTrunc
594; OPTM1: shld
595; OPTM1: shl e
596; OPTM1: test {{.*}},0x20
597; OPTM1: je
598
599; ARM32-LABEL: shl64BitSignedTrunc
600; ARM32: lsl r
601
602; MIPS32-LABEL: shl64BitSignedTrunc
603; MIPS32-O2: 	sllv
604; MIPS32-O2: 	andi	{{.*}},0x20
605; MIPS32-O2: 	movn
606
607define internal i64 @shl64BitUnsigned(i64 %a, i64 %b) {
608entry:
609  %shl = shl i64 %a, %b
610  ret i64 %shl
611}
612; CHECK-LABEL: shl64BitUnsigned
613; CHECK: shld
614; CHECK: shl e
615; CHECK: test {{.*}},0x20
616; CHECK: je
617;
618; OPTM1-LABEL: shl64BitUnsigned
619; OPTM1: shld
620; OPTM1: shl e
621; OPTM1: test {{.*}},0x20
622; OPTM1: je
623
624; ARM32-LABEL: shl64BitUnsigned
625; ARM32: rsb
626; ARM32: lsr
627; ARM32: orr
628; ARM32: sub
629; ARM32: cmp
630; ARM32: lslge
631; ARM32: lsl
632
633; MIPS32-LABEL: shl64BitUnsigned
634; MIPS32: sllv  [[T1:.*]],[[A_HI:.*]],[[B_LO:.*]]
635; MIPS32: nor   [[T2:.*]],[[B_LO]],zero
636; MIPS32: srl   [[T3:.*]],[[A_LO:.*]],0x1
637; MIPS32: srlv  [[T4:.*]],[[T3]],[[T2]]
638; MIPS32: or    [[T_HI:.*]],[[T1]],[[T4]]
639; MIPS32: sllv  [[T_LO:.*]],[[A_LO]],[[B_LO]]
640; MIPS32: move  [[T1_LO:.*]],[[T_LO]]
641; MIPS32: andi  [[T5:.*]],[[B_LO]],0x20
642; MIPS32: movn  [[T_HI]],[[T_LO]],[[T5]]
643; MIPS32: movn  [[T1_LO]],zero,[[T5]]
644; MIPS32-O2: move       v1,[[T_HI]]
645; MIPS32-OM1: sw        [[T_HI]],[[MEM:.*]]
646; MIPS32-OM1: lw        v1,[[MEM]]
647
648define internal i64 @shr64BitSigned(i64 %a, i64 %b) {
649entry:
650  %shr = ashr i64 %a, %b
651  ret i64 %shr
652}
653; CHECK-LABEL: shr64BitSigned
654; CHECK: shrd
655; CHECK: sar
656; CHECK: test {{.*}},0x20
657; CHECK: je
658; CHECK: sar {{.*}},0x1f
659;
660; OPTM1-LABEL: shr64BitSigned
661; OPTM1: shrd
662; OPTM1: sar
663; OPTM1: test {{.*}},0x20
664; OPTM1: je
665; OPTM1: sar {{.*}},0x1f
666
667; ARM32-LABEL: shr64BitSigned
668; ARM32: lsr     [[T0:r[0-9]+]], r{{[0-9]+}}, r{{[0-9]+}}
669; ARM32: rsb     [[T1:r[0-9]+]], r{{[0-9]+}}, #32
670; ARM32: orr     r{{[0-9]+}}, [[T0]], r{{[0-9]+}}, lsl [[T1]]
671; ARM32: sub     [[T2:r[0-9]+]], r{{[0-9]+}}, #32
672; ARM32: cmp     [[T2]], #0
673; ARM32: asrge   r{{[0-9]+}}, r{{[0-9]+}}, [[T2]]
674; ARM32: asr     r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}
675
676; MIPS32-LABEL: shr64BitSigned
677; MIPS32: srlv	[[T1:.*]],[[A_LO:.*]],[[B_LO:.*]]
678; MIPS32: nor	[[T2:.*]],[[B_LO]],zero
679; MIPS32: sll	[[T3:.*]],[[A_HI:.*]],0x1
680; MIPS32: sllv	[[T4:.*]],[[T3]],[[T2]]
681; MIPS32: or	[[T_LO:.*]],[[T1]],[[T4]]
682; MIPS32: srav	[[T_HI:.*]],[[A_HI]],[[B_LO]]
683; MIPS32: move	[[T_HI1:.*]],[[T_HI]]
684; MIPS32: andi	[[T5:.*]],[[B_LO]],0x20
685; MIPS32: movn	[[T_LO1:.*]],[[T_HI]],[[T5]]
686; MIPS32: sra	[[T6:.*]],[[A_HI]],0x1f
687; MIPS32: movn	[[T_HI1]],[[T6]],[[T5]]
688
689define internal i32 @shr64BitSignedTrunc(i64 %a, i64 %b) {
690entry:
691  %shr = ashr i64 %a, %b
692  %result = trunc i64 %shr to i32
693  ret i32 %result
694}
695; CHECK-LABEL: shr64BitSignedTrunc
696; CHECK: shrd
697; CHECK: sar
698; CHECK: test {{.*}},0x20
699; CHECK: je
700;
701; OPTM1-LABEL: shr64BitSignedTrunc
702; OPTM1: shrd
703; OPTM1: sar
704; OPTM1: test {{.*}},0x20
705; OPTM1: je
706; OPTM1: sar {{.*}},0x1f
707
708; ARM32-LABEL: shr64BitSignedTrunc
709; ARM32: lsr
710; ARM32: rsb
711; ARM32: orr
712; ARM32: sub
713; ARM32: cmp
714; ARM32: asrge
715
716; MIPS32-LABEL: shr64BitSignedTrunc
717; MIPS32-O2: 	srlv
718; MIPS32-O2: 	nor
719; MIPS32-O2: 	sll
720; MIPS32-O2: 	sllv
721; MIPS32-O2: 	or
722; MIPS32-O2: 	srav
723; MIPS32-O2: 	andi	{{.*}},0x20
724; MIPS32-O2: 	movn
725
726define internal i64 @shr64BitUnsigned(i64 %a, i64 %b) {
727entry:
728  %shr = lshr i64 %a, %b
729  ret i64 %shr
730}
731; CHECK-LABEL: shr64BitUnsigned
732; CHECK: shrd
733; CHECK: shr
734; CHECK: test {{.*}},0x20
735; CHECK: je
736;
737; OPTM1-LABEL: shr64BitUnsigned
738; OPTM1: shrd
739; OPTM1: shr
740; OPTM1: test {{.*}},0x20
741; OPTM1: je
742
743; ARM32-LABEL: shr64BitUnsigned
744; ARM32: lsr
745; ARM32: rsb
746; ARM32: orr
747; ARM32: sub
748; ARM32: cmp
749; ARM32: lsrge
750; ARM32: lsr
751
752; MIPS32-LABEL: shr64BitUnsigned
753; MIPS32: srlv  [[T1:.*]],[[A_LO:.*]],[[B_LO:.*]]
754; MIPS32: nor   [[T2:.*]],[[B_LO]],zero
755; MIPS32: sll   [[T3:.*]],[[A_HI:.*]],0x1
756; MIPS32: sllv  [[T4:.*]],[[T3]],[[T2]]
757; MIPS32: or    [[T_LO:.*]],[[T1]],[[T4]]
758; MIPS32: srlv  [[T_HI:.*]],[[A_HI]],[[B_LO]]
759; MIPS32: move  [[T_HI1:.*]],[[T_HI]]
760; MIPS32: andi  [[T5:.*]],[[B_LO]],0x20
761; MIPS32: movn  [[T_LO1:.*]],[[T_HI]],[[T5]]
762; MIPS32: movn  [[T_HI1]],zero,[[T5]]
763
764define internal i32 @shr64BitUnsignedTrunc(i64 %a, i64 %b) {
765entry:
766  %shr = lshr i64 %a, %b
767  %result = trunc i64 %shr to i32
768  ret i32 %result
769}
770; CHECK-LABEL: shr64BitUnsignedTrunc
771; CHECK: shrd
772; CHECK: shr
773; CHECK: test {{.*}},0x20
774; CHECK: je
775;
776; OPTM1-LABEL: shr64BitUnsignedTrunc
777; OPTM1: shrd
778; OPTM1: shr
779; OPTM1: test {{.*}},0x20
780; OPTM1: je
781
782; ARM32-LABEL: shr64BitUnsignedTrunc
783; ARM32: lsr
784; ARM32: rsb
785; ARM32: orr
786; ARM32: sub
787; ARM32: cmp
788; ARM32: lsrge
789
790; MIPS32-LABEL: shr64BitUnsignedTrunc
791; MIPS32-O2: 	srlv
792; MIPS32-O2: 	nor
793; MIPS32-O2: 	sll
794; MIPS32-O2: 	sllv
795; MIPS32-O2: 	or
796; MIPS32-O2: 	srlv
797; MIPS32-O2: 	andi
798; MIPS32-O2: 	movn
799
800define internal i64 @and64BitSigned(i64 %a, i64 %b) {
801entry:
802  %and = and i64 %b, %a
803  ret i64 %and
804}
805; CHECK-LABEL: and64BitSigned
806; CHECK: and
807; CHECK: and
808;
809; OPTM1-LABEL: and64BitSigned
810; OPTM1: and
811; OPTM1: and
812
813; ARM32-LABEL: and64BitSigned
814; ARM32: and
815; ARM32: and
816
817; MIPS32-LABEL: and64BitSigned
818; MIPS32: and
819; MIPS32: and
820
821define internal i64 @and64BitUnsigned(i64 %a, i64 %b) {
822entry:
823  %and = and i64 %b, %a
824  ret i64 %and
825}
826; CHECK-LABEL: and64BitUnsigned
827; CHECK: and
828; CHECK: and
829;
830; OPTM1-LABEL: and64BitUnsigned
831; OPTM1: and
832; OPTM1: and
833
834; ARM32-LABEL: and64BitUnsigned
835; ARM32: and
836; ARM32: and
837
838; MIPS32-LABEL: and64BitUnsigned
839; MIPS32: and
840; MIPS32: and
841
842define internal i64 @or64BitSigned(i64 %a, i64 %b) {
843entry:
844  %or = or i64 %b, %a
845  ret i64 %or
846}
847; CHECK-LABEL: or64BitSigned
848; CHECK: or
849; CHECK: or
850;
851; OPTM1-LABEL: or64BitSigned
852; OPTM1: or
853; OPTM1: or
854
855; ARM32-LABEL: or64BitSigned
856; ARM32: orr
857; ARM32: orr
858
859; MIPS32-LABEL: or64BitSigned
860; MIPS32: or
861; MIPS32: or
862
863define internal i64 @or64BitUnsigned(i64 %a, i64 %b) {
864entry:
865  %or = or i64 %b, %a
866  ret i64 %or
867}
868; CHECK-LABEL: or64BitUnsigned
869; CHECK: or
870; CHECK: or
871;
872; OPTM1-LABEL: or64BitUnsigned
873; OPTM1: or
874; OPTM1: or
875
876; ARM32-LABEL: or64BitUnsigned
877; ARM32: orr
878; ARM32: orr
879
880; MIPS32-LABEL: or64BitUnsigned
881; MIPS32: or
882; MIPS32: or
883
884define internal i64 @xor64BitSigned(i64 %a, i64 %b) {
885entry:
886  %xor = xor i64 %b, %a
887  ret i64 %xor
888}
889; CHECK-LABEL: xor64BitSigned
890; CHECK: xor
891; CHECK: xor
892;
893; OPTM1-LABEL: xor64BitSigned
894; OPTM1: xor
895; OPTM1: xor
896
897; ARM32-LABEL: xor64BitSigned
898; ARM32: eor
899; ARM32: eor
900
901; MIPS32-LABEL: xor64BitSigned
902; MIPS32: xor
903; MIPS32: xor
904
905define internal i64 @xor64BitUnsigned(i64 %a, i64 %b) {
906entry:
907  %xor = xor i64 %b, %a
908  ret i64 %xor
909}
910; CHECK-LABEL: xor64BitUnsigned
911; CHECK: xor
912; CHECK: xor
913;
914; OPTM1-LABEL: xor64BitUnsigned
915; OPTM1: xor
916; OPTM1: xor
917
918; ARM32-LABEL: xor64BitUnsigned
919; ARM32: eor
920; ARM32: eor
921
922; MIPS32-LABEL: xor64BitUnsigned
923; MIPS32: xor
924; MIPS32: xor
925
926define internal i32 @trunc64To32Signed(i64 %padding, i64 %a) {
927entry:
928  %conv = trunc i64 %a to i32
929  ret i32 %conv
930}
931; CHECK-LABEL: trunc64To32Signed
932; CHECK: mov     eax,DWORD PTR [esp+0xc]
933;
934; OPTM1-LABEL: trunc64To32Signed
935; OPTM1: mov     eax,DWORD PTR [esp+
936
937; ARM32-LABEL: trunc64To32Signed
938; ARM32: mov r0, r2
939
940; MIPS32-LABEL: trunc64To32Signed
941; MIPS32: move v0,a2
942
943define internal i32 @trunc64To16Signed(i64 %a) {
944entry:
945  %conv = trunc i64 %a to i16
946  %conv.ret_ext = sext i16 %conv to i32
947  ret i32 %conv.ret_ext
948}
949; CHECK-LABEL: trunc64To16Signed
950; CHECK:      mov     eax,DWORD PTR [esp+0x4]
951; CHECK-NEXT: movsx  eax,ax
952;
953; OPTM1-LABEL: trunc64To16Signed
954; OPTM1:      mov     ax,WORD PTR [esp+
955; OPTM1: movsx  eax,
956
957; ARM32-LABEL: trunc64To16Signed
958; ARM32: sxth r0, r0
959
960; MIPS32-LABEL: trunc64To16Signed
961; MIPS32-O2: sll [[T1:.*]],a0,0x10
962; MIPS32-O2: sra [[T2:.*]],[[T1]],0x10
963; MIPS32-O2: move v0,[[T2]]
964; MIPS32-OM1: sll [[T1:.*]],{{.*}},0x10
965; MIPS32-OM1: sra [[T2:.*]],[[T1]],0x10
966; MIPS32-OM1: sw [[T2]],[[MEM:.*]]
967; MIPS32-OM1: lw v0,[[MEM]]
968
969define internal i32 @trunc64To8Signed(i64 %a) {
970entry:
971  %conv = trunc i64 %a to i8
972  %conv.ret_ext = sext i8 %conv to i32
973  ret i32 %conv.ret_ext
974}
975; CHECK-LABEL: trunc64To8Signed
976; CHECK:      mov     eax,DWORD PTR [esp+0x4]
977; CHECK-NEXT: movsx  eax,al
978;
979; OPTM1-LABEL: trunc64To8Signed
980; OPTM1:      mov     eax,DWORD PTR [esp+
981; OPTM1: movsx  eax,
982
983; ARM32-LABEL: trunc64To8Signed
984; ARM32: sxtb r0, r0
985
986; MIPS32-LABEL: trunc64To8Signed
987; MIPS32-O2: sll [[T1:.*]],a0,0x18
988; MIPS32-O2: sra [[T2:.*]],[[T1]],0x18
989; MIPS32-O2: move v0,[[T2]]
990; MIPS32-OM1: sll [[T1:.*]],{{.*}},0x18
991; MIPS32-OM1: sra [[T2:.*]],[[T1]],0x18
992; MIPS32-OM1: sw [[T2]],[[MEM:.*]]
993; MIPS32-OM1: lw v0,[[MEM]]
994
995define internal i32 @trunc64To32SignedConst() {
996entry:
997  %conv = trunc i64 12345678901234 to i32
998  ret i32 %conv
999}
1000; CHECK-LABEL: trunc64To32SignedConst
1001; CHECK: mov eax,0x73ce2ff2
1002;
1003; OPTM1-LABEL: trunc64To32SignedConst
1004; OPTM1: mov eax,0x73ce2ff2
1005
1006; ARM32-LABEL: trunc64To32SignedConst
1007; ARM32: movw r0, #12274 ; 0x2ff2
1008; ARM32: movt r0, #29646 ; 0x73ce
1009
1010; MIPS32-LABEL: trunc64To32SignedConst
1011; MIPS32: lui v0,0x73ce
1012; MIPS32: ori v0,v0,0x2ff2
1013
1014define internal i32 @trunc64To16SignedConst() {
1015entry:
1016  %conv = trunc i64 12345678901234 to i16
1017  %conv.ret_ext = sext i16 %conv to i32
1018  ret i32 %conv.ret_ext
1019}
1020; CHECK-LABEL: trunc64To16SignedConst
1021; CHECK: mov eax,0x73ce2ff2
1022; CHECK: movsx eax,ax
1023;
1024; OPTM1-LABEL: trunc64To16SignedConst
1025; OPTM1: mov eax,0x73ce2ff2
1026; OPTM1: movsx eax,
1027
1028; ARM32-LABEL: trunc64To16SignedConst
1029; ARM32: movw r0, #12274 ; 0x2ff2
1030; ARM32: movt r0, #29646 ; 0x73ce
1031; ARM32: sxth r0, r0
1032
1033; MIPS32-LABEL: trunc64To16SignedConst
1034; MIPS32: lui v0,0x73ce
1035; MIPS32: ori v0,v0,0x2ff2
1036; MIPS32: sll v0,v0,0x10
1037; MIPS32: sra v0,v0,0x10
1038
1039define internal i32 @trunc64To32Unsigned(i64 %padding, i64 %a) {
1040entry:
1041  %conv = trunc i64 %a to i32
1042  ret i32 %conv
1043}
1044; CHECK-LABEL: trunc64To32Unsigned
1045; CHECK: mov     eax,DWORD PTR [esp+0xc]
1046;
1047; OPTM1-LABEL: trunc64To32Unsigned
1048; OPTM1: mov     eax,DWORD PTR [esp+
1049
1050; ARM32-LABEL: trunc64To32Unsigned
1051; ARM32: mov r0, r2
1052
1053; MIPS32-LABEL: trunc64To32Unsigned
1054; MIPS32: move v0,a2
1055
1056define internal i32 @trunc64To16Unsigned(i64 %a) {
1057entry:
1058  %conv = trunc i64 %a to i16
1059  %conv.ret_ext = zext i16 %conv to i32
1060  ret i32 %conv.ret_ext
1061}
1062; CHECK-LABEL: trunc64To16Unsigned
1063; CHECK:      mov     eax,DWORD PTR [esp+0x4]
1064; CHECK-NEXT: movzx  eax,ax
1065;
1066; OPTM1-LABEL: trunc64To16Unsigned
1067; OPTM1:      mov     ax,WORD PTR [esp+
1068; OPTM1: movzx  eax,
1069
1070; ARM32-LABEL: trunc64To16Unsigned
1071; ARM32: uxth
1072
1073; MIPS32-LABEL: trunc64To16Unsigned
1074; MIPS32-O2: andi [[T1:.*]],a0,0xffff
1075; MIPS32-O2: move v0,[[T1]]
1076; MIPS32-OM1: andi [[T1:.*]],{{.*}},0xffff
1077; MIPS32-OM1: sw [[T1]],[[MEM:.*]]
1078; MIPS32-OM1: lw v0,[[MEM]]
1079
1080define internal i32 @trunc64To8Unsigned(i64 %a) {
1081entry:
1082  %conv = trunc i64 %a to i8
1083  %conv.ret_ext = zext i8 %conv to i32
1084  ret i32 %conv.ret_ext
1085}
1086; CHECK-LABEL: trunc64To8Unsigned
1087; CHECK:      mov     eax,DWORD PTR [esp+0x4]
1088; CHECK-NEXT: movzx  eax,al
1089;
1090; OPTM1-LABEL: trunc64To8Unsigned
1091; OPTM1: mov    eax,DWORD PTR [esp+
1092; OPTM1: movzx  eax,
1093
1094; ARM32-LABEL: trunc64To8Unsigned
1095; ARM32: uxtb
1096
1097; MIPS32-LABEL: trunc64To8Unsigned
1098; MIPS32-O2: andi [[T1:.*]],a0,0xff
1099; MIPS32-O2: move v0,[[T1]]
1100; MIPS32-OM1: andi [[T1:.*]],{{.*}},0xff
1101; MIPS32-OM1: sw [[T1]],[[MEM:.*]]
1102; MIPS32-OM1: lw v0,[[MEM]]
1103
1104define internal i32 @trunc64To1(i64 %a) {
1105entry:
1106;  %tobool = icmp ne i64 %a, 0
1107  %tobool = trunc i64 %a to i1
1108  %tobool.ret_ext = zext i1 %tobool to i32
1109  ret i32 %tobool.ret_ext
1110}
1111; CHECK-LABEL: trunc64To1
1112; CHECK:      mov     eax,DWORD PTR [esp+0x4]
1113; CHECK:      and     al,0x1
1114; CHECK-NOT:  and     eax,0x1
1115;
1116; OPTM1-LABEL: trunc64To1
1117; OPTM1:      mov     eax,DWORD PTR [esp+
1118; OPTM1:      and     al,0x1
1119; OPTM1-NOT:  and     eax,0x1
1120
1121; ARM32-LABEL: trunc64To1
1122; ARM32-OM1: and r0, r0, #1
1123; ARM32-O2: and r0, r0, #1
1124
1125; MIPS32-LABEL: trunc64To1
1126; MIPS32-O2: andi [[T1:.*]],a0,0x1
1127; MIPS32-O2: move v0,[[T1]]
1128; MIPS32-OM1: andi [[T1:.*]],{{.*}},0x1
1129; MIPS32-OM1: sw [[T1]],[[MEM:.*]]
1130; MIPS32-OM1: lw v0,[[MEM]]
1131
1132define internal i64 @sext32To64(i32 %a) {
1133entry:
1134  %conv = sext i32 %a to i64
1135  ret i64 %conv
1136}
1137; CHECK-LABEL: sext32To64
1138; CHECK: mov
1139; CHECK: sar {{.*}},0x1f
1140;
1141; OPTM1-LABEL: sext32To64
1142; OPTM1: mov
1143; OPTM1: sar {{.*}},0x1f
1144
1145; ARM32-LABEL: sext32To64
1146; ARM32: asr {{.*}}, #31
1147
1148; MIPS32-LABEL: sext32To64
1149; MIPS32: sra [[T_HI:.*]],[[T_LO:.*]],0x1f
1150; MIPS32-O2: move v1,[[T_HI]]
1151; MIPS32-O2: move v0,[[T_LO]]
1152; MIPS32-OM1: sw [[T_HI]],[[MEM_HI:.*]]
1153; MIPS32-OM1: sw [[T_LO]],[[MEM_LO:.*]]
1154; MIPS32-OM1: lw v0,[[MEM_LO]]
1155; MIPS32-OM1: lw v1,[[MEM_HI]]
1156
1157define internal i64 @sext16To64(i32 %a) {
1158entry:
1159  %a.arg_trunc = trunc i32 %a to i16
1160  %conv = sext i16 %a.arg_trunc to i64
1161  ret i64 %conv
1162}
1163; CHECK-LABEL: sext16To64
1164; CHECK: movsx
1165; CHECK: sar {{.*}},0x1f
1166;
1167; OPTM1-LABEL: sext16To64
1168; OPTM1: movsx
1169; OPTM1: sar {{.*}},0x1f
1170
1171; ARM32-LABEL: sext16To64
1172; ARM32: sxth
1173; ARM32: asr {{.*}}, #31
1174
1175; MIPS32-LABEL: sext16To64
1176; MIPS32: sll [[T1_LO:.*]],{{.*}},0x10
1177; MIPS32: sra [[T2_LO:.*]],[[T1_LO]],0x10
1178; MIPS32: sra [[T_HI:.*]],[[T2_LO]],0x1f
1179; MIPS32-O2: move v1,[[T_HI]]
1180; MIPS32-O2: move v0,[[T2_LO]]
1181; MIPS32-OM1: sw [[T_HI]],[[MEM_HI:.*]]
1182; MIPS32-OM1: sw [[T2_LO]],[[MEM_LO:.*]]
1183; MIPS32-OM1: lw v0,[[MEM_LO]]
1184; MIPS32-OM1: lw v1,[[MEM_HI]]
1185
1186
1187define internal i64 @sext8To64(i32 %a) {
1188entry:
1189  %a.arg_trunc = trunc i32 %a to i8
1190  %conv = sext i8 %a.arg_trunc to i64
1191  ret i64 %conv
1192}
1193; CHECK-LABEL: sext8To64
1194; CHECK: movsx
1195; CHECK: sar {{.*}},0x1f
1196;
1197; OPTM1-LABEL: sext8To64
1198; OPTM1: movsx
1199; OPTM1: sar {{.*}},0x1f
1200
1201; ARM32-LABEL: sext8To64
1202; ARM32: sxtb
1203; ARM32: asr {{.*}}, #31
1204
1205; MIPS32-LABEL: sext8To64
1206; MIPS32: sll [[T1_LO:.*]],{{.*}},0x18
1207; MIPS32: sra [[T2_LO:.*]],[[T1_LO]],0x18
1208; MIPS32: sra [[T_HI:.*]],[[T2_LO]],0x1f
1209; MIPS32-O2: move v1,[[T_HI]]
1210; MIPS32-O2: move v0,[[T2_LO]]
1211; MIPS32-OM1: sw [[T_HI]],[[MEM_HI:.*]]
1212; MIPS32-OM1: sw [[T2_LO]],[[MEM_LO:.*]]
1213; MIPS32-OM1: lw v0,[[MEM_LO]]
1214; MIPS32-OM1: lw v1,[[MEM_HI]]
1215
1216define internal i64 @sext1To64(i32 %a) {
1217entry:
1218  %a.arg_trunc = trunc i32 %a to i1
1219  %conv = sext i1 %a.arg_trunc to i64
1220  ret i64 %conv
1221}
1222; CHECK-LABEL: sext1To64
1223; CHECK: mov
1224; CHECK: shl {{.*}},0x1f
1225; CHECK: sar {{.*}},0x1f
1226;
1227; OPTM1-LABEL: sext1To64
1228; OPTM1: mov
1229; OPTM1: shl {{.*}},0x1f
1230; OPTM1: sar {{.*}},0x1f
1231
1232; ARM32-LABEL: sext1To64
1233; ARM32: mov {{.*}}, #0
1234; ARM32: tst {{.*}}, #1
1235; ARM32: mvn {{.*}}, #0
1236; ARM32: movne
1237
1238; MIPS32-LABEL: sext1To64
1239; MIPS32: sll [[T1:.*]],{{.*}},0x1f
1240; MIPS32: sra [[T2:.*]],[[T1]],0x1f
1241; MIPS32-O2: move v1,[[T2]]
1242; MIPS32-O2: move v0,[[T2]]
1243; MIPS32-OM1: sw [[T2]],[[MEM_HI:.*]]
1244; MIPS32-OM1: sw [[T2]],[[MEM_LO:.*]]
1245; MIPS32-OM1: lw v0,[[MEM_LO]]
1246; MIPS32-OM1: lw v1,[[MEM_HI]]
1247
1248define internal i64 @zext32To64(i32 %a) {
1249entry:
1250  %conv = zext i32 %a to i64
1251  ret i64 %conv
1252}
1253; CHECK-LABEL: zext32To64
1254; CHECK: mov
1255; CHECK: mov {{.*}},0x0
1256;
1257; OPTM1-LABEL: zext32To64
1258; OPTM1: mov
1259; OPTM1: mov {{.*}},0x0
1260
1261; ARM32-LABEL: zext32To64
1262; ARM32: mov {{.*}}, #0
1263
1264; MIPS32-LABEL: zext32To64
1265; MIPS32: li [[T1:.*]],0
1266; MIPS32-O2: move v1,[[T1]]
1267; MIPS32-O2: move v0,a0
1268; MIPS32-OM1: sw [[T1]],[[MEM_HI:.*]]
1269; MIPS32-OM1: lw v1,[[MEM_HI]]
1270
1271define internal i64 @zext16To64(i32 %a) {
1272entry:
1273  %a.arg_trunc = trunc i32 %a to i16
1274  %conv = zext i16 %a.arg_trunc to i64
1275  ret i64 %conv
1276}
1277; CHECK-LABEL: zext16To64
1278; CHECK: movzx
1279; CHECK: mov {{.*}},0x0
1280;
1281; OPTM1-LABEL: zext16To64
1282; OPTM1: movzx
1283; OPTM1: mov {{.*}},0x0
1284
1285; ARM32-LABEL: zext16To64
1286; ARM32: uxth
1287; ARM32: mov {{.*}}, #0
1288
1289; MIPS32-LABEL: zext16To64
1290; MIPS32: andi [[T_LO:.*]],{{.*}},0xffff
1291; MIPS32: li [[T_HI:.*]],0
1292; MIPS32-O2: move v1,[[T_HI]]
1293; MIPS32-O2: move v0,[[T_LO]]
1294; MIPS32-OM1: sw [[T_HI]],[[MEM_HI:.*]]
1295; MIPS32-OM1: lw v1,[[MEM_HI]]
1296
1297define internal i64 @zext8To64(i32 %a) {
1298entry:
1299  %a.arg_trunc = trunc i32 %a to i8
1300  %conv = zext i8 %a.arg_trunc to i64
1301  ret i64 %conv
1302}
1303; CHECK-LABEL: zext8To64
1304; CHECK: movzx
1305; CHECK: mov {{.*}},0x0
1306;
1307; OPTM1-LABEL: zext8To64
1308; OPTM1: movzx
1309; OPTM1: mov {{.*}},0x0
1310
1311; ARM32-LABEL: zext8To64
1312; ARM32: uxtb
1313; ARM32: mov {{.*}}, #0
1314
1315; MIPS32-LABEL: zext8To64
1316; MIPS32: andi [[T_LO:.*]],{{.*}},0xff
1317; MIPS32: li [[T_HI:.*]],0
1318; MIPS32-O2: move v1,[[T_HI]]
1319; MIPS32-O2: move v0,[[T_LO]]
1320; MIPS32-OM1: sw [[T_HI]],[[MEM_HI:.*]]
1321; MIPS32-OM1: lw v1,[[MEM_HI]]
1322
1323define internal i64 @zext1To64(i32 %a) {
1324entry:
1325  %a.arg_trunc = trunc i32 %a to i1
1326  %conv = zext i1 %a.arg_trunc to i64
1327  ret i64 %conv
1328}
1329; CHECK-LABEL: zext1To64
1330; CHECK: and {{.*}},0x1
1331; CHECK: mov {{.*}},0x0
1332;
1333; OPTM1-LABEL: zext1To64
1334; OPTM1: and {{.*}},0x1
1335; OPTM1: mov {{.*}},0x0
1336
1337; ARM32-LABEL: zext1To64
1338; ARM32: and {{.*}}, #1
1339; ARM32: mov {{.*}}, #0
1340; ARM32: bx
1341
1342; MIPS32-LABEL: zext1To64
1343; MIPS32: andi [[T_LO:.*]],{{.*}},0x1
1344; MIPS32: li [[T_HI:.*]],0
1345; MIPS32-O2: move v1,[[T_HI]]
1346; MIPS32-O2: move v0,[[T_LO]]
1347; MIPS32-OM1: sw [[T_HI]],[[MEM_HI:.*]]
1348; MIPS32-OM1: lw v1,[[MEM_HI]]
1349
1350define internal void @icmpEq64(i64 %a, i64 %b, i64 %c, i64 %d) {
1351entry:
1352  %cmp = icmp eq i64 %a, %b
1353  br i1 %cmp, label %if.then, label %if.end
1354
1355if.then:                                          ; preds = %entry
1356  call void @func()
1357  br label %if.end
1358
1359if.end:                                           ; preds = %if.then, %entry
1360  %cmp1 = icmp eq i64 %c, %d
1361  br i1 %cmp1, label %if.then2, label %if.end3
1362
1363if.then2:                                         ; preds = %if.end
1364  call void @func()
1365  br label %if.end3
1366
1367if.end3:                                          ; preds = %if.then2, %if.end
1368  ret void
1369}
1370; CHECK-LABEL: icmpEq64
1371; CHECK: cmp {{.*}}
1372; CHECK-NEXT: jne {{.*}}
1373; CHECK-NEXT: cmp {{.*}}
1374; CHECK-NEXT: jne {{.*}}
1375; CHECK-NEXT: call {{.*}}
1376; CHECK: cmp {{.*}}
1377; CHECK-NEXT: jne {{.*}}
1378; CHECK-NEXT: cmp {{.*}}
1379; CHECK-NEXT: jne {{.*}}
1380; CHECK-NEXT: call {{.*}}
1381;
1382; OPTM1-LABEL: icmpEq64
1383; OPTM1: mov [[RESULT:.*]],0x1
1384; OPTM1-NEXT: cmp {{.*}}
1385; OPTM1-NEXT: jne {{.*}}
1386; OPTM1-NEXT: cmp {{.*}}
1387; OPTM1-NEXT: je {{.*}}
1388; OPTM1-NEXT: mov [[RESULT]],0x0
1389; OPTM1-NEXT: cmp [[RESULT]],0x0
1390; OPTM1-NEXT: jne
1391; OPTM1-NEXT: jmp
1392; OPTM1-NEXT: call
1393; OPTM1: mov [[RESULT:.*]],0x1
1394; OPTM1-NEXT: cmp {{.*}}
1395; OPTM1-NEXT: jne {{.*}}
1396; OPTM1-NEXT: cmp {{.*}}
1397; OPTM1-NEXT: je {{.*}}
1398; OPTM1-NEXT: mov [[RESULT]],0x0
1399; OPTM1-NEXT: cmp [[RESULT]],0x0
1400; OPTM1-NEXT: jne
1401; OPTM1-NEXT: jmp
1402; OPTM1-NEXT: call
1403
1404; ARM32-LABEL: icmpEq64
1405; ARM32: cmp
1406; ARM32: cmpeq
1407; ARM32-OM1: tst
1408; ARM32: bne
1409; ARM32: bl {{.*}} <func>
1410; ARM32: cmp
1411; ARM32: cmpeq
1412; ARM32-OM1: tst
1413; ARM32: bne
1414; ARM32: bl {{.*}} <func>
1415; ARM32: bx
1416
1417; MIPS32-LABEL: icmpEq64
1418; MIPS32: xor [[T1:.*]],{{.*}},{{.*}}
1419; MIPS32: xor [[T2:.*]],{{.*}},{{.*}}
1420; MIPS32: or [[T3:.*]],[[T1]],[[T2]]
1421; MIPS32-O2: bnez [[T3]],{{.*}}
1422; MIPS32-OM1: sltiu [[T4:.*]],[[T3]],1
1423; MIPS32-OM1: sw [[T4]],[[MEM:.*]]
1424; MIPS32-OM1: lb [[T5:.*]],[[MEM]]
1425; MIPS32-OM1: beqz [[T5]],{{.*}}
1426; MIPS32-OM1: b {{.*}}
1427; MIPS32: jal {{.*}}
1428; MIPS32-OM1: b {{.*}}
1429; MIPS32: xor [[T1:.*]],{{.*}},{{.*}}
1430; MIPS32: xor [[T2:.*]],{{.*}},{{.*}}
1431; MIPS32: or [[T3:.*]],[[T1]],[[T2]]
1432; MIPS32-O2: bnez [[T3]],{{.*}}
1433; MIPS32-OM1: sltiu [[T4:.*]],[[T3]],1
1434; MIPS32-OM1: sw [[T4]],[[MEM:.*]]
1435; MIPS32-OM1: lb [[T5:.*]],[[MEM]]
1436; MIPS32-OM1: beqz [[T5]],{{.*}}
1437; MIPS32-OM1: b {{.*}}
1438; MIPS32: jal {{.*}}
1439; MIPS32-OM1: b {{.*}}
1440
1441declare void @func()
1442
1443define internal void @icmpNe64(i64 %a, i64 %b, i64 %c, i64 %d) {
1444entry:
1445  %cmp = icmp ne i64 %a, %b
1446  br i1 %cmp, label %if.then, label %if.end
1447
1448if.then:                                          ; preds = %entry
1449  call void @func()
1450  br label %if.end
1451
1452if.end:                                           ; preds = %if.then, %entry
1453  %cmp1 = icmp ne i64 %c, %d
1454  br i1 %cmp1, label %if.then2, label %if.end3
1455
1456if.then2:                                         ; preds = %if.end
1457  call void @func()
1458  br label %if.end3
1459
1460if.end3:                                          ; preds = %if.end, %if.then2
1461  ret void
1462}
1463; CHECK-LABEL: icmpNe64
1464; CHECK: cmp {{.*}}
1465; CHECK-NEXT: jne {{.*}}
1466; CHECK-NEXT: cmp {{.*}}
1467; CHECK-NEXT: je {{.*}}
1468; CHECK-NEXT: call {{.*}}
1469; CHECK: cmp {{.*}}
1470; CHECK-NEXT: jne {{.*}}
1471; CHECK-NEXT: cmp {{.*}}
1472; CHECK-NEXT: je {{.*}}
1473; CHECK-NEXT: call {{.*}}
1474;
1475; OPTM1-LABEL: icmpNe64
1476; OPTM1: mov [[RESULT:.*]],0x1
1477; OPTM1-NEXT: cmp {{.*}}
1478; OPTM1-NEXT: jne {{.*}}
1479; OPTM1-NEXT: cmp {{.*}}
1480; OPTM1-NEXT: jne {{.*}}
1481; OPTM1-NEXT: mov [[RESULT:.*]],0x0
1482; OPTM1-NEXT: cmp [[RESULT]],0x0
1483; OPTM1-NEXT: jne {{.*}}
1484; OPTM1-NEXT: jmp {{.*}}
1485; OPTM1-NEXT: call
1486; OPTM1: mov [[RESULT:.*]],0x1
1487; OPTM1-NEXT: cmp {{.*}}
1488; OPTM1-NEXT: jne {{.*}}
1489; OPTM1-NEXT: cmp {{.*}}
1490; OPTM1-NEXT: jne {{.*}}
1491; OPTM1-NEXT: mov [[RESULT:.*]],0x0
1492; OPTM1-NEXT: cmp [[RESULT]],0x0
1493; OPTM1-NEXT: jne {{.*}}
1494; OPTM1-NEXT: jmp {{.*}}
1495; OPTM1-NEXT: call
1496
1497; ARM32-LABEL: icmpNe64
1498; ARM32: cmp
1499; ARM32: cmpeq
1500; ARM32-OM1: tst
1501; ARM32-OM1: bne
1502; ARM32-O2: beq
1503; ARM32: bl {{.*}} <func>
1504; ARM32: cmp
1505; ARM32: cmpeq
1506; ARM32-OM1: tst
1507; ARM32-OM1: bne
1508; ARM32-O2: beq
1509; ARM32: bl
1510
1511; MIPS32-LABEL: icmpNe64
1512; MIPS32: xor [[T1:.*]],{{.*}},{{.*}}
1513; MIPS32: xor [[T2:.*]],{{.*}},{{.*}}
1514; MIPS32: or [[T3:.*]],[[T1]],[[T2]]
1515; MIPS32-O2: beqz [[T3]],{{.*}}
1516; MIPS32-OM1: sltu [[T4:.*]],zero,[[T3]]
1517; MIPS32-OM1: sw [[T4]],[[MEM:.*]]
1518; MIPS32-OM1: lb [[T5:.*]],[[MEM]]
1519; MIPS32-OM1: beqz [[T5]],{{.*}}
1520; MIPS32-OM1: b {{.*}}
1521; MIPS32: jal {{.*}}
1522; MIPS32-OM1: b {{.*}}
1523; MIPS32: xor [[T1:.*]],{{.*}},{{.*}}
1524; MIPS32: xor [[T2:.*]],{{.*}},{{.*}}
1525; MIPS32: or [[T3:.*]],[[T1]],[[T2]]
1526; MIPS32-O2: beqz [[T3]],{{.*}}
1527; MIPS32-OM1: sltu [[T4:.*]],zero,[[T3]]
1528; MIPS32-OM1: sw [[T4]],[[MEM:.*]]
1529; MIPS32-OM1: lb [[T5:.*]],[[MEM]]
1530; MIPS32-OM1: beqz [[T5]],{{.*}}
1531; MIPS32-OM1: b {{.*}}
1532; MIPS32: jal {{.*}}
1533; MIPS32-OM1: b {{.*}}
1534
1535define internal void @icmpGt64(i64 %a, i64 %b, i64 %c, i64 %d) {
1536entry:
1537  %cmp = icmp ugt i64 %a, %b
1538  br i1 %cmp, label %if.then, label %if.end
1539
1540if.then:                                          ; preds = %entry
1541  call void @func()
1542  br label %if.end
1543
1544if.end:                                           ; preds = %if.then, %entry
1545  %cmp1 = icmp sgt i64 %c, %d
1546  br i1 %cmp1, label %if.then2, label %if.end3
1547
1548if.then2:                                         ; preds = %if.end
1549  call void @func()
1550  br label %if.end3
1551
1552if.end3:                                          ; preds = %if.then2, %if.end
1553  ret void
1554}
1555; CHECK-LABEL: icmpGt64
1556; CHECK: ja
1557; CHECK: jb
1558; CHECK: jbe
1559; CHECK: call
1560; CHECK: jg
1561; CHECK: jl
1562; CHECK: jbe
1563; CHECK: call
1564;
1565; OPTM1-LABEL: icmpGt64
1566; OPTM1: ja
1567; OPTM1: jb
1568; OPTM1: ja
1569; OPTM1: call
1570; OPTM1: jg
1571; OPTM1: jl
1572; OPTM1: ja
1573; OPTM1: call
1574
1575; ARM32-LABEL: icmpGt64
1576; ARM32: cmp
1577; ARM32: cmpeq
1578; ARM32-OM1: tst
1579; ARM32-OM1: bne
1580; ARM32-O2: bls
1581; ARM32: bl
1582; ARM32: cmp
1583; ARM32: sbcs
1584; ARM32-OM1: tst
1585; ARM32-OM1: bne
1586; ARM32-O2: bge
1587; ARM32: bl
1588
1589; MIPS32-LABEL: icmpGt64
1590; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1591; MIPS32-O2: sltu [[T2:.*]],[[B_HI]],[[A_HI]]
1592; MIPS32-O2: xori [[T3:.*]],[[T2]],0x1
1593; MIPS32-O2: sltu [[T4:.*]],{{.*}},{{.*}}
1594; MIPS32-O2: xori [[T5:.*]],[[T4]],0x1
1595; MIPS32-OM1: sltu [[T3:.*]],[[B_HI]],[[A_HI]]
1596; MIPS32-OM1: sltu [[T5:.*]],{{.*}},{{.*}}
1597; MIPS32: movz [[T3]],[[T5]],[[T1]]
1598; MIPS32-O2: bnez [[T3]],{{.*}}
1599; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1600; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1601; MIPS32-OM1: beqz [[T6]],{{.*}}
1602; MIPS32-OM1: b {{.*}}
1603; MIPS32: jal {{.*}}
1604; MIPS32-OM1: b {{.*}}
1605; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1606; MIPS32-O2: slt [[T2:.*]],[[B_HI]],[[A_HI]]
1607; MIPS32-O2: xori [[T3:.*]],[[T2]],0x1
1608; MIPS32-O2: sltu [[T4:.*]],{{.*}},{{.*}}
1609; MIPS32-O2: xori [[T5:.*]],[[T4]],0x1
1610; MIPS32-OM1: slt [[T3:.*]],[[B_HI]],[[A_HI]]
1611; MIPS32-OM1: sltu [[T5:.*]],{{.*}},{{.*}}
1612; MIPS32: movz [[T3]],[[T5]],[[T1]]
1613; MIPS32-O2: bnez [[T3]],{{.*}}
1614; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1615; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1616; MIPS32-OM1: beqz [[T6]],{{.*}}
1617; MIPS32-OM1: b {{.*}}
1618; MIPS32: jal {{.*}}
1619; MIPS32-OM1: b {{.*}}
1620
1621define internal void @icmpGe64(i64 %a, i64 %b, i64 %c, i64 %d) {
1622entry:
1623  %cmp = icmp uge i64 %a, %b
1624  br i1 %cmp, label %if.then, label %if.end
1625
1626if.then:                                          ; preds = %entry
1627  call void @func()
1628  br label %if.end
1629
1630if.end:                                           ; preds = %if.then, %entry
1631  %cmp1 = icmp sge i64 %c, %d
1632  br i1 %cmp1, label %if.then2, label %if.end3
1633
1634if.then2:                                         ; preds = %if.end
1635  call void @func()
1636  br label %if.end3
1637
1638if.end3:                                          ; preds = %if.end, %if.then2
1639  ret void
1640}
1641; CHECK-LABEL: icmpGe64
1642; CHECK: ja
1643; CHECK: jb
1644; CHECK: jb
1645; CHECK: call
1646; CHECK: jg
1647; CHECK: jl
1648; CHECK: jb
1649; CHECK: call
1650;
1651; OPTM1-LABEL: icmpGe64
1652; OPTM1: ja
1653; OPTM1: jb
1654; OPTM1: jae
1655; OPTM1: call
1656; OPTM1: jg
1657; OPTM1: jl
1658; OPTM1: jae
1659; OPTM1: call
1660
1661; ARM32-LABEL: icmpGe64
1662; ARM32: cmp
1663; ARM32: cmpeq
1664; ARM32-OM1: tst
1665; ARM32-OM1: bne
1666; ARM32-O2: bcc
1667; ARM32: bl
1668; ARM32: cmp
1669; ARM32: sbcs
1670; ARM32-OM1: tst
1671; ARM32-OM1: bne
1672; ARM32-O2: blt
1673; ARM32: bl
1674
1675; MIPS32-LABEL: icmpGe64
1676; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1677; MIPS32-OM1: sltu [[T2:.*]],[[A_HI]],[[B_HI]]
1678; MIPS32-OM1: xori [[T3:.*]],[[T2]],0x1
1679; MIPS32-OM1: sltu [[T4:.*]],{{.*}},{{.*}}
1680; MIPS32-OM1: xori [[T5:.*]],[[T4]],0x1
1681; MIPS32-O2: sltu [[T3:.*]],[[A_HI]],[[B_HI]]
1682; MIPS32-O2: sltu [[T5:.*]],{{.*}},{{.*}}
1683; MIPS32: movz [[T3]],[[T5]],[[T1]]
1684; MIPS32-O2: bnez [[T3]],{{.*}}
1685; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1686; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1687; MIPS32-OM1: beqz [[T6]],{{.*}}
1688; MIPS32-OM1: b {{.*}}
1689; MIPS32: jal {{.*}}
1690; MIPS32-OM1: b {{.*}}
1691; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1692; MIPS32-OM1: slt [[T2:.*]],[[A_HI]],[[B_HI]]
1693; MIPS32-OM1: xori [[T3:.*]],[[T2]],0x1
1694; MIPS32-OM1: sltu [[T4:.*]],{{.*}},{{.*}}
1695; MIPS32-OM1: xori [[T5:.*]],[[T4]],0x1
1696; MIPS32-O2: slt [[T3:.*]],[[A_HI]],[[B_HI]]
1697; MIPS32-O2: sltu [[T5:.*]],{{.*}},{{.*}}
1698; MIPS32: movz [[T3]],[[T5]],[[T1]]
1699; MIPS32-O2: bnez [[T3]],{{.*}}
1700; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1701; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1702; MIPS32-OM1: beqz [[T6]],{{.*}}
1703; MIPS32-OM1: b {{.*}}
1704; MIPS32: jal {{.*}}
1705; MIPS32-OM1: b {{.*}}
1706
1707define internal void @icmpLt64(i64 %a, i64 %b, i64 %c, i64 %d) {
1708entry:
1709  %cmp = icmp ult i64 %a, %b
1710  br i1 %cmp, label %if.then, label %if.end
1711
1712if.then:                                          ; preds = %entry
1713  call void @func()
1714  br label %if.end
1715
1716if.end:                                           ; preds = %if.then, %entry
1717  %cmp1 = icmp slt i64 %c, %d
1718  br i1 %cmp1, label %if.then2, label %if.end3
1719
1720if.then2:                                         ; preds = %if.end
1721  call void @func()
1722  br label %if.end3
1723
1724if.end3:                                          ; preds = %if.then2, %if.end
1725  ret void
1726}
1727; CHECK-LABEL: icmpLt64
1728; CHECK: jb
1729; CHECK: ja
1730; CHECK: jae
1731; CHECK: call
1732; CHECK: jl
1733; CHECK: jg
1734; CHECK: jae
1735; CHECK: call
1736;
1737; OPTM1-LABEL: icmpLt64
1738; OPTM1: jb
1739; OPTM1: ja
1740; OPTM1: jb
1741; OPTM1: call
1742; OPTM1: jl
1743; OPTM1: jg
1744; OPTM1: jb
1745; OPTM1: call
1746
1747; ARM32-LABEL: icmpLt64
1748; ARM32: cmp
1749; ARM32: cmpeq
1750; ARM32-OM1: tst
1751; ARM32-OM1: bne
1752; ARM32-O2: bcs
1753; ARM32: bl
1754; ARM32: cmp
1755; ARM32: sbcs
1756; ARM32-OM1: tst
1757; ARM32-OM1: bne
1758; ARM32-O2: bge
1759; ARM32: bl
1760
1761; MIPS32-LABEL: icmpLt64
1762; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1763; MIPS32-O2: sltu [[T2:.*]],[[A_HI]],[[B_HI]]
1764; MIPS32-O2: xori [[T3:.*]],[[T2]],0x1
1765; MIPS32-O2: sltu [[T4:.*]],{{.*}},{{.*}}
1766; MIPS32-O2: xori [[T5:.*]],[[T4]],0x1
1767; MIPS32-OM1: sltu [[T3:.*]],[[A_HI]],[[B_HI]]
1768; MIPS32-OM1: sltu [[T5:.*]],{{.*}},{{.*}}
1769; MIPS32: movz [[T3]],[[T5]],[[T1]]
1770; MIPS32-O2: bnez [[T3]],{{.*}}
1771; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1772; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1773; MIPS32-OM1: beqz [[T6]],{{.*}}
1774; MIPS32-OM1: b {{.*}}
1775; MIPS32: jal {{.*}}
1776; MIPS32-OM1: b {{.*}}
1777; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1778; MIPS32-O2: slt [[T2:.*]],[[A_HI]],[[B_HI]]
1779; MIPS32-O2: xori [[T3:.*]],[[T2]],0x1
1780; MIPS32-O2: sltu [[T4:.*]],{{.*}},{{.*}}
1781; MIPS32-O2: xori [[T5:.*]],[[T4]],0x1
1782; MIPS32-OM1: slt [[T3:.*]],[[A_HI]],[[B_HI]]
1783; MIPS32-OM1: sltu [[T5:.*]],{{.*}},{{.*}}
1784; MIPS32: movz [[T3]],[[T5]],[[T1]]
1785; MIPS32-O2: bnez [[T3]],{{.*}}
1786; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1787; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1788; MIPS32-OM1: beqz [[T6]],{{.*}}
1789; MIPS32-OM1: b {{.*}}
1790; MIPS32: jal {{.*}}
1791; MIPS32-OM1: b {{.*}}
1792
1793define internal void @icmpLe64(i64 %a, i64 %b, i64 %c, i64 %d) {
1794entry:
1795  %cmp = icmp ule i64 %a, %b
1796  br i1 %cmp, label %if.then, label %if.end
1797
1798if.then:                                          ; preds = %entry
1799  call void @func()
1800  br label %if.end
1801
1802if.end:                                           ; preds = %if.then, %entry
1803  %cmp1 = icmp sle i64 %c, %d
1804  br i1 %cmp1, label %if.then2, label %if.end3
1805
1806if.then2:                                         ; preds = %if.end
1807  call void @func()
1808  br label %if.end3
1809
1810if.end3:                                          ; preds = %if.end, %if.then2
1811  ret void
1812}
1813; CHECK-LABEL: icmpLe64
1814; CHECK: jb
1815; CHECK: ja
1816; CHECK: ja
1817; CHECK: call
1818; CHECK: jl
1819; CHECK: jg
1820; CHECK: ja
1821; CHECK: call
1822;
1823; OPTM1-LABEL: icmpLe64
1824; OPTM1: jb
1825; OPTM1: ja
1826; OPTM1: jbe
1827; OPTM1: call
1828; OPTM1: jl
1829; OPTM1: jg
1830; OPTM1: jbe
1831; OPTM1: call
1832
1833; ARM32-LABEL: icmpLe64
1834; ARM32: cmp
1835; ARM32: cmpeq
1836; ARM32-OM1: tst
1837; ARM32-OM1: bne
1838; ARM32-O2: bhi
1839; ARM32: bl
1840; ARM32: cmp
1841; ARM32: sbcs
1842; ARM32-OM1: tst
1843; ARM32-OM1: bne
1844; ARM32-O2: blt
1845; ARM32: bl
1846
1847; MIPS32-LABEL: icmpLe64
1848; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1849; MIPS32-OM1: sltu [[T2:.*]],[[B_HI]],[[A_HI]]
1850; MIPS32-OM1: xori [[T3:.*]],[[T2]],0x1
1851; MIPS32-OM1: sltu [[T4:.*]],{{.*}},{{.*}}
1852; MIPS32-OM1: xori [[T5:.*]],[[T4]],0x1
1853; MIPS32-O2: sltu [[T3:.*]],[[B_HI]],[[A_HI]]
1854; MIPS32-O2: sltu [[T5:.*]],{{.*}},{{.*}}
1855; MIPS32: movz [[T3]],[[T5]],[[T1]]
1856; MIPS32-O2: bnez [[T3]],{{.*}}
1857; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1858; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1859; MIPS32-OM1: beqz [[T6]],{{.*}}
1860; MIPS32-OM1: b {{.*}}
1861; MIPS32: jal {{.*}}
1862; MIPS32-OM1: b {{.*}}
1863; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1864; MIPS32-OM1: slt [[T2:.*]],[[B_HI]],[[A_HI]]
1865; MIPS32-OM1: xori [[T3:.*]],[[T2]],0x1
1866; MIPS32-OM1: sltu [[T4:.*]],{{.*}},{{.*}}
1867; MIPS32-OM1: xori [[T5:.*]],[[T4]],0x1
1868; MIPS32-O2: slt [[T3:.*]],[[B_HI]],[[A_HI]]
1869; MIPS32-O2: sltu [[T5:.*]],{{.*}},{{.*}}
1870; MIPS32: movz [[T3]],[[T5]],[[T1]]
1871; MIPS32-O2: bnez [[T3]],{{.*}}
1872; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
1873; MIPS32-OM1: lb [[T6:.*]],[[MEM]]
1874; MIPS32-OM1: beqz [[T6]],{{.*}}
1875; MIPS32-OM1: b {{.*}}
1876; MIPS32: jal {{.*}}
1877; MIPS32-OM1: b {{.*}}
1878
1879define internal i32 @icmpEq64Bool(i64 %a, i64 %b) {
1880entry:
1881  %cmp = icmp eq i64 %a, %b
1882  %cmp.ret_ext = zext i1 %cmp to i32
1883  ret i32 %cmp.ret_ext
1884}
1885; CHECK-LABEL: icmpEq64Bool
1886; CHECK: jne
1887; CHECK: je
1888;
1889; OPTM1-LABEL: icmpEq64Bool
1890; OPTM1: jne
1891; OPTM1: je
1892
1893; ARM32-LABEL: icmpEq64Bool
1894; ARM32: mov
1895; ARM32: moveq
1896
1897; MIPS32-LABEL: icmpEq64Bool
1898; MIPS32: xor	[[T1:.*]],{{.*}},{{.*}}
1899; MIPS32: xor	[[T2:.*]],{{.*}},{{.*}}
1900; MIPS32: or	[[T3:.*]],[[T1]],[[T2]]
1901; MIPS32: sltiu	{{.*}},[[T3]],1
1902
1903define internal i32 @icmpNe64Bool(i64 %a, i64 %b) {
1904entry:
1905  %cmp = icmp ne i64 %a, %b
1906  %cmp.ret_ext = zext i1 %cmp to i32
1907  ret i32 %cmp.ret_ext
1908}
1909; CHECK-LABEL: icmpNe64Bool
1910; CHECK: jne
1911; CHECK: jne
1912;
1913; OPTM1-LABEL: icmpNe64Bool
1914; OPTM1: jne
1915; OPTM1: jne
1916
1917; ARM32-LABEL: icmpNe64Bool
1918; ARM32: mov
1919; ARM32: movne
1920
1921; MIPS32-LABEL: icmpNe64Bool
1922; MIPS32: xor   [[T1:.*]],{{.*}},{{.*}}
1923; MIPS32: xor   [[T2:.*]],{{.*}},{{.*}}
1924; MIPS32: or    [[T3:.*]],[[T1]],[[T2]]
1925; MIPS32: sltu {{.*}},zero,[[T3]]
1926
1927define internal i32 @icmpSgt64Bool(i64 %a, i64 %b) {
1928entry:
1929  %cmp = icmp sgt i64 %a, %b
1930  %cmp.ret_ext = zext i1 %cmp to i32
1931  ret i32 %cmp.ret_ext
1932}
1933; CHECK-LABEL: icmpSgt64Bool
1934; CHECK: cmp
1935; CHECK: jg
1936; CHECK: jl
1937; CHECK: cmp
1938; CHECK: ja
1939;
1940; OPTM1-LABEL: icmpSgt64Bool
1941; OPTM1: cmp
1942; OPTM1: jg
1943; OPTM1: jl
1944; OPTM1: cmp
1945; OPTM1: ja
1946
1947; ARM32-LABEL: icmpSgt64Bool
1948; ARM32: mov
1949; ARM32: cmp
1950; ARM32: sbcs
1951; ARM32: movlt
1952
1953; MIPS32-LABEL: icmpSgt64Bool
1954; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1955; MIPS32: slt	[[T2:.*]],{{.*}},{{.*}}
1956; MIPS32: sltu	[[T3:.*]],{{.*}},{{.*}}
1957; MIPS32: movz	[[T2]],[[T3]],[[T1]]
1958; MIPS32-O2: move	{{.*}},[[T2]]
1959; MIPS32-OM1: sw	[[T2]],[[MEM:.*]]
1960; MIPS32-OM1: lb	{{.*}},[[MEM]]
1961
1962define internal i32 @icmpUgt64Bool(i64 %a, i64 %b) {
1963entry:
1964  %cmp = icmp ugt i64 %a, %b
1965  %cmp.ret_ext = zext i1 %cmp to i32
1966  ret i32 %cmp.ret_ext
1967}
1968; CHECK-LABEL: icmpUgt64Bool
1969; CHECK: cmp
1970; CHECK: ja
1971; CHECK: jb
1972; CHECK: cmp
1973; CHECK: ja
1974;
1975; OPTM1-LABEL: icmpUgt64Bool
1976; OPTM1: cmp
1977; OPTM1: ja
1978; OPTM1: jb
1979; OPTM1: cmp
1980; OPTM1: ja
1981
1982; ARM32-LABEL: icmpUgt64Bool
1983; ARM32: mov
1984; ARM32: cmp
1985; ARM32: cmpeq
1986; ARM32: movhi
1987
1988; MIPS32-LABEL: icmpUgt64Bool
1989; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
1990; MIPS32: sltu	[[T2:.*]],[[B_HI]],[[A_HI]]
1991; MIPS32: sltu	[[T3:.*]],{{.*}},{{.*}}
1992; MIPS32: movz	[[T2]],[[T3]],[[T1]]
1993; MIPS32-O2: move	{{.*}},[[T2]]
1994; MIPS32-OM1: sw	[[T2]],[[MEM:.*]]
1995; MIPS32-OM1: lb	{{.*}},[[MEM]]
1996
1997define internal i32 @icmpSge64Bool(i64 %a, i64 %b) {
1998entry:
1999  %cmp = icmp sge i64 %a, %b
2000  %cmp.ret_ext = zext i1 %cmp to i32
2001  ret i32 %cmp.ret_ext
2002}
2003; CHECK-LABEL: icmpSge64Bool
2004; CHECK: cmp
2005; CHECK: jg
2006; CHECK: jl
2007; CHECK: cmp
2008; CHECK: jae
2009;
2010; OPTM1-LABEL: icmpSge64Bool
2011; OPTM1: cmp
2012; OPTM1: jg
2013; OPTM1: jl
2014; OPTM1: cmp
2015; OPTM1: jae
2016
2017; ARM32-LABEL: icmpSge64Bool
2018; ARM32: mov
2019; ARM32: cmp
2020; ARM32: sbcs
2021; ARM32: movge
2022
2023; MIPS32-LABEL: icmpSge64Bool
2024; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
2025; MIPS32: slt	[[T2:.*]],[[A_HI]],[[B_HI]]
2026; MIPS32: xori	[[T3:.*]],[[T2]],0x1
2027; MIPS32: sltu	[[T4:.*]],{{.*}},{{.*}}
2028; MIPS32: xori	[[T5:.*]],[[T4]],0x1
2029; MIPS32: movz	[[T6:.*]],[[T5]],[[T1]]
2030; MIPS32-O2: move       {{.*}},[[T3]]
2031; MIPS32-OM1: sw        [[T3]],[[MEM:.*]]
2032; MIPS32-OM1: lb        {{.*}},[[MEM]]
2033
2034define internal i32 @icmpUge64Bool(i64 %a, i64 %b) {
2035entry:
2036  %cmp = icmp uge i64 %a, %b
2037  %cmp.ret_ext = zext i1 %cmp to i32
2038  ret i32 %cmp.ret_ext
2039}
2040; CHECK-LABEL: icmpUge64Bool
2041; CHECK: cmp
2042; CHECK: ja
2043; CHECK: jb
2044; CHECK: cmp
2045; CHECK: jae
2046;
2047; OPTM1-LABEL: icmpUge64Bool
2048; OPTM1: cmp
2049; OPTM1: ja
2050; OPTM1: jb
2051; OPTM1: cmp
2052; OPTM1: jae
2053
2054; ARM32-LABEL: icmpUge64Bool
2055; ARM32: mov
2056; ARM32: cmp
2057; ARM32: cmpeq
2058; ARM32: movcs
2059
2060; MIPS32-LABEL: icmpUge64Bool
2061; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
2062; MIPS32: sltu	[[T2:.*]],[[A_HI]],[[B_HI]]
2063; MIPS32: xori	[[T3:.*]],[[T2]],0x1
2064; MIPS32: sltu	[[T4:.*]],{{.*}},{{.*}}
2065; MIPS32: xori	[[T5:.*]],[[T4]],0x1
2066; MIPS32: movz	[[T6:.*]],[[T5]],[[T1]]
2067; MIPS32-O2: move	{{.*}},[[T3]]
2068; MIPS32-OM1: sw	[[T3]],[[MEM:.*]]
2069; MIPS32-OM1: lb	{{.*}},[[MEM]]
2070
2071define internal i32 @icmpSlt64Bool(i64 %a, i64 %b) {
2072entry:
2073  %cmp = icmp slt i64 %a, %b
2074  %cmp.ret_ext = zext i1 %cmp to i32
2075  ret i32 %cmp.ret_ext
2076}
2077; CHECK-LABEL: icmpSlt64Bool
2078; CHECK: cmp
2079; CHECK: jl
2080; CHECK: jg
2081; CHECK: cmp
2082; CHECK: jb
2083;
2084; OPTM1-LABEL: icmpSlt64Bool
2085; OPTM1: cmp
2086; OPTM1: jl
2087; OPTM1: jg
2088; OPTM1: cmp
2089; OPTM1: jb
2090
2091; ARM32-LABEL: icmpSlt64Bool
2092; ARM32: mov
2093; ARM32: cmp
2094; ARM32: sbcs
2095; ARM32: movlt
2096
2097; MIPS32-LABEL: icmpSlt64Bool
2098; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
2099; MIPS32: slt	[[T2:.*]],[[A_HI]],[[B_HI]]
2100; MIPS32: sltu	[[T3:.*]],{{.*}},{{.*}}
2101; MIPS32: movz	[[T2:.*]],[[T3]],[[T1]]
2102; MIPS32-O2: move	{{.*}},[[T2]]
2103; MIPS32-OM1: sw	[[T2]],[[MEM:.*]]
2104; MIPS32-OM1: lb	{{.*}},[[MEM]]
2105
2106define internal i32 @icmpUlt64Bool(i64 %a, i64 %b) {
2107entry:
2108  %cmp = icmp ult i64 %a, %b
2109  %cmp.ret_ext = zext i1 %cmp to i32
2110  ret i32 %cmp.ret_ext
2111}
2112; CHECK-LABEL: icmpUlt64Bool
2113; CHECK: cmp
2114; CHECK: jb
2115; CHECK: ja
2116; CHECK: cmp
2117; CHECK: jb
2118;
2119; OPTM1-LABEL: icmpUlt64Bool
2120; OPTM1: cmp
2121; OPTM1: jb
2122; OPTM1: ja
2123; OPTM1: cmp
2124; OPTM1: jb
2125
2126; ARM32-LABEL: icmpUlt64Bool
2127; ARM32: mov
2128; ARM32: cmp
2129; ARM32: cmpeq
2130; ARM32: movcc
2131
2132; MIPS32-LABEL: icmpUlt64Bool
2133; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
2134; MIPS32: sltu	[[T2:.*]],[[A_HI]],[[B_HI]]
2135; MIPS32: sltu	[[T3:.*]],{{.*}},{{.*}}
2136; MIPS32: movz	[[T2:.*]],[[T3]],[[T1]]
2137; MIPS32-O2: move	{{.*}},[[T2]]
2138; MIPS32-OM1: sw	[[T2]],[[MEM:.*]]
2139; MIPS32-OM1: lb	{{.*}},[[MEM]]
2140
2141define internal i32 @icmpSle64Bool(i64 %a, i64 %b) {
2142entry:
2143  %cmp = icmp sle i64 %a, %b
2144  %cmp.ret_ext = zext i1 %cmp to i32
2145  ret i32 %cmp.ret_ext
2146}
2147; CHECK-LABEL: icmpSle64Bool
2148; CHECK: cmp
2149; CHECK: jl
2150; CHECK: jg
2151; CHECK: cmp
2152; CHECK: jbe
2153;
2154; OPTM1-LABEL: icmpSle64Bool
2155; OPTM1: cmp
2156; OPTM1: jl
2157; OPTM1: jg
2158; OPTM1: cmp
2159; OPTM1: jbe
2160
2161; ARM32-LABEL: icmpSle64Bool
2162; ARM32: mov
2163; ARM32: cmp
2164; ARM32: sbcs
2165; ARM32: movge
2166
2167; MIPS32-LABEL: icmpSle64Bool
2168; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
2169; MIPS32: slt	[[T2:.*]],[[B_HI]],[[A_HI]]
2170; MIPS32: xori	[[T3:.*]],[[T2]],0x1
2171; MIPS32: sltu	[[T4:.*]],{{.*}},{{.*}}
2172; MIPS32: xori	[[T5:.*]],[[T4]],0x1
2173; MIPS32: movz	[[T6:.*]],[[T5]],[[T1]]
2174; MIPS32-O2: move	{{.*}},[[T3]]
2175; MIPS32-OM1: sw	[[T3]],[[MEM:.*]]
2176; MIPS32-OM1: lb	{{.*}},[[MEM]]
2177
2178define internal i32 @icmpUle64Bool(i64 %a, i64 %b) {
2179entry:
2180  %cmp = icmp ule i64 %a, %b
2181  %cmp.ret_ext = zext i1 %cmp to i32
2182  ret i32 %cmp.ret_ext
2183}
2184; CHECK-LABEL: icmpUle64Bool
2185; CHECK: cmp
2186; CHECK: jb
2187; CHECK: ja
2188; CHECK: cmp
2189; CHECK: jbe
2190;
2191; OPTM1-LABEL: icmpUle64Bool
2192; OPTM1: cmp
2193; OPTM1: jb
2194; OPTM1: ja
2195; OPTM1: cmp
2196; OPTM1: jbe
2197
2198; ARM32-LABEL: icmpUle64Bool
2199; ARM32: mov
2200; ARM32: cmp
2201; ARM32: cmpeq
2202; ARM32: movls
2203
2204; MIPS32-LABEL: icmpUle64Bool
2205; MIPS32: xor	[[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
2206; MIPS32: sltu	[[T2:.*]],[[B_HI]],[[A_HI]]
2207; MIPS32: xori	[[T3:.*]],[[T2]],0x1
2208; MIPS32: sltu	[[T4:.*]],{{.*}},{{.*}}
2209; MIPS32: xori	[[T5:.*]],[[T4]],0x1
2210; MIPS32: movz	[[T6:.*]],[[T5]],[[T1]]
2211; MIPS32-O2: move	{{.*}},[[T3]]
2212; MIPS32-OM1: sw	[[T3]],[[MEM:.*]]
2213; MIPS32-OM1: lb	{{.*}},[[MEM]]
2214
2215define internal i64 @load64(i32 %a) {
2216entry:
2217  %__1 = inttoptr i32 %a to i64*
2218  %v0 = load i64, i64* %__1, align 1
2219  ret i64 %v0
2220}
2221; CHECK-LABEL: load64
2222; CHECK: mov e[[REGISTER:[a-z]+]],DWORD PTR [esp+0x4]
2223; CHECK-NEXT: mov {{.*}},DWORD PTR [e[[REGISTER]]]
2224; CHECK-NEXT: mov {{.*}},DWORD PTR [e[[REGISTER]]+0x4]
2225;
2226; OPTM1-LABEL: load64
2227; OPTM1: mov e{{..}},DWORD PTR [e{{..}}]
2228; OPTM1: mov e{{..}},DWORD PTR [e{{..}}+0x4]
2229
2230; ARM32-LABEL: load64
2231; ARM32: ldr r{{.*}}, [r[[REG:.*]]]
2232; ARM32: ldr r{{.*}}, [r[[REG]], #4]
2233
2234; MIPS32-LABEL: load64
2235; MIPS32-O2: 	lw	{{.*}},0([[REG:.*]])
2236; MIPS32-O2: 	lw	[[REG]],4([[REG]])
2237
2238define internal void @store64(i32 %a, i64 %value) {
2239entry:
2240  %__2 = inttoptr i32 %a to i64*
2241  store i64 %value, i64* %__2, align 1
2242  ret void
2243}
2244; CHECK-LABEL: store64
2245; CHECK: mov e[[REGISTER:[a-z]+]],DWORD PTR [esp+0x4]
2246; CHECK: mov DWORD PTR [e[[REGISTER]]+0x4],
2247; CHECK: mov DWORD PTR [e[[REGISTER]]],
2248;
2249; OPTM1-LABEL: store64
2250; OPTM1: mov DWORD PTR [e[[REGISTER:[a-z]+]]+0x4],
2251; OPTM1: mov DWORD PTR [e[[REGISTER]]],
2252
2253; ARM32-LABEL: store64
2254; ARM32: str r{{.*}}, [r[[REG:.*]], #4]
2255; ARM32: str r{{.*}}, [r[[REG]]]
2256
2257; MIPS32-LABEL: store64
2258; MIPS32-O2: 	sw	{{.*}},4([[REG:.*]])
2259; MIPS32-O2: 	sw	{{.*}},0([[REG]])
2260
2261define internal void @store64Const(i32 %a) {
2262entry:
2263  %__1 = inttoptr i32 %a to i64*
2264  store i64 -2401053092306725256, i64* %__1, align 1
2265  ret void
2266}
2267; CHECK-LABEL: store64Const
2268; CHECK: mov e[[REGISTER:[a-z]+]],DWORD PTR [esp+0x4]
2269; CHECK: mov DWORD PTR [e[[REGISTER]]+0x4],0xdeadbeef
2270; CHECK: mov DWORD PTR [e[[REGISTER]]],0x12345678
2271;
2272; OPTM1-LABEL: store64Const
2273; OPTM1: mov DWORD PTR [e[[REGISTER:[a-z]+]]+0x4],0xdeadbeef
2274; OPTM1: mov DWORD PTR [e[[REGISTER]]],0x12345678
2275
2276; ARM32-LABEL: store64Const
2277; ARM32: movw [[REG1:.*]], #48879 ; 0xbeef
2278; ARM32: movt [[REG1:.*]], #57005 ; 0xdead
2279; ARM32: movw [[REG2:.*]], #22136 ; 0x5678
2280; ARM32: movt [[REG2:.*]], #4660  ; 0x1234
2281; ARM32: str [[REG1]], [r[[REG:.*]], #4]
2282; ARM32: str [[REG2]], [r[[REG]]]
2283
2284; MIPS32-LABEL: store64Const
2285; MIPS32-O2: 	lui	[[REG1:.*]],0xdead
2286; MIPS32-O2: 	ori	[[REG1:.*]],[[REG1]],0xbeef
2287; MIPS32-O2: 	lui	[[REG2:.*]],0x1234
2288; MIPS32-O2: 	ori	[[REG2:.*]],[[REG2]],0x5678
2289; MIPS32-O2: 	sw	[[REG1]],4([[REG:.*]])
2290; MIPS32-O2: 	sw	[[REG2]],0([[REG]])
2291
2292define internal i64 @select64VarVar(i64 %a, i64 %b) {
2293entry:
2294  %cmp = icmp ult i64 %a, %b
2295  %cond = select i1 %cmp, i64 %a, i64 %b
2296  ret i64 %cond
2297}
2298; CHECK-LABEL: select64VarVar
2299; CHECK: mov
2300; CHECK: mov
2301; CHECK: cmp
2302; CHECK: jb
2303; CHECK: ja
2304; CHECK: cmp
2305; CHECK: jb
2306; CHECK: mov
2307; CHECK: mov
2308;
2309; OPTM1-LABEL: select64VarVar
2310; OPTM1: cmp
2311; OPTM1: jb
2312; OPTM1: ja
2313; OPTM1: cmp
2314; OPTM1: jb
2315; OPTM1: cmp
2316; OPTM1: cmovne
2317
2318; ARM32-LABEL: select64VarVar
2319; ARM32: cmp
2320; ARM32: cmpeq
2321; ARM32-OM1: tst
2322; ARM32-OM1: movne
2323; ARM32-O2: movcc
2324; ARM32-OM1: movne
2325; ARM32-O2: movcc
2326
2327; MIPS32-LABEL: select64VarVar
2328; MIPS32: movn
2329; MIPS32: movn
2330
2331define internal i64 @select64VarConst(i64 %a, i64 %b) {
2332entry:
2333  %cmp = icmp ult i64 %a, %b
2334  %cond = select i1 %cmp, i64 %a, i64 -2401053092306725256
2335  ret i64 %cond
2336}
2337; CHECK-LABEL: select64VarConst
2338; CHECK: mov
2339; CHECK: mov
2340; CHECK: cmp
2341; CHECK: jb
2342; CHECK: ja
2343; CHECK: cmp
2344; CHECK: jb
2345; CHECK: mov
2346; CHECK: mov
2347;
2348; OPTM1-LABEL: select64VarConst
2349; OPTM1: cmp
2350; OPTM1: jb
2351; OPTM1: ja
2352; OPTM1: cmp
2353; OPTM1: jb
2354; OPTM1: cmp
2355; OPTM1: cmovne
2356
2357; ARM32-LABEL: select64VarConst
2358; ARM32: mov
2359; ARM32: mov
2360; ARM32: cmp
2361; ARM32: cmpeq
2362; ARM32-OM1: tst
2363; ARM32-OM1: movne
2364; ARM32-O2: movcc
2365; ARM32-OM1: movne
2366; ARM32-O2: movcc
2367; ARM32-O2: mov
2368; ARM32-O2: mov
2369
2370; MIPS32-LABEL: select64VarConst
2371; MIPS32: movn
2372; MIPS32: movn
2373
2374define internal i64 @select64ConstVar(i64 %a, i64 %b) {
2375entry:
2376  %cmp = icmp ult i64 %a, %b
2377  %cond = select i1 %cmp, i64 -2401053092306725256, i64 %b
2378  ret i64 %cond
2379}
2380; CHECK-LABEL: select64ConstVar
2381; CHECK: mov
2382; CHECK: mov
2383; CHECK: cmp
2384; CHECK: jb
2385; CHECK: ja
2386; CHECK: cmp
2387; CHECK: jb
2388; CHECK: mov
2389; CHECK: mov
2390;
2391; OPTM1-LABEL: select64ConstVar
2392; OPTM1: cmp
2393; OPTM1: jb
2394; OPTM1: ja
2395; OPTM1: cmp
2396; OPTM1: jb
2397; OPTM1: cmp
2398; OPTM1: cmove
2399
2400; ARM32-LABEL: select64ConstVar
2401; ARM32: cmp
2402; ARM32: cmpeq
2403; ARM32-OM1: tst
2404; ARM32: movw
2405; ARM32: movt
2406; ARM32-OM1: movne
2407; ARM32-O2: movcc
2408; ARM32: movw
2409; ARM32: movt
2410; ARM32-OM1: movne
2411; ARM32-O2: movcc
2412
2413; MIPS32-LABEL: select64ConstVar
2414; MIPS32: movn
2415; MIPS32: movn
2416
2417define internal void @icmpEq64Imm() {
2418entry:
2419  %cmp = icmp eq i64 123, 234
2420  br i1 %cmp, label %if.then, label %if.end
2421
2422if.then:                                          ; preds = %entry
2423  call void @func()
2424  br label %if.end
2425
2426if.end:                                           ; preds = %if.then, %entry
2427  %cmp1 = icmp eq i64 345, 456
2428  br i1 %cmp1, label %if.then2, label %if.end3
2429
2430if.then2:                                         ; preds = %if.end
2431  call void @func()
2432  br label %if.end3
2433
2434if.end3:                                          ; preds = %if.then2, %if.end
2435  ret void
2436}
2437; The following checks are not strictly necessary since one of the RUN
2438; lines actually runs the output through the assembler.
2439; CHECK-LABEL: icmpEq64Imm
2440; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
2441; OPTM1-LABEL: icmpEq64Imm
2442; OPTM1-LABEL-NOT: cmp 0x{{[0-9a-f]+}},
2443; ARM32-LABEL: icmpEq64Imm
2444; ARM32-NOT: cmp #{{[0-9a-f]+}},
2445
2446define internal void @icmpLt64Imm() {
2447entry:
2448  %cmp = icmp ult i64 123, 234
2449  br i1 %cmp, label %if.then, label %if.end
2450
2451if.then:                                          ; preds = %entry
2452  call void @func()
2453  br label %if.end
2454
2455if.end:                                           ; preds = %if.then, %entry
2456  %cmp1 = icmp slt i64 345, 456
2457  br i1 %cmp1, label %if.then2, label %if.end3
2458
2459if.then2:                                         ; preds = %if.end
2460  call void @func()
2461  br label %if.end3
2462
2463if.end3:                                          ; preds = %if.then2, %if.end
2464  ret void
2465}
2466; The following checks are not strictly necessary since one of the RUN
2467; lines actually runs the output through the assembler.
2468; CHECK-LABEL: icmpLt64Imm
2469; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
2470; OPTM1-LABEL: icmpLt64Imm
2471; OPTM1-NOT: cmp 0x{{[0-9a-f]+}},
2472; ARM32-LABEL: icmpLt64Imm
2473; ARM32-NOT: cmp #{{[0-9a-f]+}},
2474
2475define internal i64 @phi64Imm(i32 %x, i64 %y, i64 %z) {
2476entry:
2477  %cond = icmp eq i32 %x, 88
2478  br i1 %cond, label %branch1, label %branch2
2479branch1:
2480  %tmp = add i64 %y, %z
2481  br label %branch2
2482
2483branch2:
2484  %merge = phi i64 [ %tmp, %branch1 ], [ 20014547621496, %entry ]
2485  ret i64 %merge
2486}
2487; CHECK-LABEL: phi64Imm
2488; CHECK: mov {{.*}},0x5678
2489; CHECK: mov {{.*}},0x1234
2490; OPTM1-LABEL: phi64Imm
2491; OPTM1: mov {{.*}},0x5678
2492; OPTM1: mov {{.*}},0x1234
2493; ARM32-LABEL: phi64Imm
2494; ARM32: movw {{.*}}, #22136 ; 0x5678
2495; ARM32: movw {{.*}}, #4660  ; 0x1234
2496
2497define internal i64 @phi64Undef(i32 %x, i64 %y, i64 %z) {
2498entry:
2499  %cond = icmp eq i32 %x, 88
2500  br i1 %cond, label %branch1, label %branch2
2501branch1:
2502  %tmp = add i64 %y, %z
2503  br label %branch2
2504
2505branch2:
2506  %merge = phi i64 [ %tmp, %branch1 ], [ undef, %entry ]
2507  ret i64 %merge
2508}
2509
2510; CHECK-LABEL: phi64Undef
2511; CHECK: mov {{.*}},0x0
2512; CHECK: mov {{.*}},0x0
2513; OPTM1-LABEL: phi64Undef
2514; OPTM1: mov {{.*}},0x0
2515; OPTM1: mov {{.*}},0x0
2516; ARM32-LABEL: phi64Undef
2517; ARM32: mov {{.*}} #0
2518; ARM32: mov {{.*}} #0
2519
2520define internal i32 @addOneToUpperAfterShift(i64 %value) {
2521  %a = add i64 %value, 1
2522  %s = lshr i64 %a, 40
2523  %t = trunc i64 %s to i32
2524  %r = add i32 %t, 1
2525  ret i32 %r
2526; ARM32-LABEL: addOneToUpperAfterShift
2527; ARM32: adds
2528; ARM32: adc
2529; ARM32: lsr
2530; ARM32: add
2531}
2532
2533define internal i32 @subOneToUpperAfterShift(i64 %value) {
2534  %a = sub i64 %value, 1
2535  %s = lshr i64 %a, 40
2536  %t = trunc i64 %s to i32
2537  %r = sub i32 %t, 1
2538  ret i32 %r
2539; ARM32-LABEL: subOneToUpperAfterShift
2540; ARM32: subs
2541; ARM32: sbc
2542; ARM32: lsr
2543; ARM32: sub
2544}
2545