[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2005-10-25 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.119 -> 1.120
PPCInstrInfo.td updated: 1.133 -> 1.134
---
Log message:

Autogen a few new ppc-specific nodes


---
Diffs of the changes:  (+11 -15)

 PPCISelDAGToDAG.cpp |   12 
 PPCInstrInfo.td |   14 +++---
 2 files changed, 11 insertions(+), 15 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.119 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.120
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.119   Tue Oct 25 15:36:10 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Oct 25 15:41:46 2005
@@ -903,18 +903,6 @@
  Select(N->getOperand(1)), Select(N->getOperand(2)));
 return SDOperand(N, 0);
   }
-  case PPCISD::FCFID:
-CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0),
- Select(N->getOperand(0)));
-return SDOperand(N, 0);
-  case PPCISD::FCTIDZ:
-CurDAG->SelectNodeTo(N, PPC::FCTIDZ, N->getValueType(0),
- Select(N->getOperand(0)));
-return SDOperand(N, 0);
-  case PPCISD::FCTIWZ:
-CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0),
- Select(N->getOperand(0)));
-return SDOperand(N, 0);
   case ISD::FADD: {
 MVT::ValueType Ty = N->getValueType(0);
 if (!NoExcessFPPrecision) {  // Match FMA ops


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.133 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.134
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.133   Fri Oct 21 16:17:10 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Tue Oct 25 15:41:46 2005
@@ -14,6 +14,14 @@
 
 include "PPCInstrFormats.td"
 
+//===--===//
+// PowerPC specific DAG Nodes.
+//
+
+def PPCfcfid  : SDNode<"PPCISD::FCFID" , SDTFPUnaryOp, []>;
+def PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>;
+def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>;
+
 
 
//===--===//
 // PowerPC specific transformation functions and pattern fragments.
@@ -449,13 +457,13 @@
 }
 def FCFID  : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB),
   "fcfid $frD, $frB", FPGeneral,
-  []>, isPPC64;
+  [(set F8RC:$frD, (PPCfcfid F8RC:$frB))]>, isPPC64;
 def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB),
   "fctidz $frD, $frB", FPGeneral,
-  []>, isPPC64;
+  [(set F8RC:$frD, (PPCfctidz F8RC:$frB))]>, isPPC64;
 def FCTIWZ : XForm_26<63, 15, (ops F8RC:$frD, F8RC:$frB),
   "fctiwz $frD, $frB", FPGeneral,
-  []>;
+  [(set F8RC:$frD, (PPCfctiwz F8RC:$frB))]>;
 def FRSP   : XForm_26<63, 12, (ops F4RC:$frD, F8RC:$frB),
   "frsp $frD, $frB", FPGeneral,
   [(set F4RC:$frD, (fround F8RC:$frB))]>;



___
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/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2005-10-25 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.120 -> 1.121
PPCInstrInfo.td updated: 1.134 -> 1.135
---
Log message:

Autogen fsel


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

 PPCISelDAGToDAG.cpp |   12 
 PPCInstrInfo.td |8 ++--
 2 files changed, 6 insertions(+), 14 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.120 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.121
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.120   Tue Oct 25 15:41:46 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Oct 25 15:55:47 2005
@@ -891,18 +891,6 @@
 else
   return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, GA);
   }
