[llvm-commits] CVS: llvm/lib/Target/X86/X86InstrSSE.td

2006-04-16 Thread Evan Cheng


Changes in directory llvm/lib/Target/X86:

X86InstrSSE.td updated: 1.95 -> 1.96
---
Log message:

Encoding bugs

---
Diffs of the changes:  (+2 -2)

 X86InstrSSE.td |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)


Index: llvm/lib/Target/X86/X86InstrSSE.td
diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.95 
llvm/lib/Target/X86/X86InstrSSE.td:1.96
--- llvm/lib/Target/X86/X86InstrSSE.td:1.95 Sat Apr 15 01:10:09 2006
+++ llvm/lib/Target/X86/X86InstrSSE.td  Sun Apr 16 02:02:22 2006
@@ -766,10 +766,10 @@
 
 def MOVUPSrr : PSI<0x10, MRMSrcReg, (ops VR128:$dst, VR128:$src),
"movups {$src, $dst|$dst, $src}", []>;
-def MOVUPSrm : PDI<0x10, MRMSrcMem, (ops VR128:$dst, f128mem:$src),
+def MOVUPSrm : PSI<0x10, MRMSrcMem, (ops VR128:$dst, f128mem:$src),
"movups {$src, $dst|$dst, $src}",
[(set VR128:$dst, (int_x86_sse_loadu_ps addr:$src))]>;
-def MOVUPSmr : PDI<0x11, MRMDestMem, (ops f128mem:$dst, VR128:$src),
+def MOVUPSmr : PSI<0x11, MRMDestMem, (ops f128mem:$dst, VR128:$src),
"movups {$src, $dst|$dst, $src}",
[(int_x86_sse_storeu_ps addr:$dst, VR128:$src)]>;
 def MOVUPDrr : PDI<0x10, MRMSrcReg, (ops VR128:$dst, VR128:$src),



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/Target/X86/X86InstrSSE.td

2006-04-16 Thread Evan Cheng


Changes in directory llvm/lib/Target/X86:

X86InstrSSE.td updated: 1.96 -> 1.97
---
Log message:

movduprm, movshduprm bugs

---
Diffs of the changes:  (+5 -4)

 X86InstrSSE.td |9 +
 1 files changed, 5 insertions(+), 4 deletions(-)


Index: llvm/lib/Target/X86/X86InstrSSE.td
diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.96 
llvm/lib/Target/X86/X86InstrSSE.td:1.97
--- llvm/lib/Target/X86/X86InstrSSE.td:1.96 Sun Apr 16 02:02:22 2006
+++ llvm/lib/Target/X86/X86InstrSSE.td  Sun Apr 16 13:11:28 2006
@@ -852,7 +852,7 @@
   [(set VR128:$dst, (v4f32 (vector_shuffle
 VR128:$src, (undef),
 MOVSHDUP_shuffle_mask)))]>;
