0a338dac6a2a9120d86aba783545450de9d63808
[oota-llvm.git] / lib / Target / PowerPC / README_ALTIVEC.txt
1 //===- README_ALTIVEC.txt - Notes for improving Altivec code gen ----------===//
2
3 Implement PPCInstrInfo::isLoadFromStackSlot/isStoreToStackSlot for vector
4 registers, to generate better spill code.
5
6 //===----------------------------------------------------------------------===//
7
8 Altivec support.  The first should be a single lvx from the constant pool, the
9 second should be a xor/stvx:
10
11 void foo(void) {
12   int x[8] __attribute__((aligned(128))) = { 1, 1, 1, 1, 1, 1, 1, 1 };
13   bar (x);
14 }
15
16 #include <string.h>
17 void foo(void) {
18   int x[8] __attribute__((aligned(128)));
19   memset (x, 0, sizeof (x));
20   bar (x);
21 }
22
23 //===----------------------------------------------------------------------===//
24
25 Altivec: Codegen'ing MUL with vector FMADD should add -0.0, not 0.0:
26 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8763
27
28 When -ffast-math is on, we can use 0.0.
29
30 //===----------------------------------------------------------------------===//
31
32   Consider this:
33   v4f32 Vector;
34   v4f32 Vector2 = { Vector.X, Vector.X, Vector.X, Vector.X };
35
36 Since we know that "Vector" is 16-byte aligned and we know the element offset 
37 of ".X", we should change the load into a lve*x instruction, instead of doing
38 a load/store/lve*x sequence.
39
40 //===----------------------------------------------------------------------===//
41
42 There are a wide range of vector constants we can generate with combinations of
43 altivec instructions.  Examples
44  GCC does: "t=vsplti*, r = t+t"  for constants it can't generate with one vsplti
45
46  -0.0 (sign bit):  vspltisw v0,-1 / vslw v0,v0,v0
47
48 //===----------------------------------------------------------------------===//
49
50 Missing intrinsics:
51
52 ds*
53 vsel (some aliases only accessible using builtins)
54
55 //===----------------------------------------------------------------------===//
56
57 FABS/FNEG can be codegen'd with the appropriate and/xor of -0.0.
58
59 //===----------------------------------------------------------------------===//
60
61 Codegen the constant here with something better than a constant pool load.
62
63 void %test_f(<4 x float>* %P, <4 x float>* %Q, float %X) {
64         %tmp = load <4 x float>* %Q
65         %tmp = cast <4 x float> %tmp to <4 x int>
66         %tmp1 = and <4 x int> %tmp, < int 2147483647, int 2147483647, int 2147483647, int 2147483647 > 
67         %tmp2 = cast <4 x int> %tmp1 to <4 x float>
68         store <4 x float> %tmp2, <4 x float>* %P
69         ret void
70 }
71
72 //===----------------------------------------------------------------------===//
73
74 For functions that use altivec AND have calls, we are VRSAVE'ing all call
75 clobbered regs.
76
77 //===----------------------------------------------------------------------===//
78
79 VSPLTW and friends are expanded by the FE into insert/extract element ops.  Make
80 sure that the dag combiner puts them back together in the appropriate 
81 vector_shuffle node and that this gets pattern matched appropriately.
82
83 //===----------------------------------------------------------------------===//
84
85 Implement passing/returning vectors by value.
86
87 //===----------------------------------------------------------------------===//
88
89 GCC apparently tries to codegen { C1, C2, Variable, C3 } as a constant pool load
90 of C1/C2/C3, then a load and vperm of Variable.
91
92 //===----------------------------------------------------------------------===//
93
94 We currently codegen SCALAR_TO_VECTOR as a store of the scalar to a 16-byte
95 aligned stack slot, followed by a lve*x/vperm.  We should probably just store it
96 to a scalar stack slot, then use lvsl/vperm to load it.  If the value is already
97 in memory, this is a huge win.
98
99 //===----------------------------------------------------------------------===//
100
101 Do not generate the MFCR/RLWINM sequence for predicate compares when the
102 predicate compare is used immediately by a branch.  Just branch on the right
103 cond code on CR6.
104
105 //===----------------------------------------------------------------------===//
106
107 SROA should turn "vector unions" into the appropriate insert/extract element
108 instructions.
109  
110 //===----------------------------------------------------------------------===//
111
112 We need an LLVM 'shuffle' instruction, that corresponds to the VECTOR_SHUFFLE
113 node.
114
115 //===----------------------------------------------------------------------===//
116
117 We need a way to teach tblgen that some operands of an intrinsic are required to
118 be constants.  The verifier should enforce this constraint.
119
120 //===----------------------------------------------------------------------===//
121
122 Instead of writting a pattern for type-agnostic operations (e.g. gen-zero, load,
123 store, and, ...) in every supported type, make legalize do the work.  We should
124 have a canonical type that we want operations changed to (e.g. v4i32 for
125 build_vector) and legalize should change non-identical types to thse.  This is
126 similar to what it does for operations that are only supported in some types,
127 e.g. x86 cmov (not supported on bytes).
128
129 This would fix two problems:
130 1. Writing patterns multiple times.
131 2. Identical operations in different types are not getting CSE'd (e.g. 
132    { 0U, 0U, 0U, 0U } and {0.0, 0.0, 0.0, 0.0}.
133
134 //===----------------------------------------------------------------------===//
135
136 Instcombine llvm.ppc.altivec.vperm with an immediate into a shuffle operation.
137
138 //===----------------------------------------------------------------------===//
139
140 Handle VECTOR_SHUFFLE nodes with the appropriate shuffle mask with vsldoi,
141 vpkuhum and vpkuwum.
142
143 //===----------------------------------------------------------------------===//
144
145 Implement multiply for vector integer types, to avoid the horrible scalarized
146 code produced by legalize.
147
148 void test(vector int *X, vector int *Y) {
149   *X = *X * *Y;
150 }
151
152 //===----------------------------------------------------------------------===//
153
154 Lower "merges" in the front-end to shuffles, reconstruct in the backend.
155
156 //===----------------------------------------------------------------------===//