-
-  case PPCISD::FSEL: {
-SDOperand Comparison = Select(N->getOperand(0));
-// Extend the comparison to 64-bits.
-if (Comparison.getValueType() == MVT::f32)
-  Comparison = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Comparison);
-
-unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FSELS : PPC::FSELD;
-CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Comparison,
- Select(N->getOperand(1)), Select(N->getOperand(2)));
-return SDOperand(N, 0);
-  }
   case ISD::FADD: {
 MVT::ValueType Ty = N->getValueType(0);
 if (!NoExcessFPPrecision) {  // Match FMA ops


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.134 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.135
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.134   Tue Oct 25 15:41:46 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Tue Oct 25 15:55:47 2005
@@ -22,6 +22,10 @@
 def PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>;
 def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>;
 
+def PPCfsel   : SDNode<"PPCISD::FSEL",  
+   // Type constraint for fsel.
+   SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, 
+SDTCisFP<0>, SDTCisVT<1, f64>]>, []>;
 
 
//===--===//
 // PowerPC specific transformation functions and pattern fragments.
@@ -654,11 +658,11 @@
 def FSELD : AForm_1<63, 23,
 (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
 "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral,
-[]>;
+[(set F8RC:$FRT, (PPCfsel 
F8RC:$FRA,F8RC:$FRC,F8RC:$FRB))]>;
 def FSELS : AForm_1<63, 23,
  (ops F4RC:$FRT, F8RC:$FRA, F4RC:$FRC, F4RC:$FRB),
  "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral,
- []>;
+[(set F4RC:$FRT, (PPCfsel 
F8RC:$FRA,F4RC:$FRC,F4RC:$FRB))]>;
 def FADD  : AForm_2<63, 21,
 (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
 "fadd $FRT, $FRA, $FRB", FPGeneral,



___
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/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2005-10-25 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.121 -> 1.122
PPCInstrInfo.td updated: 1.136 -> 1.137
---
Log message:

autogen undef


---
Diffs of the changes:  (+6 -11)

 PPCISelDAGToDAG.cpp |8 
 PPCInstrInfo.td |9 ++---
 2 files changed, 6 insertions(+), 11 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.121 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.122
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.121   Tue Oct 25 15:55:47 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Oct 25 16:03:41 2005
@@ -844,14 +844,6 @@
   case ISD::CALL:   return SelectCALL(Op);
   case ISD::TAILCALL:   return SelectCALL(Op);
 
-  case ISD::UNDEF:
-if (N->getValueType(0) == MVT::i32)
-  CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32);
-else if (N->getValueType(0) == MVT::f32)
-  CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32);
-else 
-  CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64);
-return SDOperand(N, 0);
   case ISD::FrameIndex: {
 int FI = cast(N)->getIndex();
 if (N->hasOneUse()) {


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.136 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.137
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.136   Tue Oct 25 15:58:43 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Tue Oct 25 16:03:41 2005
@@ -153,9 +153,12 @@
 def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKDOWN", []>;
 def ADJCALLSTACKUP : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKUP", []>;
 }
-def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC", []>;
-def IMPLICIT_DEF_F8  : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8", []>;
-def IMPLICIT_DEF_F4  : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4", []>;
+def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC",
+  [(set GPRC:$rD, (undef))]>;
+def IMPLICIT_DEF_F8  : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8",
+  [(set F8RC:$rD, (undef))]>;
+def IMPLICIT_DEF_F4  : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4",
+  [(set F4RC:$rD, (undef))]>;
 
 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by 
the
 // scheduler into a branch sequence.



___
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/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2005-10-28 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.122 -> 1.123
PPCInstrInfo.td updated: 1.137 -> 1.138
---
Log message:

add support for branch on ordered/unordered.


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

 PPCISelDAGToDAG.cpp |   17 +
 PPCInstrInfo.td |4 
 2 files changed, 21 insertions(+)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.122 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.123
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.122   Tue Oct 25 16:03:41 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Oct 28 15:32:44 2005
@@ -489,6 +489,15 @@
   case ISD::SETGT:  return PPC::BGT;
   case ISD::SETUGE:
   case ISD::SETGE:  return PPC::BGE;
+
+  case ISD::SETO:   return PPC::BUN;
+  case ISD::SETUO:  return PPC::BNU;
+  case ISD::SETOEQ:
+  case ISD::SETOGT:
+  case ISD::SETOGE:
+  case ISD::SETOLT:
+  case ISD::SETOLE:
+  case ISD::SETONE: assert(0 && "Unknown condition!"); abort();
   }
   return 0;
 }
@@ -509,6 +518,14 @@
   case ISD::SETLE:  Inv = true;   return 1;
   case ISD::SETEQ:  Inv = false;  return 2;
   case ISD::SETNE:  Inv = true;   return 2;
+  case ISD::SETO:   Inv = true;   return 3;
+  case ISD::SETUO:  Inv = false;  return 3;
+  case ISD::SETOEQ:
+  case ISD::SETOGT:
+  case ISD::SETOGE:
+  case ISD::SETOLT:
+  case ISD::SETOLE:
+  case ISD::SETONE: assert(0 && "Unknown condition!"); abort();
   }
   return 0;
 }


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.137 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.138
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.137   Tue Oct 25 16:03:41 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Fri Oct 28 15:32:44 2005
@@ -204,6 +204,10 @@
   "bgt $crS, $block", BrB>;
   def BNE : BForm<16, 0, 0, 4,  2, (ops CRRC:$crS, target:$block),
   "bne $crS, $block", BrB>;