-def MOVSHDUPrm : S3SI<0x16, MRMSrcReg, (ops VR128:$dst, f128mem:$src),
+def MOVSHDUPrm : S3SI<0x16, MRMSrcMem, (ops VR128:$dst, f128mem:$src),
   "movshdup {$src, $dst|$dst, $src}",
   [(set VR128:$dst, (v4f32 (vector_shuffle
 (loadv4f32 addr:$src), (undef),
@@ -863,7 +863,7 @@
   [(set VR128:$dst, (v4f32 (vector_shuffle
 VR128:$src, (undef),
 MOVSLDUP_shuffle_mask)))]>;
-def MOVSLDUPrm : S3SI<0x12, MRMSrcReg, (ops VR128:$dst, f128mem:$src),
+def MOVSLDUPrm : S3SI<0x12, MRMSrcMem, (ops VR128:$dst, f128mem:$src),
   "movsldup {$src, $dst|$dst, $src}",
   [(set VR128:$dst, (v4f32 (vector_shuffle
 (loadv4f32 addr:$src), (undef),
@@ -874,10 +874,11 @@
   [(set VR128:$dst, (v2f64 (vector_shuffle
 VR128:$src, (undef),
 SSE_splat_v2_mask)))]>;
-def MOVDDUPrm : S3DI<0x12, MRMSrcReg, (ops VR128:$dst, f64mem:$src),
+def MOVDDUPrm : S3DI<0x12, MRMSrcMem, (ops VR128:$dst, f64mem:$src),
   "movddup {$src, $dst|$dst, $src}",
   [(set VR128:$dst, (v2f64 (vector_shuffle
-(loadv2f64 addr:$src), (undef),
+ (scalar_to_vector (loadf64 
addr:$src)),
+ (undef),
 SSE_splat_v2_mask)))]>;
 
 // SSE2 instructions without OpSize prefix



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/vec_splat.ll

2006-04-16 Thread Evan Cheng


Changes in directory llvm/test/Regression/CodeGen/X86:

vec_splat.ll updated: 1.2 -> 1.3
---
Log message:

Better way to splat v2f64

---
Diffs of the changes:  (+1 -1)

 vec_splat.ll |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


Index: llvm/test/Regression/CodeGen/X86/vec_splat.ll
diff -u llvm/test/Regression/CodeGen/X86/vec_splat.ll:1.2 
llvm/test/Regression/CodeGen/X86/vec_splat.ll:1.3
--- llvm/test/Regression/CodeGen/X86/vec_splat.ll:1.2   Wed Mar 29 12:59:48 2006
+++ llvm/test/Regression/CodeGen/X86/vec_splat.ll   Sun Apr 16 13:16:43 2006
@@ -1,5 +1,5 @@
 ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep shufps
-; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep unpcklpd
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep mulpd
 
 void %test_v4sf(<4 x float>* %P, <4 x float>* %Q, float %X) {
%tmp = insertelement <4 x float> zeroinitializer, float %X, uint 0



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/BuildShuffleTable/

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils/BuildShuffleTable:

---
Log message:

Directory /home/vadve/shared/PublicCVS/llvm/utils/BuildShuffleTable added to 
the repository


---
Diffs of the changes:  (+0 -0)

 0 files changed



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp Makefile

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils/BuildShuffleTable:

BuildShuffleTable.cpp added (r1.1)
Makefile added (r1.1)
---
Log message:

Initial checking of a perfect shuffle generation program for 4-element 
Altivec vectors.


---
Diffs of the changes:  (+487 -0)

 BuildShuffleTable.cpp |  474 ++
 Makefile  |   13 +
 2 files changed, 487 insertions(+)


Index: llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp
diff -c /dev/null llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp:1.1
*** /dev/null   Sun Apr 16 19:30:51 2006
--- llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp  Sun Apr 16 19:30:41 2006
***
*** 0 
--- 1,474 
+ //===-- BuildShuffleTable.cpp - Perfect Shuffle Generator 
-===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Chris Lattner and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for 
details.
+ //
+ 
//===--===//
+ //
+ // This file computes an optimal sequence of instructions for doing all 
shuffles
+ // of two 4-element vectors.  With a release build and when configured to emit
+ // an altivec instruction table, this takes about 30s to run on a 2.7Ghz
+ // PowerPC G5.
+ //
+ 
//===--===//
+ 
+ #include 
+ #include 
+ 
+ struct Operator;
+ 
+ // Masks are 4-nibble hex numbers.  Values 0-7 in any nibble means that it 
takes
+ // an element from that value of the input vectors.  A value of 8 means the 
+ // entry is undefined.
+ 
+ // Mask manipulation functions.
+ static inline unsigned short MakeMask(unsigned V0, unsigned V1, 
+   unsigned V2, unsigned V3) {
+   return (V0 << (3*4)) | (V1 << (2*4)) | (V2 << (1*4)) | (V3 << (0*4));
+ }
+ 
+ /// getMaskElt - Return element N of the specified mask.
+ static unsigned getMaskElt(unsigned Mask, unsigned Elt) {
+   return (Mask >> ((3-Elt)*4)) & 0xF;
+ }
+ 
+ static unsigned setMaskElt(unsigned Mask, unsigned Elt, unsigned NewVal) {
+   unsigned FieldShift = ((3-Elt)*4);
+   return (Mask & ~(0xF << FieldShift)) | (NewVal << FieldShift);
+ }
+ 
+ // Reject elements where the values are 9-15.
+ static bool isValidMask(unsigned short Mask) {
+   unsigned short UndefBits = Mask & 0x;
+   return (Mask & ((UndefBits >> 1)|(UndefBits>>2)|(UndefBits>>3))) == 0;
+ }
+ 
+ /// hasUndefElements - Return true if any of the elements in the mask are 
undefs
+ ///
+ static bool hasUndefElements(unsigned short Mask) {
+   return (Mask & 0x) != 0;
+ }
+ 
+ /// isOnlyLHSMask - Return true if this mask only refers to its LHS, not
+ /// including undef values..
+ static bool isOnlyLHSMask(unsigned short Mask) {
+   return (Mask & 0x) == 0;
+ }
+ 
+ /// getLHSOnlyMask - Given a mask that refers to its LHS and RHS, modify it to
+ /// refer to the LHS only (for when one argument value is passed into the same
+ /// function twice).
+ static unsigned short getLHSOnlyMask(unsigned short Mask) {
+   return Mask & 0x;  // Keep only LHS and Undefs.
+ }
+ 
+ /// getCompressedMask - Turn a 16-bit uncompressed mask (where each elt uses 4
+ /// bits) into a compressed 13-bit mask, where each elt is multiplied by 9.
+ static unsigned getCompressedMask(unsigned short Mask) {
+   return getMaskElt(Mask, 0)*9*9*9 + getMaskElt(Mask, 1)*9*9 + 
+  getMaskElt(Mask, 2)*9 + getMaskElt(Mask, 3);
+ }
+ 
+ static void PrintMask(unsigned i, std::ostream &OS) {
+   OS << "<" << (char)(getMaskElt(i, 0) == 8 ? 'u' : ('0'+getMaskElt(i, 0)))
+  << "," << (char)(getMaskElt(i, 1) == 8 ? 'u' : ('0'+getMaskElt(i, 1)))
+  << "," << (char)(getMaskElt(i, 2) == 8 ? 'u' : ('0'+getMaskElt(i, 2)))
+  << "," << (char)(getMaskElt(i, 3) == 8 ? 'u' : ('0'+getMaskElt(i, 3)))
+  << ">";
+ }
+ 
+ /// ShuffleVal - This represents a shufflevector operation.
+ struct ShuffleVal {
+   unsigned Cost;  // Number of instrs used to generate this value.
+   Operator *Op;   // The Operation used to generate this value.
+   unsigned short Arg0, Arg1;  // Input operands for this value.
+   
+   ShuffleVal() : Cost(100) {}
+ };
+ 
+ 
+ /// ShufTab - This is the actual shuffle table that we are trying to generate.
+ ///
+ static ShuffleVal ShufTab[65536];
+ 
+ /// TheOperators - All of the operators that this target supports.
+ static std::vector TheOperators;
+ 
+ /// Operator - This is a vector operation that is available for use.
+ struct Operator {
+   unsigned short ShuffleMask;
+   unsigned short OpNum;
+   const char *Name;
+   
+   Operator(unsigned short shufflemask, const char *name)
+ : ShuffleMask(shufflemask), Name(name) {
+ OpNum = TheOperators.size();
+ TheOperators.push_back(this);
+   }
+   ~Operator() {
+ assert(TheOperators.back() == this);
+ TheOperators.pop_back();
+   }
+   
+   bool is

[llvm-commits] CVS: llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils/BuildShuffleTable:

BuildShuffleTable.cpp updated: 1.1 -> 1.2
---
Log message:

rename the table


---
Diffs of the changes:  (+1 -1)

 BuildShuffleTable.cpp |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


Index: llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp
diff -u llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp:1.1 
llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp:1.2
--- llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp:1.1  Sun Apr 16 
19:30:41 2006
+++ llvm/utils/BuildShuffleTable/BuildShuffleTable.cpp  Sun Apr 16 19:33:35 2006
@@ -375,7 +375,7 @@
   
   // Build up the table to emit.
   std::cout << "\n// This table is 6561*4 = 26244 bytes in size.\n";
-  std::cout << "static const unsigned InstrTab[6561+1] = {\n";
+  std::cout << "static const unsigned PerfectShuffleTable[6561+1] = {\n";
   
   for (unsigned i = 0; i != 0x8889; ++i) {
 if (!isValidMask(i)) continue;



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/PerfectShuffle/Makefile PerfectShuffle.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils/PerfectShuffle:

Makefile updated: 1.1 -> 1.2
PerfectShuffle.cpp updated: 1.2 -> 1.3
---
Log message:

Rename BuildShuffleTable -> PerfectShuffle


---
Diffs of the changes:  (+3 -3)

 Makefile   |4 ++--
 PerfectShuffle.cpp |2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)


Index: llvm/utils/PerfectShuffle/Makefile
diff -u llvm/utils/PerfectShuffle/Makefile:1.1 
llvm/utils/PerfectShuffle/Makefile:1.2
--- llvm/utils/PerfectShuffle/Makefile:1.1  Sun Apr 16 19:30:41 2006
+++ llvm/utils/PerfectShuffle/Makefile  Sun Apr 16 19:35:34 2006
@@ -1,4 +1,4 @@
-##===- utils/BuildShuffleTable/Makefile *- Makefile 
-*-===##
+##===- utils/PerfectShuffle/Makefile ---*- Makefile 
-*-===##
 # 
 # The LLVM Compiler Infrastructure
 #
@@ -8,6 +8,6 @@
 
##===--===##
 
 LEVEL = ../..
-TOOLNAME = llvm-BuildShuffleTable
+TOOLNAME = llvm-PerfectShuffle
 include $(LEVEL)/Makefile.common
 


Index: llvm/utils/PerfectShuffle/PerfectShuffle.cpp
diff -u llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.2 
llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.3
--- llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.2Sun Apr 16 19:33:35 2006
+++ llvm/utils/PerfectShuffle/PerfectShuffle.cppSun Apr 16 19:35:34 2006
@@ -1,4 +1,4 @@
-//===-- BuildShuffleTable.cpp - Perfect Shuffle Generator 
-===//
+//===-- PerfectShuffle.cpp - Perfect Shuffle Generator 
===//
 //
 // The LLVM Compiler Infrastructure
 //



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/Makefile

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils:

Makefile updated: 1.12 -> 1.13
---
Log message:

Rename BuildShuffleTable -> PerfectShuffle


---
Diffs of the changes:  (+1 -1)

 Makefile |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


Index: llvm/utils/Makefile
diff -u llvm/utils/Makefile:1.12 llvm/utils/Makefile:1.13
--- llvm/utils/Makefile:1.12Thu Apr 13 01:27:20 2006
+++ llvm/utils/Makefile Sun Apr 16 19:35:34 2006
@@ -8,7 +8,7 @@
 
##===--===##
 
 LEVEL = ..
-DIRS = Burg TableGen fpcmp
+DIRS = Burg TableGen fpcmp PerfectShuffle
 
 EXTRA_DIST := cgiplotNLT.pl check-each-file codegen-diff countloc.sh cvsupdate 
\
   DSAclean.py DSAextract.py emacs findsym.pl GenLibDeps.pl \



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/llvmdo

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils:

llvmdo updated: 1.11 -> 1.12
---
Log message:

PPCPerfectShuffle.h is autogenerated, don't include it in the LOC counts.


---
Diffs of the changes:  (+1 -0)

 llvmdo |1 +
 1 files changed, 1 insertion(+)


Index: llvm/utils/llvmdo
diff -u llvm/utils/llvmdo:1.11 llvm/utils/llvmdo:1.12
--- llvm/utils/llvmdo:1.11  Tue Mar 14 00:08:05 2006
+++ llvm/utils/llvmdo   Sun Apr 16 19:46:09 2006
@@ -105,6 +105,7 @@
   \! -name 'StackerParser.h' \
   \! -name 'StackerParser.cpp' \
   \! -name 'ConfigLexer.cpp' \
+  \! -name 'PPCPerfectShuffle.h' \
  -exec $PROGRAM "$@" {} \; \
 \)
 else



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/PerfectShuffle/PerfectShuffle.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils/PerfectShuffle:

PerfectShuffle.cpp updated: 1.3 -> 1.4
---
Log message:

assign stable opcodes to the various altivec ops.


---
Diffs of the changes:  (+33 -14)

 PerfectShuffle.cpp |   47 +--
 1 files changed, 33 insertions(+), 14 deletions(-)


Index: llvm/utils/PerfectShuffle/PerfectShuffle.cpp
diff -u llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.3 
llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.4
--- llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.3Sun Apr 16 19:35:34 2006
+++ llvm/utils/PerfectShuffle/PerfectShuffle.cppSun Apr 16 19:47:18 2006
@@ -102,9 +102,8 @@
   unsigned short OpNum;
   const char *Name;
   
-  Operator(unsigned short shufflemask, const char *name)
-: ShuffleMask(shufflemask), Name(name) {
-OpNum = TheOperators.size();
+  Operator(unsigned short shufflemask, const char *name, unsigned opnum)
+: ShuffleMask(shufflemask), OpNum(opnum), Name(name) {
 TheOperators.push_back(this);
   }
   ~Operator() {
@@ -438,37 +437,57 @@
 }
 
 
+#define GENERATE_ALTIVEC
+
+#ifdef GENERATE_ALTIVEC
 
 
///===-===//
 /// The altivec instruction definitions.  This is the altivec-specific part of
 /// this file.
 
///===-===//
 
+// Note that the opcode numbers here must match those in the PPC backend.
+enum {
+  OP_COPY = 0,   // Copy, used for things like  to say it is <0,1,2,3>
+  OP_VMRGHW,
+  OP_VMRGLW,
+  OP_VSPLTISW0,
+  OP_VSPLTISW1,
+  OP_VSPLTISW2,
+  OP_VSPLTISW3,
+  OP_VSLDOI4,
+  OP_VSLDOI8,
+  OP_VSLDOI12,
+};
+
 struct vmrghw : public Operator {
-  vmrghw() : Operator(0x0415, "vmrghw") {}
+  vmrghw() : Operator(0x0415, "vmrghw", OP_VMRGHW) {}
 } the_vmrghw;
 
 struct vmrglw : public Operator {
-  vmrglw() : Operator(0x2637, "vmrglw") {}
+  vmrglw() : Operator(0x2637, "vmrglw", OP_VMRGLW) {}
 } the_vmrglw;
 
 template
 struct vspltisw : public Operator {
-  vspltisw(const char *N) : Operator(MakeMask(Elt, Elt, Elt, Elt), N) {}
+  vspltisw(const char *N, unsigned Opc)
+: Operator(MakeMask(Elt, Elt, Elt, Elt), N, Opc) {}
 };
 
-vspltisw<0> the_vspltisw0("vspltisw0");
-vspltisw<1> the_vspltisw1("vspltisw1");
-vspltisw<2> the_vspltisw2("vspltisw2");
-vspltisw<3> the_vspltisw3("vspltisw3");
+vspltisw<0> the_vspltisw0("vspltisw0", OP_VSPLTISW0);
+vspltisw<1> the_vspltisw1("vspltisw1", OP_VSPLTISW1);
+vspltisw<2> the_vspltisw2("vspltisw2", OP_VSPLTISW2);
+vspltisw<3> the_vspltisw3("vspltisw3", OP_VSPLTISW3);
 
 template
 struct vsldoi : public Operator {
-  vsldoi(const char *n) : Operator(MakeMask(N&7, (N+1)&7, (N+2)&7, (N+3)&7), 
n){
+  vsldoi(const char *Name, unsigned Opc)
+: Operator(MakeMask(N&7, (N+1)&7, (N+2)&7, (N+3)&7), Name, Opc) {
   }
 };
 
-vsldoi<1> the_vsldoi1("vsldoi4");
-vsldoi<2> the_vsldoi2("vsldoi8");
-vsldoi<3> the_vsldoi3("vsldoi12");
+vsldoi<1> the_vsldoi1("vsldoi4" , OP_VSLDOI4);
+vsldoi<2> the_vsldoi2("vsldoi8" , OP_VSLDOI8);
+vsldoi<3> the_vsldoi3("vsldoi12", OP_VSLDOI12);
 
+#endif



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/PerfectShuffle/PerfectShuffle.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils/PerfectShuffle:

PerfectShuffle.cpp updated: 1.4 -> 1.5
---
Log message:

Really, I can count!


---
Diffs of the changes:  (+1 -1)

 PerfectShuffle.cpp |2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


Index: llvm/utils/PerfectShuffle/PerfectShuffle.cpp
diff -u llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.4 
llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.5
--- llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.4Sun Apr 16 19:47:18 2006
+++ llvm/utils/PerfectShuffle/PerfectShuffle.cppMon Apr 17 00:05:52 2006
@@ -391,7 +391,7 @@
 
 // Encode this as 2 bits of saturated cost, 4 bits of opcodes, 13 bits of
 // LHS, and 13 bits of RHS = 32 bits.
-unsigned Val = (CostSat << 30) | (OpNum << 27) | (LHS << 13) | RHS;
+unsigned Val = (CostSat << 30) | (OpNum << 26) | (LHS << 13) | RHS;
 
 std::cout << "  " << Val << "U,\t// ";
 PrintMask(i, std::cout);



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/utils/PerfectShuffle/PerfectShuffle.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/utils/PerfectShuffle:

PerfectShuffle.cpp updated: 1.5 -> 1.6
---
Log message:

Encode a cost of zero as a cost of 1.


---
Diffs of the changes:  (+3 -1)

 PerfectShuffle.cpp |4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)


Index: llvm/utils/PerfectShuffle/PerfectShuffle.cpp
diff -u llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.5 
llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.6
--- llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.5Mon Apr 17 00:05:52 2006
+++ llvm/utils/PerfectShuffle/PerfectShuffle.cppMon Apr 17 00:25:16 2006
@@ -381,7 +381,9 @@
 
 // CostSat - The cost of this operation saturated to two bits.
 unsigned CostSat = ShufTab[i].Cost;
-if (CostSat > 3) CostSat = 3;
+if (CostSat > 4) CostSat = 4;
+if (CostSat == 0) CostSat = 1;
+--CostSat;  // Cost is now between 0-3.
 
 unsigned OpNum = ShufTab[i].Op ? ShufTab[i].Op->OpNum : 0;
 assert(OpNum < 16 && "Too few bits to encode operation!");



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/vec_perf_shuffle.ll

2006-04-16 Thread Chris Lattner


Changes in directory llvm/test/Regression/CodeGen/PowerPC:

vec_perf_shuffle.ll added (r1.1)
---
Log message:

new testcase, these shuffles can be implemented with discrete instructions,
and shouldn't be lowered to vperm.


---
Diffs of the changes:  (+43 -0)

 vec_perf_shuffle.ll |   43 +++
 1 files changed, 43 insertions(+)


Index: llvm/test/Regression/CodeGen/PowerPC/vec_perf_shuffle.ll
diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/vec_perf_shuffle.ll:1.1
*** /dev/null   Mon Apr 17 00:27:41 2006
--- llvm/test/Regression/CodeGen/PowerPC/vec_perf_shuffle.llMon Apr 17 
00:27:31 2006
***
*** 0 
--- 1,43 
+ ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5 &&
+ ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5 | not grep vperm
+ 
+ <4 x float> %test_uu72(<4 x float> *%P1, <4 x float> *%P2) {
+   %V1 = load <4 x float> *%P1
+   %V2 = load <4 x float> *%P2
+   ; vmrglw + vsldoi
+   %V3 = shufflevector <4 x float> %V1, <4 x float> %V2,
+   <4 x uint> 
+   ret <4 x float> %V3
+ }
+ 
+ <4 x float> %test_30u5(<4 x float> *%P1, <4 x float> *%P2) {
+   %V1 = load <4 x float> *%P1
+   %V2 = load <4 x float> *%P2
+   %V3 = shufflevector <4 x float> %V1, <4 x float> %V2,
+ <4 x uint> 
+   ret <4 x float> %V3
+ }
+ 
+ <4 x float> %test_3u73(<4 x float> *%P1, <4 x float> *%P2) {
+   %V1 = load <4 x float> *%P1
+   %V2 = load <4 x float> *%P2
+   %V3 = shufflevector <4 x float> %V1, <4 x float> %V2,
+ <4 x uint> 
+   ret <4 x float> %V3
+ }
+ 
+ <4 x float> %test_3774(<4 x float> *%P1, <4 x float> *%P2) {
+   %V1 = load <4 x float> *%P1
+   %V2 = load <4 x float> *%P2
+   %V3 = shufflevector <4 x float> %V1, <4 x float> %V2,
+ <4 x uint> 
+   ret <4 x float> %V3
+ }
+ 
+ <4 x float> %test_4450(<4 x float> *%P1, <4 x float> *%P2) {
+   %V1 = load <4 x float> *%P1
+   %V2 = load <4 x float> *%P2
+   %V3 = shufflevector <4 x float> %V1, <4 x float> %V2,
+ <4 x uint> 
+   ret <4 x float> %V3
+ }



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp README_ALTIVEC.txt

2006-04-16 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.154 -> 1.155
README_ALTIVEC.txt updated: 1.24 -> 1.25
---
Log message:

Implement a TODO: for any shuffle that can be viewed as a v4[if]32 shuffle,
if it can be implemented in 3 or fewer discrete altivec instructions, codegen
it as such.  This implements Regression/CodeGen/PowerPC/vec_perf_shuffle.ll


---
Diffs of the changes:  (+135 -14)

 PPCISelLowering.cpp |  137 +++-
 README_ALTIVEC.txt  |   10 ---
 2 files changed, 135 insertions(+), 12 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.154 
llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.155
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.154   Sat Apr 15 20:37:57 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Apr 17 00:28:54 2006
@@ -13,6 +13,7 @@
 
 #include "PPCISelLowering.h"
 #include "PPCTargetMachine.h"
+#include "PPCPerfectShuffle.h"
 #include "llvm/ADT/VectorExtras.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
@@ -1123,6 +1124,88 @@
   return SDOperand();
 }
 
+/// GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit
+/// the specified operations to build the shuffle.
+static SDOperand GeneratePerfectShuffle(unsigned PFEntry, SDOperand LHS,
+SDOperand RHS, SelectionDAG &DAG) {
+  unsigned OpNum = (PFEntry >> 26) & 0x0F;
+  unsigned LHSID  = (PFEntry >> 13) & ((1 << 13)-1);
+  unsigned RHSID = (PFEntry >>  0) & ((1 << 13)-1);
+  
+  enum {
+OP_COPY = 0,   // Copy, used for things like  to say it is 
<0,1,2,3>
+OP_VMRGHW,
+OP_VMRGLW,
+OP_VSPLTISW0,
+OP_VSPLTISW1,
+OP_VSPLTISW2,
+OP_VSPLTISW3,
+OP_VSLDOI4,
+OP_VSLDOI8,
+OP_VSLDOI12,
+  };
+  
+  if (OpNum == OP_COPY) {
+if (LHSID == (1*9+2)*9+3) return LHS;
+assert(LHSID == ((4*9+5)*9+6)*9+7 && "Illegal OP_COPY!");
+return RHS;
+  }
+  
+  unsigned ShufIdxs[16];
+  switch (OpNum) {
+  default: assert(0 && "Unknown i32 permute!");
+  case OP_VMRGHW:
+ShufIdxs[ 0] =  0; ShufIdxs[ 1] =  1; ShufIdxs[ 2] =  2; ShufIdxs[ 3] =  3;
+ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
+ShufIdxs[ 8] =  4; ShufIdxs[ 9] =  5; ShufIdxs[10] =  6; ShufIdxs[11] =  7;
+ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
+break;
+  case OP_VMRGLW:
+ShufIdxs[ 0] =  8; ShufIdxs[ 1] =  9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
+ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
+ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
+ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
+break;
+  case OP_VSPLTISW0:
+for (unsigned i = 0; i != 16; ++i)
+  ShufIdxs[i] = (i&3)+0;
+break;
+  case OP_VSPLTISW1:
+for (unsigned i = 0; i != 16; ++i)
+  ShufIdxs[i] = (i&3)+4;
+break;
+  case OP_VSPLTISW2:
+for (unsigned i = 0; i != 16; ++i)
+  ShufIdxs[i] = (i&3)+8;
+break;
+  case OP_VSPLTISW3:
+for (unsigned i = 0; i != 16; ++i)
+  ShufIdxs[i] = (i&3)+12;
+break;
+  case OP_VSLDOI4:
+for (unsigned i = 0; i != 16; ++i)
+  ShufIdxs[i] = i+4;
+break;
+  case OP_VSLDOI8:
+for (unsigned i = 0; i != 16; ++i)
+  ShufIdxs[i] = i+8;
+break;
+  case OP_VSLDOI12:
+for (unsigned i = 0; i != 16; ++i)
+  ShufIdxs[i] = i+12;
+break;
+  }
+  std::vector Ops;
+  for (unsigned i = 0; i != 16; ++i)
+Ops.push_back(DAG.getConstant(ShufIdxs[i], MVT::i32));
+  SDOperand OpLHS, OpRHS;
+  OpLHS = GeneratePerfectShuffle(PerfectShuffleTable[LHSID], LHS, RHS, DAG);
+  OpRHS = GeneratePerfectShuffle(PerfectShuffleTable[RHSID], LHS, RHS, DAG);
+  
+  return DAG.getNode(ISD::VECTOR_SHUFFLE, OpLHS.getValueType(), OpLHS, OpRHS,
+ DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, Ops));
+}
+
 /// LowerVECTOR_SHUFFLE - Return the code we lower for VECTOR_SHUFFLE.  If this
 /// is a shuffle we can handle in a single instruction, return it.  Otherwise,
 /// return the code it can be lowered into.  Worst case, it can always be
@@ -1166,8 +1249,58 @@
   PPC::isVMRGHShuffleMask(PermMask.Val, 4, false))
 return Op;
   
-  // TODO: Handle more cases, and also handle cases that are cheaper to do as
-  // multiple such instructions than as a constant pool load/vperm pair.
+  // Check to see if this is a shuffle of 4-byte values.  If so, we can use our
+  // perfect shuffle table to emit an optimal matching sequence.
+  unsigned PFIndexes[4];
+  bool isFourElementShuffle = true;
+  for (unsigned i = 0; i != 4 && isFourElementShuffle; ++i) { // Element number
+unsigned EltNo = 8;   // Start out undef.
+for (unsigned j = 0; j != 4; ++j) {  // Intra-element byte.
+  if (PermMask.getOperand(i*4+j).getOpcode() == ISD::UNDEF)
+  

[llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll

2006-04-16 Thread Chris Lattner


Changes in directory llvm/test/Regression/CodeGen/PowerPC:

vec_constants.ll updated: 1.1 -> 1.2
---
Log message:

New testcase


---
Diffs of the changes:  (+3 -0)

 vec_constants.ll |3 +++
 1 files changed, 3 insertions(+)


Index: llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll
diff -u llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.1 
llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.2
--- llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.1   Wed Apr 12 
14:04:27 2006
+++ llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll   Mon Apr 17 
00:58:22 2006
@@ -18,3 +18,6 @@
 ret void
 }
 
+<4 x int> %test2() {
+ret <4 x int> 
+}



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.155 -> 1.156
---
Log message:

Pull some code out into a helper function.
Effeciently codegen even splats in the range [-32,30].

This allows us to codegen <30,30,30,30> as:

vspltisw v0, 15
vadduwm v2, v0, v0

instead of as a cp load.



---
Diffs of the changes:  (+26 -16)

 PPCISelLowering.cpp |   42 ++
 1 files changed, 26 insertions(+), 16 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.155 
llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.156
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.155   Mon Apr 17 00:28:54 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Apr 17 01:00:21 2006
@@ -1041,6 +1041,23 @@
   return true;
 }
 
+/// BuildSplatI - Build a canonical splati of Val with an element size of
+/// SplatSize.  Cast the result to VT.
+static SDOperand BuildSplatI(int Val, unsigned SplatSize, MVT::ValueType VT,
+ SelectionDAG &DAG) {
+  assert(Val >= -16 && Val <= 15 && "vsplti is out of range!");
+  static const MVT::ValueType VTys[] = { // canonical VT to use for each size.
+MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
+  };
+  MVT::ValueType CanonicalVT = VTys[SplatSize-1];
+  
+  // Build a canonical splat for this value.
+  SDOperand Elt = DAG.getConstant(Val, MVT::getVectorBaseType(CanonicalVT));
+  std::vector Ops(MVT::getVectorNumElements(CanonicalVT), Elt);
+  SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT, Ops);
+  return DAG.getNode(ISD::BIT_CONVERT, VT, Res);
+}
+
 // If this is a case we can't handle, return null and let the default
 // expansion code take care of it.  If we CAN select this case, and if it
 // selects to a single instruction, return Op.  Otherwise, if we can codegen
@@ -1079,23 +1096,16 @@
 
 // If the sign extended value is in the range [-16,15], use VSPLTI[bhw].
 int32_t SextVal= int32_t(SplatBits << (32-8*SplatSize)) >> 
(32-8*SplatSize);
-if (SextVal >= -16 && SextVal <= 15) {
-  const MVT::ValueType VTys[] = { // canonical VT to use for each size.
-MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
-  };
-  MVT::ValueType CanonicalVT = VTys[SplatSize-1];
-   
-  // If this is a non-canonical splat for this value, 
-  if (Op.getValueType() != CanonicalVT || HasAnyUndefs) {
-SDOperand Elt = DAG.getConstant(SplatBits, 
-MVT::getVectorBaseType(CanonicalVT));
-std::vector Ops(MVT::getVectorNumElements(CanonicalVT), 
Elt);
-SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT, Ops);
-Op = DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
-  }
-  return Op;
-}
+if (SextVal >= -16 && SextVal <= 15)
+  return BuildSplatI(SextVal, SplatSize, Op.getValueType(), DAG);
 
+// If this value is in the range [-32,30] and is even, use:
+//tmp = VSPLTI[bhw], result = add tmp, tmp
+if (SextVal >= -32 && SextVal <= 30 && (SextVal & 1) == 0) {
+  Op = BuildSplatI(SextVal >> 1, SplatSize, Op.getValueType(), DAG);
+  return DAG.getNode(ISD::ADD, Op.getValueType(), Op, Op);
+}
+
 
 // If this is 0x8000_ x 4, turn into vspltisw + vslw.  If it is 
 // 0x7FFF_ x 4, turn it into not(0x8000_).  These are important



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll

2006-04-16 Thread Chris Lattner


Changes in directory llvm/test/Regression/CodeGen/PowerPC:

vec_constants.ll updated: 1.2 -> 1.3
---
Log message:

new testcase


---
Diffs of the changes:  (+5 -1)

 vec_constants.ll |6 +-
 1 files changed, 5 insertions(+), 1 deletion(-)


Index: llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll
diff -u llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.2 
llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.3
--- llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.2   Mon Apr 17 
00:58:22 2006
+++ llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll   Mon Apr 17 
01:06:50 2006
@@ -18,6 +18,10 @@
 ret void
 }
 
-<4 x int> %test2() {
+<4 x int> %test_30() {
 ret <4 x int> 
 }
+
+<4 x int> %test_29() {
+ret <4 x int> 
+}



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.156 -> 1.157
---
Log message:

Learn how to make odd splatted constants in range [17,29].  This implements
PowerPC/vec_constants.ll:test_29.


---
Diffs of the changes:  (+7 -0)

 PPCISelLowering.cpp |7 +++
 1 files changed, 7 insertions(+)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.156 
llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.157
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.156   Mon Apr 17 01:00:21 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Apr 17 01:07:44 2006
@@ -1105,6 +1105,13 @@
   Op = BuildSplatI(SextVal >> 1, SplatSize, Op.getValueType(), DAG);
   return DAG.getNode(ISD::ADD, Op.getValueType(), Op, Op);
 }
+// Otherwise, in range [17,29]:  (vsplti 15) + (vsplti C).
+if (SextVal >= 0 && SextVal <= 29) {
+  SDOperand LHS = BuildSplatI(15, SplatSize, Op.getValueType(), DAG);
+  SDOperand RHS = BuildSplatI(SextVal-15, SplatSize, 
Op.getValueType(),DAG);
+  return DAG.getNode(ISD::ADD, Op.getValueType(), LHS, RHS);
+  
+}
 
 
 // If this is 0x8000_ x 4, turn into vspltisw + vslw.  If it is 



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll

2006-04-16 Thread Chris Lattner


Changes in directory llvm/test/Regression/CodeGen/PowerPC:

vec_constants.ll updated: 1.3 -> 1.4
---
Log message:

New testcases


---
Diffs of the changes:  (+12 -0)

 vec_constants.ll |   12 
 1 files changed, 12 insertions(+)


Index: llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll
diff -u llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.3 
llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.4
--- llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll:1.3   Mon Apr 17 
01:06:50 2006
+++ llvm/test/Regression/CodeGen/PowerPC/vec_constants.ll   Mon Apr 17 
01:58:16 2006
@@ -25,3 +25,15 @@
 <4 x int> %test_29() {
 ret <4 x int> 
 }
+
+<8 x short> %test_n30() {
+ret <8 x short> 
+}
+
+<16 x sbyte> %test_n104() {
+ret <16 x sbyte> 
+}



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp

2006-04-16 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.157 -> 1.158
---
Log message:

Make some code more general, adding support for constant formation of several
new patterns.


---
Diffs of the changes:  (+78 -22)

 PPCISelLowering.cpp |  100 
 1 files changed, 78 insertions(+), 22 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.157 
llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.158
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.157   Mon Apr 17 01:07:44 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Apr 17 01:58:41 2006
@@ -1046,6 +1046,10 @@
 static SDOperand BuildSplatI(int Val, unsigned SplatSize, MVT::ValueType VT,
  SelectionDAG &DAG) {
   assert(Val >= -16 && Val <= 15 && "vsplti is out of range!");
+  
+  // Force vspltis[hw] -1 to vspltisb -1.
+  if (Val == -1) SplatSize = 1;
+  
   static const MVT::ValueType VTys[] = { // canonical VT to use for each size.
 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
   };
@@ -1058,6 +1062,14 @@
   return DAG.getNode(ISD::BIT_CONVERT, VT, Res);
 }
 
+/// BuildIntrinsicBinOp - Return a binary operator intrinsic node with the
+/// specified intrinsic ID.
+static SDOperand BuildIntrinsicBinOp(unsigned IID, SDOperand LHS, SDOperand 
RHS,
+ SelectionDAG &DAG) {
+  return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, LHS.getValueType(),
+ DAG.getConstant(IID, MVT::i32), LHS, RHS);
+}
+
 // If this is a case we can't handle, return null and let the default
 // expansion code take care of it.  If we CAN select this case, and if it
 // selects to a single instruction, return Op.  Otherwise, if we can codegen
@@ -1105,37 +1117,81 @@
   Op = BuildSplatI(SextVal >> 1, SplatSize, Op.getValueType(), DAG);
   return DAG.getNode(ISD::ADD, Op.getValueType(), Op, Op);
 }
-// Otherwise, in range [17,29]:  (vsplti 15) + (vsplti C).
-if (SextVal >= 0 && SextVal <= 29) {
-  SDOperand LHS = BuildSplatI(15, SplatSize, Op.getValueType(), DAG);
-  SDOperand RHS = BuildSplatI(SextVal-15, SplatSize, 
Op.getValueType(),DAG);
-  return DAG.getNode(ISD::ADD, Op.getValueType(), LHS, RHS);
-  
-}
-
 
 // If this is 0x8000_ x 4, turn into vspltisw + vslw.  If it is 
-// 0x7FFF_ x 4, turn it into not(0x8000_).  These are important
+// 0x7FFF_ x 4, turn it into not(0x8000_).  This is important
 // for fneg/fabs.
-if (SplatSize == 4 &&
-SplatBits == 0x8000 || SplatBits == (0x7FFF&~SplatUndef)) {
+if (SplatSize == 4 && SplatBits == (0x7FFF&~SplatUndef)) {
   // Make -1 and vspltisw -1:
-  SDOperand OnesI = DAG.getConstant(~0U, MVT::i32);
-  SDOperand OnesV = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
-OnesI, OnesI, OnesI, OnesI);
+  SDOperand OnesV = BuildSplatI(-1, 4, MVT::v4i32, DAG);
   
   // Make the VSLW intrinsic, computing 0x8000_.
-  SDOperand Res
-= DAG.getNode(ISD::INTRINSIC_WO_CHAIN, MVT::v4i32,
-  DAG.getConstant(Intrinsic::ppc_altivec_vslw, MVT::i32),
-  OnesV, OnesV);
-  
-  // If this is 0x7FFF_, xor by OnesV to invert it.
-  if (SplatBits == 0x8000)
-Res = DAG.getNode(ISD::XOR, MVT::v4i32, Res, OnesV);
+  SDOperand Res = BuildIntrinsicBinOp(Intrinsic::ppc_altivec_vslw, OnesV, 
+  OnesV, DAG);
   
+  // xor by OnesV to invert it.
+  Res = DAG.getNode(ISD::XOR, MVT::v4i32, Res, OnesV);
   return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
 }
+
+// Check to see if this is a wide variety of vsplti*, binop self cases.
+unsigned SplatBitSize = SplatSize*8;
+static const char SplatCsts[] = {
+  -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
+  -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 14, -15
+};
+for (unsigned idx = 0; idx < sizeof(SplatCsts)/sizeof(SplatCsts[0]); 
++idx){
+  // Indirect through the SplatCsts array so that we favor 'vsplti -1' for
+  // cases which are ambiguous (e.g. formation of 0x8000_).  'vsplti 
-1'
+  int i = SplatCsts[idx];
+  
+  // Figure out what shift amount will be used by altivec if shifted by i 
in
+  // this splat size.
+  unsigned TypeShiftAmt = i & (SplatBitSize-1);
+  
+  // vsplti + shl self.
+  if (SextVal == (i << (int)TypeShiftAmt)) {
+Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+static const unsigned IIDs[] = { // Intrinsic to use for each size.
+  Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
+  Intrinsic::ppc_altivec_vslw
+};
+return BuildIntrinsicBinOp(IIDs[SplatSize-1], Op, Op, DAG);
+  }
+  
+  // vsplti + srl self.
+