9766fe9329ddecd7e8c06fd6cad19a4fd33d1a1e
[oota-llvm.git] / test / Transforms / InstCombine / x86-sse4a.ll
1 ; RUN: opt < %s -instcombine -S | FileCheck %s\r
2 \r
3 ; We should optimize these two redundant insertqi into one\r
4 ; CHECK: define <2 x i64> @testInsertTwice(<2 x i64> %v, <2 x i64> %i)\r
5 define <2 x i64> @testInsertTwice(<2 x i64> %v, <2 x i64> %i) {\r
6 ; CHECK: call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 32)\r
7 ; CHECK-NOT: insertqi\r
8   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 32)\r
9   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 32)\r
10   ret <2 x i64> %2\r
11 }\r
12 \r
13 ; The result of this insert is the second arg, since the top 64 bits of\r
14 ; the result are undefined, and we copy the bottom 64 bits from the\r
15 ; second arg\r
16 ; CHECK: define <2 x i64> @testInsert64Bits(<2 x i64> %v, <2 x i64> %i)\r
17 define <2 x i64> @testInsert64Bits(<2 x i64> %v, <2 x i64> %i) {\r
18 ; CHECK: ret <2 x i64> %i\r
19   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 64, i8 0)\r
20   ret <2 x i64> %1\r
21 }\r
22 \r
23 ; Test the several types of ranges and ordering that exist for two insertqi\r
24 ; CHECK: define <2 x i64> @testInsertContainedRange(<2 x i64> %v, <2 x i64> %i)\r
25 define <2 x i64> @testInsertContainedRange(<2 x i64> %v, <2 x i64> %i) {\r
26 ; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)\r
27 ; CHECK: ret <2 x i64> %[[RES]]\r
28   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)\r
29   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 16)\r
30   ret <2 x i64> %2\r
31 }\r
32 \r
33 ; CHECK: define <2 x i64> @testInsertContainedRange_2(<2 x i64> %v, <2 x i64> %i)\r
34 define <2 x i64> @testInsertContainedRange_2(<2 x i64> %v, <2 x i64> %i) {\r
35 ; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)\r
36 ; CHECK: ret <2 x i64> %[[RES]]\r
37   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 16)\r
38   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 0)\r
39   ret <2 x i64> %2\r
40 }\r
41 \r
42 ; CHECK: define <2 x i64> @testInsertOverlappingRange(<2 x i64> %v, <2 x i64> %i)\r
43 define <2 x i64> @testInsertOverlappingRange(<2 x i64> %v, <2 x i64> %i) {\r
44 ; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)\r
45 ; CHECK: ret <2 x i64> %[[RES]]\r
46   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)\r
47   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 16)\r
48   ret <2 x i64> %2\r
49 }\r
50 \r
51 ; CHECK: define <2 x i64> @testInsertOverlappingRange_2(<2 x i64> %v, <2 x i64> %i)\r
52 define <2 x i64> @testInsertOverlappingRange_2(<2 x i64> %v, <2 x i64> %i) {\r
53 ; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)\r
54 ; CHECK: ret <2 x i64> %[[RES]]\r
55   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 16)\r
56   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 0)\r
57   ret <2 x i64> %2\r
58 }\r
59 \r
60 ; CHECK: define <2 x i64> @testInsertAdjacentRange(<2 x i64> %v, <2 x i64> %i)\r
61 define <2 x i64> @testInsertAdjacentRange(<2 x i64> %v, <2 x i64> %i) {\r
62 ; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)\r
63 ; CHECK: ret <2 x i64> %[[RES]]\r
64   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 32, i8 0)\r
65   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)\r
66   ret <2 x i64> %2\r
67 }\r
68 \r
69 ; CHECK: define <2 x i64> @testInsertAdjacentRange_2(<2 x i64> %v, <2 x i64> %i)\r
70 define <2 x i64> @testInsertAdjacentRange_2(<2 x i64> %v, <2 x i64> %i) {\r
71 ; CHECK: %[[RES:.*]] = call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 0)\r
72 ; CHECK: ret <2 x i64> %[[RES]]\r
73   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 32)\r
74   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 32, i8 0)\r
75   ret <2 x i64> %2\r
76 }\r
77 \r
78 ; CHECK: define <2 x i64> @testInsertDisjointRange(<2 x i64> %v, <2 x i64> %i)\r
79 define <2 x i64> @testInsertDisjointRange(<2 x i64> %v, <2 x i64> %i) {\r
80 ; CHECK: tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)\r
81 ; CHECK: tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)\r
82   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)\r
83   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)\r
84   ret <2 x i64> %2\r
85 }\r
86 \r
87 ; CHECK: define <2 x i64> @testInsertDisjointRange_2(<2 x i64> %v, <2 x i64> %i)\r
88 define <2 x i64> @testInsertDisjointRange_2(<2 x i64> %v, <2 x i64> %i) {\r
89 ; CHECK:  tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)\r
90 ; CHECK:  tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)\r
91   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 16, i8 0)\r
92   %2 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %1, <2 x i64> %i, i8 16, i8 32)\r
93   ret <2 x i64> %2\r
94 }\r
95 \r
96 ; CHECK: define <2 x i64> @testZeroLength(<2 x i64> %v, <2 x i64> %i)\r
97 define <2 x i64> @testZeroLength(<2 x i64> %v, <2 x i64> %i) {\r
98 ; CHECK: ret <2 x i64> %i\r
99   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 0, i8 0)\r
100   ret <2 x i64> %1\r
101 }\r
102 \r
103 ; CHECK: define <2 x i64> @testUndefinedInsertq_1(<2 x i64> %v, <2 x i64> %i)\r
104 define <2 x i64> @testUndefinedInsertq_1(<2 x i64> %v, <2 x i64> %i) {\r
105 ; CHECK: ret <2 x i64> undef\r
106   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 0, i8 16)\r
107   ret <2 x i64> %1\r
108 }\r
109 \r
110 ; CHECK: define <2 x i64> @testUndefinedInsertq_2(<2 x i64> %v, <2 x i64> %i)\r
111 define <2 x i64> @testUndefinedInsertq_2(<2 x i64> %v, <2 x i64> %i) {\r
112 ; CHECK: ret <2 x i64> undef\r
113   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 48, i8 32)\r
114   ret <2 x i64> %1\r
115 }\r
116 \r
117 ; CHECK: define <2 x i64> @testUndefinedInsertq_3(<2 x i64> %v, <2 x i64> %i)\r
118 define <2 x i64> @testUndefinedInsertq_3(<2 x i64> %v, <2 x i64> %i) {\r
119 ; CHECK: ret <2 x i64> undef\r
120   %1 = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> %v, <2 x i64> %i, i8 64, i8 16)\r
121   ret <2 x i64> %1\r
122 }\r
123 \r
124 ; CHECK: declare <2 x i64> @llvm.x86.sse4a.insertqi\r
125 declare <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64>, <2 x i64>, i8, i8) nounwind\r