+  def BUN : BForm<16, 0, 0, 12, 3, (ops CRRC:$crS, target:$block),
+  "bun $crS, $block", BrB>;
+  def BNU : BForm<16, 0, 0, 4,  3, (ops CRRC:$crS, target:$block),
+  "bnu $crS, $block", BrB>;
 }
 
 let isCall = 1, 



___
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/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2005-12-14 Thread Nate Begeman


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.140 -> 1.141
PPCInstrInfo.td updated: 1.158 -> 1.159
---
Log message:

Use the new predicate support that Evan Cheng added to remove some code
from the DAGToDAG cpp file.  This adds pattern support for vector and
scalar fma, which passes test/Regression/CodeGen/PowerPC/fma.ll, and 
does the right thing in the presence of -disable-excess-fp-precision.

Allows us to match:
void %foo(<4 x float> * %a) {
entry:
  %tmp1 = load <4 x float> * %a;
  %tmp2 = mul <4 x float> %tmp1, %tmp1
  %tmp3 = add <4 x float> %tmp2, %tmp1
  store <4 x float> %tmp3, <4 x float> *%a
  ret void
}

As:

_foo:
li r2, 0
lvx v0, r2, r3
vmaddfp v0, v0, v0, v0
stvx v0, r2, r3
blr

Or, with llc -disable-excess-fp-precision,

_foo:
li r2, 0
lvx v0, r2, r3
vxor v1, v1, v1
vmaddfp v1, v0, v0, v1
vaddfp v0, v1, v0
stvx v0, r2, r3
blr


---
Diffs of the changes:  (+24 -57)

 PPCISelDAGToDAG.cpp |   47 ---
 PPCInstrInfo.td |   34 --
 2 files changed, 24 insertions(+), 57 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.140 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.141
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.140   Fri Dec  9 20:36:00 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed Dec 14 16:54:33 2005
@@ -885,53 +885,6 @@
 CurDAG->getTargetFrameIndex(FI, MVT::i32),
 getI32Imm(0));
   }
