1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s --check-prefixes=ALL,VSX
3; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s --check-prefixes=ALL,NOVSX
4
5; Check VMX 64-bit integer operations
6
7define <2 x i64> @test_add(<2 x i64> %x, <2 x i64> %y) nounwind {
8; ALL-LABEL: test_add:
9; ALL:       # %bb.0:
10; ALL-NEXT:    vaddudm 2, 2, 3
11; ALL-NEXT:    blr
12  %result = add <2 x i64> %x, %y
13  ret <2 x i64> %result
14}
15
16define <2 x i64> @increment_by_one(<2 x i64> %x) nounwind {
17; VSX-LABEL: increment_by_one:
18; VSX:       # %bb.0:
19; VSX-NEXT:    addis 3, 2, .LCPI1_0@toc@ha
20; VSX-NEXT:    addi 3, 3, .LCPI1_0@toc@l
21; VSX-NEXT:    lxvd2x 35, 0, 3
22; VSX-NEXT:    vaddudm 2, 2, 3
23; VSX-NEXT:    blr
24;
25; NOVSX-LABEL: increment_by_one:
26; NOVSX:       # %bb.0:
27; NOVSX-NEXT:    addis 3, 2, .LCPI1_0@toc@ha
28; NOVSX-NEXT:    addi 3, 3, .LCPI1_0@toc@l
29; NOVSX-NEXT:    lvx 3, 0, 3
30; NOVSX-NEXT:    vaddudm 2, 2, 3
31; NOVSX-NEXT:    blr
32  %result = add <2 x i64> %x, <i64 1, i64 1>
33  ret <2 x i64> %result
34}
35
36define <2 x i64> @increment_by_val(<2 x i64> %x, i64 %val) nounwind {
37; VSX-LABEL: increment_by_val:
38; VSX:       # %bb.0:
39; VSX-NEXT:    mtfprd 0, 5
40; VSX-NEXT:    xxspltd 35, 0, 0
41; VSX-NEXT:    vaddudm 2, 2, 3
42; VSX-NEXT:    blr
43;
44; NOVSX-LABEL: increment_by_val:
45; NOVSX:       # %bb.0:
46; NOVSX-NEXT:    addi 3, 1, -16
47; NOVSX-NEXT:    std 5, -8(1)
48; NOVSX-NEXT:    std 5, -16(1)
49; NOVSX-NEXT:    lvx 3, 0, 3
50; NOVSX-NEXT:    vaddudm 2, 2, 3
51; NOVSX-NEXT:    blr
52  %tmpvec = insertelement <2 x i64> <i64 0, i64 0>, i64 %val, i32 0
53  %tmpvec2 = insertelement <2 x i64> %tmpvec, i64 %val, i32 1
54  %result = add <2 x i64> %x, %tmpvec2
55  ret <2 x i64> %result
56; FIXME: This is currently generating the following instruction sequence
57;   std 5, -8(1)
58;   std 5, -16(1)
59;   addi 3, 1, -16
60;   ori 2, 2, 0
61;   lxvd2x 35, 0, 3
62;   vaddudm 2, 2, 3
63;   blr
64;   This will almost certainly cause a load-hit-store hazard.
65;   Since val is a value parameter, it should not need to be
66;   saved onto the stack at all (unless we're using this to set
67;   up the vector register). Instead, it would be better to splat
68;   the value into a vector register.
69}
70
71define <2 x i64> @test_sub(<2 x i64> %x, <2 x i64> %y) nounwind {
72; ALL-LABEL: test_sub:
73; ALL:       # %bb.0:
74; ALL-NEXT:    vsubudm 2, 2, 3
75; ALL-NEXT:    blr
76  %result = sub <2 x i64> %x, %y
77  ret <2 x i64> %result
78}
79
80define <2 x i64> @decrement_by_one(<2 x i64> %x) nounwind {
81; VSX-LABEL: decrement_by_one:
82; VSX:       # %bb.0:
83; VSX-NEXT:    xxleqv 35, 35, 35
84; VSX-NEXT:    vsubudm 2, 2, 3
85; VSX-NEXT:    blr
86;
87; NOVSX-LABEL: decrement_by_one:
88; NOVSX:       # %bb.0:
89; NOVSX-NEXT:    addis 3, 2, .LCPI4_0@toc@ha
90; NOVSX-NEXT:    addi 3, 3, .LCPI4_0@toc@l
91; NOVSX-NEXT:    lvx 3, 0, 3
92; NOVSX-NEXT:    vsubudm 2, 2, 3
93; NOVSX-NEXT:    blr
94  %result = sub <2 x i64> %x, <i64 -1, i64 -1>
95  ret <2 x i64> %result
96}
97
98define <2 x i64> @decrement_by_val(<2 x i64> %x, i64 %val) nounwind {
99; VSX-LABEL: decrement_by_val:
100; VSX:       # %bb.0:
101; VSX-NEXT:    mtfprd 0, 5
102; VSX-NEXT:    xxspltd 35, 0, 0
103; VSX-NEXT:    vsubudm 2, 2, 3
104; VSX-NEXT:    blr
105;
106; NOVSX-LABEL: decrement_by_val:
107; NOVSX:       # %bb.0:
108; NOVSX-NEXT:    addi 3, 1, -16
109; NOVSX-NEXT:    std 5, -8(1)
110; NOVSX-NEXT:    std 5, -16(1)
111; NOVSX-NEXT:    lvx 3, 0, 3
112; NOVSX-NEXT:    vsubudm 2, 2, 3
113; NOVSX-NEXT:    blr
114  %tmpvec = insertelement <2 x i64> <i64 0, i64 0>, i64 %val, i32 0
115  %tmpvec2 = insertelement <2 x i64> %tmpvec, i64 %val, i32 1
116  %result = sub <2 x i64> %x, %tmpvec2
117  ret <2 x i64> %result
118}
119