-  case ISD::FADD: {
-MVT::ValueType Ty = N->getValueType(0);
-if (!NoExcessFPPrecision) {  // Match FMA ops
-  if (N->getOperand(0).getOpcode() == ISD::FMUL &&
-  N->getOperand(0).Val->hasOneUse()) {
-++FusedFP; // Statistic
-return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD 
:PPC::FMADDS,
-Ty, Select(N->getOperand(0).getOperand(0)),
-Select(N->getOperand(0).getOperand(1)),
-Select(N->getOperand(1)));
-  } else if (N->getOperand(1).getOpcode() == ISD::FMUL &&
- N->getOperand(1).hasOneUse()) {
-++FusedFP; // Statistic
-return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD 
:PPC::FMADDS,
-Ty, Select(N->getOperand(1).getOperand(0)),
-Select(N->getOperand(1).getOperand(1)),
-Select(N->getOperand(0)));
-  }
-}
-
-// Other cases are autogenerated.
-break;
-  }
-  case ISD::FSUB: {
-MVT::ValueType Ty = N->getValueType(0);
-
-if (!NoExcessFPPrecision) {  // Match FMA ops
-  if (N->getOperand(0).getOpcode() == ISD::FMUL &&
-  N->getOperand(0).Val->hasOneUse()) {
-++FusedFP; // Statistic
-return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMSUB:PPC::FMSUBS,
-Ty, Select(N->getOperand(0).getOperand(0)),
-Select(N->getOperand(0).getOperand(1)),
-Select(N->getOperand(1)));
-  } else if (N->getOperand(1).getOpcode() == ISD::FMUL &&
- N->getOperand(1).Val->hasOneUse()) {
-++FusedFP; // Statistic
-return CurDAG->SelectNodeTo(N, Ty == MVT::f64 
?PPC::FNMSUB:PPC::FNMSUBS, 
-Ty, Select(N->getOperand(1).getOperand(0)),
-Select(N->getOperand(1).getOperand(1)),
-Select(N->getOperand(0)));
-  }
-}
-
-// Other cases are autogenerated.
-break;
-  }
   case ISD::SDIV: {
 // FIXME: since this depends on the setting of the carry flag from the 
srawi
 //we should really be making notes about that for the scheduler.


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.158 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.159
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.158   Wed Dec 14 16:07:12 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Wed Dec 14 16:54:33 2005
@@ -168,7 +168,7 @@
 
 
//===--===//
 // PowerPC Instruction Predicate Definitions.
-def FPContractions : Predicate<"!NoExcessFPPrecision">;
+def FPContractions : Predicate<"NoExcessFPPrecision">;
 
 
//===--===//
 // PowerPC Instruction Definitions.
@@ -746,22 +746,26 @@
 (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
 "fnmadd $FRT, $FRA, $FRC, $FRB", FPFused,
 [(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC),
-  

[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2006-02-16 Thread Nate Begeman


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.158 -> 1.159
PPCInstrInfo.td updated: 1.176 -> 1.177
---
Log message:

kill ADD_PARTS & SUB_PARTS and replace them with fancy new ADDC, ADDE, SUBC
and SUBE nodes that actually expose what's going on and allow for 
significant simplifications in the targets.


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

 PPCISelDAGToDAG.cpp |   75 
 PPCInstrInfo.td |   22 +--
 2 files changed, 14 insertions(+), 83 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.158 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.159
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.158   Thu Feb 16 02:27:56 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Feb 16 23:43:56 2006
@@ -535,75 +535,6 @@
   return 0;
 }
 
-
-SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
-  SDNode *N = Op.Val;
-  SDOperand LHSL, LHSH;
-  Select(LHSL, N->getOperand(0));
-  Select(LHSH, N->getOperand(1));
-  
-  unsigned Imm;
-  bool ME = false, ZE = false;
-  if (isIntImmediate(N->getOperand(3), Imm)) {
-ME = (signed)Imm == -1;
-ZE = Imm == 0;
-  }
-  
-  std::vector Result;
-  SDOperand Tmp;
-  SDNode *CarryFromLo;
-  if (isIntImmediate(N->getOperand(2), Imm) &&
-  ((signed)Imm >= -32768 || (signed)Imm < 32768)) {
-// Codegen the low 32 bits of the add.  Interestingly, there is no
-// shifted form of add immediate carrying.
-CarryFromLo = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
-LHSL, getI32Imm(Imm));
-  } else {
-Select(Tmp, N->getOperand(2));
-CarryFromLo = CurDAG->getTargetNode(PPC::ADDC, MVT::i32, MVT::Flag,
-LHSL, Tmp);
-  }
-  
-  // Codegen the high 32 bits, adding zero, minus one, or the full value
-  // along with the carry flag produced by addc/addic.
-  SDOperand ResultHi;
-  if (ZE)
-ResultHi = SDOperand(CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, LHSH,
-   SDOperand(CarryFromLo, 1)), 0);
-  else if (ME)
-ResultHi = SDOperand(CurDAG->getTargetNode(PPC::ADDME, MVT::i32, LHSH,
-   SDOperand(CarryFromLo, 1)), 0);
-  else {
-Select(Tmp, N->getOperand(3));
-ResultHi = SDOperand(CurDAG->getTargetNode(PPC::ADDE, MVT::i32, LHSH,
-Tmp, SDOperand(CarryFromLo, 1)), 
0);
-  }
-  Result.push_back(SDOperand(CarryFromLo, 0));
-  Result.push_back(ResultHi);
-  
-  CodeGenMap[Op.getValue(0)] = Result[0];
-  CodeGenMap[Op.getValue(1)] = Result[1];
-  return Result[Op.ResNo];
-}
-SDOperand PPCDAGToDAGISel::SelectSUB_PARTS(SDOperand Op) {
-  SDNode *N = Op.Val;
-  SDOperand LHSL, LHSH, RHSL, RHSH;
-  Select(LHSL, N->getOperand(0));
-  Select(LHSH, N->getOperand(1));
-  Select(RHSL, N->getOperand(2));
-  Select(RHSH, N->getOperand(3));
-  
-  std::vector Result;
-  Result.push_back(SDOperand(CurDAG->getTargetNode(PPC::SUBFC, MVT::i32,
-   MVT::Flag, RHSL, LHSL), 0));
-  Result.push_back(SDOperand(CurDAG->getTargetNode(PPC::SUBFE, MVT::i32,
-   RHSH, LHSH,
-   Result[0].getValue(1)), 0));
-  CodeGenMap[Op.getValue(0)] = Result[0];
-  CodeGenMap[Op.getValue(1)] = Result[1];
-  return Result[Op.ResNo];
-}
-
 SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
   SDNode *N = Op.Val;
   unsigned Imm;
@@ -846,12 +777,6 @@
   
   switch (N->getOpcode()) {
   default: break;
-  case ISD::ADD_PARTS:
-Result = SelectADD_PARTS(Op);
-return;
-  case ISD::SUB_PARTS:
-Result = SelectSUB_PARTS(Op);
-return;
   case ISD::SETCC:
 Result = SelectSETCC(Op);
 return;


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.176 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.177
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.176   Sun Feb 12 03:09:52 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Thu Feb 16 23:43:56 2006
@@ -302,7 +302,7 @@
  [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>;
 def ADDIC  : DForm_2<12, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
  "addic $rD, $rA, $imm", IntGeneral,
- []>;
+ [(set GPRC:$rD, (addc GPRC:$rA, immSExt16:$imm))]>;
 def ADDICo : DForm_2<13, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
  "addic. $rD, $rA, $imm", IntGeneral,
  []>;
@@ -684,10 +684,10 @@
  [(set G8RC:$rT, (add G8RC:$rA, G8RC:$rB))]>;
 def ADDC  : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
  "addc $rT, $rA, $rB", IntGeneral,
- []>;
+ [(set GPRC:$rT, (addc GPRC:$rA, GPRC:$rB))]>;

[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2006-03-20 Thread Evan Cheng


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.170 -> 1.171
PPCInstrInfo.td updated: 1.197 -> 1.198
---
Log message:

Use tblgen'd VECTOR_SHUFFLE selection code.

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

 PPCISelDAGToDAG.cpp |   16 
 PPCInstrInfo.td |5 ++---
 2 files changed, 2 insertions(+), 19 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.170 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.171
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.170   Mon Mar 20 00:51:10 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon Mar 20 02:14:16 2006
@@ -927,22 +927,6 @@
   
   switch (N->getOpcode()) {
   default: break;
-  case ISD::VECTOR_SHUFFLE:
-// FIXME: This should be autogenerated from the .td file, it is here for 
now
-// due to bugs in tblgen.
-if (Op.getOperand(1).getOpcode() == ISD::UNDEF &&
-(Op.getValueType() == MVT::v4f32 || Op.getValueType() == MVT::v4i32) &&
-PPC::isSplatShuffleMask(Op.getOperand(2).Val)) {
-  SDOperand N0;
-  Select(N0, N->getOperand(0));
-
-  Result = CodeGenMap[Op] = 
-SDOperand(CurDAG->getTargetNode(PPC::VSPLTW, MVT::v4f32,
-  getI32Imm(PPC::getVSPLTImmediate(Op.getOperand(2).Val)),
-N0), 0);
-  return;
-}
-assert(0 && "ILLEGAL VECTOR_SHUFFLE!");
   case ISD::SETCC:
 Result = SelectSETCC(Op);
 return;


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.197 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.198
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.197   Mon Mar 20 00:51:10 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Mon Mar 20 02:14:16 2006
@@ -1034,9 +1034,8 @@
   
 def VSPLTW : VXForm_1<652, (ops VRRC:$vD, u5imm:$UIMM, VRRC:$vB),
   "vspltw $vD, $vB, $UIMM", VecPerm,
-  [/*
-   (set VRRC:$vD, (vector_shuffle (v4f32 VRRC:$vB), 
(undef),
-  VSPLT_shuffle_mask:$UIMM))*/]>;
+  [(set VRRC:$vD, (vector_shuffle (v4f32 VRRC:$vB), 
(undef),
+  VSPLT_shuffle_mask:$UIMM))]>;
   // FIXME: ALSO ADD SUPPORT FOR v4i32!
   
 // VX-Form Pseudo Instructions



___
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/PPCISelDAGToDAG.cpp PPCInstrInfo.td

2006-11-15 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.220 -> 1.221
PPCInstrInfo.td updated: 1.263 -> 1.264
---
Log message:

add patterns for ppc32 preinc stores.  ppc64 next.


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

 PPCISelDAGToDAG.cpp |8 
 PPCInstrInfo.td |   21 ++---
 2 files changed, 22 insertions(+), 7 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.220 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.221
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.220   Wed Nov 15 13:55:13 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed Nov 15 18:41:37 2006
@@ -108,6 +108,14 @@
SDOperand &Base) {
   return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG);
 }
+
+/// SelectAddrImmOffs - Return true if the operand is valid for a preinc
+/// immediate field.  Because preinc imms have already been validated, just
+/// accept it.
+bool SelectAddrImmOffs(SDOperand Op, SDOperand N, SDOperand &Out) const {
+  Out = N;
+  return true;
+}
   
 /// SelectAddrIdx - Given the specified addressed, check to see if it can 
be
 /// represented as an indexed [r+r] operation.  Returns false if it can


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.263 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.264
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.263   Wed Nov 15 18:33:34 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Wed Nov 15 18:41:37 2006
@@ -273,6 +273,8 @@
 def xoaddr : ComplexPattern;
 def ixaddr : ComplexPattern; // "std"
 
+/// This is just the offset part of iaddr, used for preinc.
+def iaddroff : ComplexPattern;
 
 
//===--===//
 // PowerPC Instruction Predicate Definitions.
@@ -531,29 +533,34 @@
 def STBU  : DForm_1<39, (ops ptr_rc:$ea_res, GPRC:$rS,
  symbolLo:$ptroff, ptr_rc:$ptrreg),
 "stbu $rS, $ptroff($ptrreg)", LdStGeneral,
-[/*(set ptr_rc:$ea_res,
-  (pre_truncsti8 GPRC:$rS, iaddr:$addr))*/]>,
+[(set ptr_rc:$ea_res,
+  (pre_truncsti8 GPRC:$rS, ptr_rc:$ptrreg, 
+ iaddroff:$ptroff))]>,
 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
 def STHU  : DForm_1<37, (ops ptr_rc:$ea_res, GPRC:$rS,
  symbolLo:$ptroff, ptr_rc:$ptrreg),
 "sthu $rS, $ptroff($ptrreg)", LdStGeneral,
-[/*(set ptr_rc:$ea_res,
-  (pre_truncsti16 GPRC:$rS, iaddr:$addr))*/]>,
+[(set ptr_rc:$ea_res,
+(pre_truncsti16 GPRC:$rS, ptr_rc:$ptrreg, 
+iaddroff:$ptroff))]>,
 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
 def STWU  : DForm_1<37, (ops ptr_rc:$ea_res, GPRC:$rS,
  symbolLo:$ptroff, ptr_rc:$ptrreg),
 "stwu $rS, $ptroff($ptrreg)", LdStGeneral,
-[/*(set ptr_rc:$ea_res, (pre_store GPRC:$rS, 
iaddr:$addr))*/]>,
+[(set ptr_rc:$ea_res, (pre_store GPRC:$rS, ptr_rc:$ptrreg, 
+ iaddroff:$ptroff))]>,
 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
 def STFSU : DForm_1<37, (ops ptr_rc:$ea_res, F4RC:$rS,
  symbolLo:$ptroff, ptr_rc:$ptrreg),
 "stfsu $rS, $ptroff($ptrreg)", LdStGeneral,
-[/*(set ptr_rc:$ea_res, (pre_store F4RC:$rS, 
iaddr:$addr))*/]>,
+[(set ptr_rc:$ea_res, (pre_store F4RC:$rS,  
ptr_rc:$ptrreg, 
+  iaddroff:$ptroff))]>,
 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
 def STFDU : DForm_1<37, (ops ptr_rc:$ea_res, F8RC:$rS,
  symbolLo:$ptroff, ptr_rc:$ptrreg),
 "stfdu $rS, $ptroff($ptrreg)", LdStGeneral,
-[/*(set ptr_rc:$ea_res, (pre_store F8RC:$rS, 
iaddr:$addr))*/]>,
+[(set ptr_rc:$ea_res, (pre_store F8RC:$rS, ptr_rc:$ptrreg, 
+  iaddroff:$ptroff))]>,
 RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">;
 }
 



___
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/PPCISelDAGToDAG.cpp PPCInstrInfo.td README.txt

2006-09-21 Thread Nate Begeman


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.210 -> 1.211
PPCInstrInfo.td updated: 1.241 -> 1.242
README.txt updated: 1.99 -> 1.100
---
Log message:

Fold AND and ROTL more often


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

 PPCISelDAGToDAG.cpp |   66 +---
 PPCInstrInfo.td |   24 ++
 README.txt  |   34 --
 3 files changed, 62 insertions(+), 62 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.210 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.211
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.210   Tue Sep 19 23:33:27 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Fri Sep 22 00:01:56 2006
@@ -76,6 +76,17 @@
   return CurDAG->getTargetConstant(Imm, PPCLowering.getPointerTy());
 }
 
+/// isRunOfOnes - Returns true iff Val consists of one contiguous run of 
1s 
+/// with any number of 0s on either side.  The 1s are allowed to wrap from
+/// LSB to MSB, so 0x000FFF0, 0x, and 0xFFFF are all runs.
+/// 0x0F0F is not, since all 1s are not contiguous.
+static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME);
+
+
+/// isRotateAndMask - Returns true if Mask and Shift can be folded into a
+/// rotate and mask opcode and mask operation.
+static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask,
+unsigned &SH, unsigned &MB, unsigned &ME);
 
 /// getGlobalBaseReg - insert code into the entry mbb to materialize the 
PIC
 /// base register.  Return the virtual register that holds this value.
@@ -324,12 +335,7 @@
   return N->getOpcode() == Opc && isInt32Immediate(N->getOperand(1).Val, Imm);
 }
 
-
-// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s with
-// any number of 0s on either side.  The 1s are allowed to wrap from LSB to
-// MSB, so 0x000FFF0, 0x, and 0xFFFF are all runs.  0x0F0F is
-// not, since all 1s are not contiguous.
-static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
+bool PPCDAGToDAGISel::isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
   if (isShiftedMask_32(Val)) {
 // look for the first non-zero bit
 MB = CountLeadingZeros_32(Val);
@@ -350,10 +356,9 @@
   return false;
 }
 
-// isRotateAndMask - Returns true if Mask and Shift can be folded into a rotate
-// and mask opcode and mask operation.
-static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask,
-unsigned &SH, unsigned &MB, unsigned &ME) {
+bool PPCDAGToDAGISel::isRotateAndMask(SDNode *N, unsigned Mask, 
+  bool IsShiftMask, unsigned &SH, 
+  unsigned &MB, unsigned &ME) {
   // Don't even go down this path for i64, since different logic will be
   // necessary for rldicl/rldicr/rldimi.
   if (N->getValueType(0) != MVT::i32)
@@ -378,6 +383,8 @@
 Indeterminant = ~(0xu >> Shift);
 // adjust for the left rotate
 Shift = 32 - Shift;
+  } else if (Opcode == ISD::ROTL) {
+Indeterminant = 0;
   } else {
 return false;
   }
@@ -1024,30 +1031,33 @@
 break;
   }
   case ISD::AND: {
-unsigned Imm, Imm2;
+unsigned Imm, Imm2, SH, MB, ME;
+
 // If this is an and of a value rotated between 0 and 31 bits and then 
and'd
 // with a mask, emit rlwinm
 if (isInt32Immediate(N->getOperand(1), Imm) &&
-(isShiftedMask_32(Imm) || isShiftedMask_32(~Imm))) {
-  SDOperand Val;
-  unsigned SH, MB, ME;
-  if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) {
-Val = N->getOperand(0).getOperand(0);
-AddToISelQueue(Val);
-  } else if (Imm == 0) {
-// AND X, 0 -> 0, not "rlwinm 32".
-AddToISelQueue(N->getOperand(1));
-ReplaceUses(SDOperand(N, 0), N->getOperand(1));
-return NULL;
-  } else {
-Val = N->getOperand(0);
-AddToISelQueue(Val);
-isRunOfOnes(Imm, MB, ME);
-SH = 0;
-  }
+isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) {
+  SDOperand Val = N->getOperand(0).getOperand(0);
+  AddToISelQueue(Val);
   SDOperand Ops[] = { Val, getI32Imm(SH), getI32Imm(MB), getI32Imm(ME) };
   return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4);
 }
+// If this is just a masked value where the input is not handled above, and
+// is not a rotate-left (handled by a pattern in the .td file), emit rlwinm
+if (isInt32Immediate(N->getOperand(1), Imm) &&
+isRunOfOnes(Imm, MB, ME) && 
+N->getOperand(0).getOpcode() != ISD::ROTL) {
+  SDOperand Val = N->getOperand(0);
+  AddToISelQueue(Val);
+  SDOperand Ops[] = { Val, getI32Imm(0), getI32Imm(MB), getI32Imm(ME) };
+  return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::

[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCInstrInfo.td PPCRegisterInfo.cpp PPCRegisterInfo.td

2006-03-13 Thread Chris Lattner


Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.164 -> 1.165
PPCInstrInfo.td updated: 1.181 -> 1.182
PPCRegisterInfo.cpp updated: 1.43 -> 1.44
PPCRegisterInfo.td updated: 1.29 -> 1.30
---
Log message:

For functions that use vector registers, save VRSAVE, mark used
registers, and update it on entry to each function, then restore it on exit.

This compiles:

void func(vfloat *a, vfloat *b, vfloat *c) {
*a = *b * *c + *c;
}

to this:

_func:
mfspr r2, 256
oris r6, r2, 49152
mtspr 256: http://llvm.cs.uiuc.edu/PR256 , r6
lvx v0, 0, r5
lvx v1, 0, r4
vmaddfp v0, v1, v0, v0
stvx v0, 0, r3
mtspr 256: http://llvm.cs.uiuc.edu/PR256 , r2
blr

GCC produces this (which has additional stack accesses):

_func:
mfspr r0,256
stw r0,-4(r1)
oris r0,r0,0xc000
mtspr 256: http://llvm.cs.uiuc.edu/PR256 ,r0
lvx v0,0,r5
lvx v1,0,r4
lwz r12,-4(r1)
vmaddfp v0,v0,v1,v0
stvx v0,0,r3
mtspr 256: http://llvm.cs.uiuc.edu/PR256 ,r12
blr



---
Diffs of the changes:  (+130 -10)

 PPCISelDAGToDAG.cpp |   59 +++-
 PPCInstrInfo.td |   26 --
 PPCRegisterInfo.cpp |   51 
 PPCRegisterInfo.td  |4 +--
 4 files changed, 130 insertions(+), 10 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.164 
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.165
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.164   Sun Mar 12 03:13:49 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon Mar 13 15:52:10 2006
@@ -196,8 +196,65 @@
   CodeGenMap.clear();
   DAG.RemoveDeadNodes();
   
-  // Emit machine code to BB. 
+  // Emit machine code to BB.
   ScheduleAndEmitDAG(DAG);
+  
+  // Check to see if this function uses vector registers, which means we have 
to
+  // save and restore the VRSAVE register and update it with the regs we use.  
+  //
+  // In this case, there will be virtual registers of vector type type created
+  // by the scheduler.  Detect them now.
+  SSARegMap *RegMap = DAG.getMachineFunction().getSSARegMap();
+  bool HasVectorVReg = false;
+  for (unsigned i = MRegisterInfo::FirstVirtualRegister, 
+   e = RegMap->getLastVirtReg(); i != e; ++i)
+if (RegMap->getRegClass(i) == &PPC::VRRCRegClass) {
+  HasVectorVReg = true;
+  break;
+}
+  
+  // If we have a vector register, we want to emit code into the entry and exit
+  // blocks to save and restore the VRSAVE register.  We do this here (instead
+  // of marking all vector instructions as clobbering VRSAVE) for two reasons:
+  //
+  // 1. This (trivially) reduces the load on the register allocator, by not
+  //having to represent the live range of the VRSAVE register.
+  // 2. This (more significantly) allows us to create a temporary virtual
+  //register to hold the saved VRSAVE value, allowing this temporary to be
+  //register allocated, instead of forcing it to be spilled to the stack.
+  if (HasVectorVReg) {
+// Create two vregs - one to hold the VRSAVE register that is live-in to 
the
+// function and one for the value after having bits or'd into it.
+unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+
+MachineFunction &MF = DAG.getMachineFunction();
+MachineBasicBlock &EntryBB = *MF.begin();
+// Emit the following code into the entry block:
+// InVRSAVE = MFVRSAVE
+// UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
+// MTVRSAVE UpdatedVRSAVE
+MachineBasicBlock::iterator IP = EntryBB.begin();  // Insert Point
+BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE);
+BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, 
UpdatedVRSAVE).addReg(InVRSAVE);
+BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE);
+
+// Find all return blocks, outputting a restore in each epilog.
+const TargetInstrInfo &TII = *DAG.getTarget().getInstrInfo();
+for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; 
++BB)
+  if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) {
+IP = BB->end(); --IP;
+
+// Skip over all terminator instructions, which are part of the return
+// sequence.
+MachineBasicBlock::iterator I2 = IP;
+while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode()))
+  IP = I2;
+
+// Emit: MTVRSAVE InVRSave
+BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE);
+  }
+  }
 }
 
 /// getGlobalBaseReg - Output the instructions required to put the


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.181 
llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.182
--- llvm/lib/Targe