summaryrefslogtreecommitdiff
path: root/debian/patches/powerpcspe
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2019-12-02 17:06:08 +0300
committerIgor Pashev <pashev.igor@gmail.com>2019-12-02 17:06:08 +0300
commit18583eaa2c6fa769ce80605422fa10a60d353af7 (patch)
tree4b6730afc2006e86ae8b91c8c4cf52b313b5c188 /debian/patches/powerpcspe
downloadllvm-toolchain-8-debian.tar.gz
Import llvm-toolchain-8 (1:8.0.1-4)debian/8.0.1-4debian
Diffstat (limited to 'debian/patches/powerpcspe')
-rw-r--r--debian/patches/powerpcspe/D49754-powerpcspe-clang.diff148
-rw-r--r--debian/patches/powerpcspe/D54409-powerpcspe-register-spilling.diff88
-rw-r--r--debian/patches/powerpcspe/D54584-powerpcspe-double-parameter.diff217
3 files changed, 453 insertions, 0 deletions
diff --git a/debian/patches/powerpcspe/D49754-powerpcspe-clang.diff b/debian/patches/powerpcspe/D49754-powerpcspe-clang.diff
new file mode 100644
index 0000000..13ba9f6
--- /dev/null
+++ b/debian/patches/powerpcspe/D49754-powerpcspe-clang.diff
@@ -0,0 +1,148 @@
+Description: Add -m(no-)spe, and e500 CPU definitions and support to clang
+Author: Justin Hibbits <jrh29@alumni.cwru.edu>
+Origin: https://reviews.llvm.org/D49754
+Last-Update: 2018-12-04
+
+Index: llvm-toolchain-snapshot_8~svn349138/clang/include/clang/Driver/Options.td
+===================================================================
+--- llvm-toolchain-snapshot_8~svn349138.orig/clang/include/clang/Driver/Options.td
++++ llvm-toolchain-snapshot_8~svn349138/clang/include/clang/Driver/Options.td
+@@ -2142,6 +2142,8 @@ def faltivec : Flag<["-"], "faltivec">,
+ def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[DriverOption]>;
+ def maltivec : Flag<["-"], "maltivec">, Group<m_ppc_Features_Group>;
+ def mno_altivec : Flag<["-"], "mno-altivec">, Group<m_ppc_Features_Group>;
++def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
++def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
+ def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
+ def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
+ def msecure_plt : Flag<["-"], "msecure-plt">, Group<m_ppc_Features_Group>;
+Index: llvm-toolchain-snapshot_8~svn349138/clang/lib/Basic/Targets/PPC.cpp
+===================================================================
+--- llvm-toolchain-snapshot_8~svn349138.orig/clang/lib/Basic/Targets/PPC.cpp
++++ llvm-toolchain-snapshot_8~svn349138/clang/lib/Basic/Targets/PPC.cpp
+@@ -54,6 +54,8 @@ bool PPCTargetInfo::handleTargetFeatures
+ HasFloat128 = true;
+ } else if (Feature == "+power9-vector") {
+ HasP9Vector = true;
++ } else if (Feature == "+spe") {
++ HasSPE = true;
+ }
+ // TODO: Finish this list and add an assert that we've handled them
+ // all.
+@@ -161,6 +163,8 @@ void PPCTargetInfo::getTargetDefines(con
+ Builder.defineMacro("__VEC__", "10206");
+ Builder.defineMacro("__ALTIVEC__");
+ }
++ if (HasSPE)
++ Builder.defineMacro("__SPE__");
+ if (HasVSX)
+ Builder.defineMacro("__VSX__");
+ if (HasP8Vector)
+@@ -334,6 +338,7 @@ bool PPCTargetInfo::hasFeature(StringRef
+ .Case("extdiv", HasExtDiv)
+ .Case("float128", HasFloat128)
+ .Case("power9-vector", HasP9Vector)
++ .Case("spe", HasSPE)
+ .Default(false);
+ }
+
+@@ -443,16 +448,16 @@ ArrayRef<TargetInfo::AddlRegName> PPCTar
+ }
+
+ static constexpr llvm::StringLiteral ValidCPUNames[] = {
+- {"generic"}, {"440"}, {"450"}, {"601"}, {"602"},
+- {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"},
+- {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"},
+- {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"},
+- {"a2"}, {"a2q"}, {"e500mc"}, {"e5500"}, {"power3"},
+- {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, {"pwr5"},
+- {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, {"power6x"},
+- {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, {"pwr8"},
+- {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"}, {"powerpc64"},
+- {"ppc64"}, {"powerpc64le"}, {"ppc64le"},
++ {"generic"}, {"440"}, {"450"}, {"601"}, {"602"},
++ {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"},
++ {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"},
++ {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"},
++ {"a2"}, {"a2q"}, {"e500"}, {"e500mc"}, {"e5500"},
++ {"power3"}, {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"},
++ {"pwr5"}, {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"},
++ {"power6x"}, {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"},
++ {"pwr8"}, {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"},
++ {"powerpc64"}, {"ppc64"}, {"powerpc64le"}, {"ppc64le"},
+ };
+
+ bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
+Index: llvm-toolchain-snapshot_8~svn349138/clang/lib/Basic/Targets/PPC.h
+===================================================================
+--- llvm-toolchain-snapshot_8~svn349138.orig/clang/lib/Basic/Targets/PPC.h
++++ llvm-toolchain-snapshot_8~svn349138/clang/lib/Basic/Targets/PPC.h
+@@ -45,7 +45,8 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetI
+ ArchDefinePwr8 = 1 << 12,
+ ArchDefinePwr9 = 1 << 13,
+ ArchDefineA2 = 1 << 14,
+- ArchDefineA2q = 1 << 15
++ ArchDefineA2q = 1 << 15,
++ ArchDefine500v2 = 1 << 16
+ } ArchDefineTypes;
+
+
+@@ -66,6 +67,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetI
+ bool HasBPERMD = false;
+ bool HasExtDiv = false;
+ bool HasP9Vector = false;
++ bool HasSPE = false;
+
+ protected:
+ std::string ABI;
+@@ -145,6 +147,8 @@ public:
+ ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
+ ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
+ ArchDefinePpcsq)
++ .Cases("e500", "e500v2",
++ ArchDefineName | ArchDefine500v2)
+ .Default(ArchDefineNone);
+ }
+ return CPUKnown;
+Index: llvm-toolchain-snapshot_8~svn349138/clang/test/Driver/ppc-features.cpp
+===================================================================
+--- llvm-toolchain-snapshot_8~svn349138.orig/clang/test/Driver/ppc-features.cpp
++++ llvm-toolchain-snapshot_8~svn349138/clang/test/Driver/ppc-features.cpp
+@@ -168,6 +168,9 @@
+ // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-invariant-function-descriptors -minvariant-function-descriptors -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-INVFUNCDESC %s
+ // CHECK-INVFUNCDESC: "-target-feature" "+invariant-function-descriptors"
+
++// RUN: %clang -target powerpc-unknown-linux-gnu %s -mno-spe -mspe -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-SPE %s
++// CHECK-SPE: "-target-feature" "+spe"
++
+ // Assembler features
+ // RUN: %clang -target powerpc64-unknown-linux-gnu %s -### -o %t.o -no-integrated-as 2>&1 | FileCheck -check-prefix=CHECK_BE_AS_ARGS %s
+ // CHECK_BE_AS_ARGS: "-mppc64"
+Index: llvm-toolchain-snapshot_8~svn349138/clang/test/Misc/target-invalid-cpu-note.c
+===================================================================
+--- llvm-toolchain-snapshot_8~svn349138.orig/clang/test/Misc/target-invalid-cpu-note.c
++++ llvm-toolchain-snapshot_8~svn349138/clang/test/Misc/target-invalid-cpu-note.c
+@@ -79,7 +79,7 @@
+ // PPC: error: unknown target CPU 'not-a-cpu'
+ // PPC: note: valid target CPU values are: generic, 440, 450, 601, 602, 603,
+ // PPC-SAME: 603e, 603ev, 604, 604e, 620, 630, g3, 7400, g4, 7450, g4+, 750,
+-// PPC-SAME: 970, g5, a2, a2q, e500mc, e5500, power3, pwr3, power4, pwr4,
++// PPC-SAME: 970, g5, a2, a2q, e500, e500mc, e5500, power3, pwr3, power4, pwr4,
+ // PPC-SAME: power5, pwr5, power5x, pwr5x, power6, pwr6, power6x, pwr6x, power7,
+ // PPC-SAME: pwr7, power8, pwr8, power9, pwr9, powerpc, ppc, powerpc64, ppc64,
+ // PPC-SAME: powerpc64le, ppc64le
+Index: llvm-toolchain-snapshot_8~svn349138/clang/test/Preprocessor/init.c
+===================================================================
+--- llvm-toolchain-snapshot_8~svn349138.orig/clang/test/Preprocessor/init.c
++++ llvm-toolchain-snapshot_8~svn349138/clang/test/Preprocessor/init.c
+@@ -7016,6 +7016,10 @@
+ //
+ // PPC32-LINUX-NOT: _CALL_LINUX
+ //
++// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-unknown-linux-gnu -target-feature +spe < /dev/null | FileCheck -match-full-lines -check-prefix PPC32-SPE %s
++//
++// PPC32-SPE:#define __SPE__ 1
++//
+ // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-apple-darwin8 < /dev/null | FileCheck -match-full-lines -check-prefix PPC-DARWIN %s
+ //
+ // PPC-DARWIN:#define _ARCH_PPC 1
diff --git a/debian/patches/powerpcspe/D54409-powerpcspe-register-spilling.diff b/debian/patches/powerpcspe/D54409-powerpcspe-register-spilling.diff
new file mode 100644
index 0000000..3a50a54
--- /dev/null
+++ b/debian/patches/powerpcspe/D54409-powerpcspe-register-spilling.diff
@@ -0,0 +1,88 @@
+Description: PowerPC/SPE: Fix register spilling for SPE registers
+Author: Justin Hibbits <jrh29@alumni.cwru.edu>
+Origin: https://reviews.llvm.org/D54409
+Last-Update: 2018-12-05
+
+--- llvm-toolchain-7-7.0.1~+rc2.orig/lib/Target/PowerPC/PPCRegisterInfo.cpp
++++ llvm-toolchain-7-7.0.1~+rc2/lib/Target/PowerPC/PPCRegisterInfo.cpp
+@@ -844,6 +844,9 @@ static unsigned offsetMinAlign(const Mac
+ case PPC::STXSD:
+ case PPC::STXSSP:
+ return 4;
++ case PPC::EVLDD:
++ case PPC::EVSTDD:
++ return 8;
+ case PPC::LXV:
+ case PPC::STXV:
+ return 16;
+@@ -960,7 +963,10 @@ PPCRegisterInfo::eliminateFrameIndex(Mac
+ // happen in invalid code.
+ assert(OpC != PPC::DBG_VALUE &&
+ "This should be handled in a target-independent way");
+- if (!noImmForm && ((isInt<16>(Offset) &&
++ bool canBeImmediate = (OpC == PPC::EVSTDD || OpC == PPC::EVLDD) ?
++ isUInt<8>(Offset) :
++ isInt<16>(Offset);
++ if (!noImmForm && ((canBeImmediate &&
+ ((Offset % offsetMinAlign(MI)) == 0)) ||
+ OpC == TargetOpcode::STACKMAP ||
+ OpC == TargetOpcode::PATCHPOINT)) {
+--- llvm-toolchain-7-7.0.1~+rc2.orig/test/CodeGen/PowerPC/spe.ll
++++ llvm-toolchain-7-7.0.1~+rc2/test/CodeGen/PowerPC/spe.ll
+@@ -525,18 +525,53 @@ entry:
+ ; CHECK: #NO_APP
+ }
+
+-define double @test_spill(double %a) nounwind {
++declare double @test_spill_spe_regs(double, double);
++define dso_local void @test_func2() #0 {
+ entry:
++ ret void
++}
++
++@global_var1 = global i32 0, align 4
++define double @test_spill(double %a, i32 %a1, i64 %a2, i8 * %a3, i32 *%a4, i32* %a5) nounwind {
++entry:
++ %a.addr = alloca double, align 8
++ %a1.addr = alloca i32, align 4
++ %a2.addr = alloca i64, align 8
++ %a3.addr = alloca i8*, align 4
++ %a4.addr = alloca i32*, align 4
++ %a5.addr = alloca i32*, align 4
++ %ptr = alloca i32*, align 4
++ %v1 = alloca [8 x i32], align 4
++ %v2 = alloca [7 x i32], align 4
++ %v3 = alloca [5 x i32], align 4
++ store i32 %a1, i32* %a1.addr, align 4
++ store i64 %a2, i64* %a2.addr, align 8
++ store i8* %a3, i8** %a3.addr, align 4
++ store i32* %a4, i32** %a4.addr, align 4
++ store i32* %a5, i32** %a5.addr, align 4
++ store i32* @global_var1, i32** %ptr, align 4
+ %0 = fadd double %a, %a
+- call void asm sideeffect "","~{r0},~{r3},~{s4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
++ call void asm sideeffect "","~{s0},~{s3},~{s4},~{s5},~{s6},~{s7},~{s8},~{s9},~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19},~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29},~{s30},~{s31}"() nounwind
+ %1 = fadd double %0, 3.14159
++ %2 = load i32*, i32** %ptr, align 4
++ %3 = bitcast [8 x i32]* %v1 to i8*
++ call void @llvm.memset.p0i8.i32(i8* align 4 %3, i8 0, i32 24, i1 true)
++ %4 = load i32*, i32** %a5.addr, align 4
++ store i32 0, i32* %4, align 4
++ call void @test_func2()
++ %5 = bitcast [7 x i32]* %v2 to i8*
++ call void @llvm.memset.p0i8.i32(i8* align 4 %5, i8 0, i32 20, i1 true)
+ br label %return
+
+ return:
+ ret double %1
+
+ ; CHECK-LABEL: test_spill
+-; CHECK: efdadd
++; CHECK: li [[VREG:[0-9]+]], 256
++; CHECK: evstddx {{[0-9]+}}, {{[0-9]+}}, [[VREG]]
++; CHECK-NOT: evstdd {{[0-9]+}}, 256({{[0-9]+}}
+ ; CHECK: evstdd
++; CHECK: efdadd
+ ; CHECK: evldd
+ }
++declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1) #1
diff --git a/debian/patches/powerpcspe/D54584-powerpcspe-double-parameter.diff b/debian/patches/powerpcspe/D54584-powerpcspe-double-parameter.diff
new file mode 100644
index 0000000..d7d670a
--- /dev/null
+++ b/debian/patches/powerpcspe/D54584-powerpcspe-double-parameter.diff
@@ -0,0 +1,217 @@
+Description: PowerPC: Optimize SPE double parameter calling setup
+Author: Justin Hibbits <jrh29@alumni.cwru.edu>
+Origin: https://reviews.llvm.org/D54583
+Last-Update: 2018-12-04
+
+Index: llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCISelLowering.cpp
+===================================================================
+--- llvm-toolchain-snapshot_8~svn350421.orig/lib/Target/PowerPC/PPCISelLowering.cpp
++++ llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCISelLowering.cpp
+@@ -385,8 +385,16 @@ PPCTargetLowering::PPCTargetLowering(con
+ } else {
+ setOperationAction(ISD::BITCAST, MVT::f32, Expand);
+ setOperationAction(ISD::BITCAST, MVT::i32, Expand);
+- setOperationAction(ISD::BITCAST, MVT::i64, Expand);
+ setOperationAction(ISD::BITCAST, MVT::f64, Expand);
++ if (Subtarget.hasSPE()) {
++ setOperationAction(ISD::BITCAST, MVT::i64, Custom);
++ } else {
++ setOperationAction(ISD::BITCAST, MVT::i64, Expand);
++ }
++ }
++
++ if (Subtarget.hasSPE()) {
++ setOperationAction(ISD::EXTRACT_ELEMENT, MVT::i64, Custom);
+ }
+
+ // We cannot sextinreg(i1). Expand to shifts.
+@@ -1366,6 +1374,9 @@ const char *PPCTargetLowering::getTarget
+ case PPCISD::QVLFSb: return "PPCISD::QVLFSb";
+ case PPCISD::BUILD_FP128: return "PPCISD::BUILD_FP128";
+ case PPCISD::EXTSWSLI: return "PPCISD::EXTSWSLI";
++ case PPCISD::BUILD_SPE64: return "PPCISD::BUILD_SPE64";
++ case PPCISD::EXTRACT_SPE_LO: return "PPCISD::EXTRACT_SPE_LO";
++ case PPCISD::EXTRACT_SPE_HI: return "PPCISD::EXTRACT_SPE_HI";
+ }
+ return nullptr;
+ }
+@@ -7886,6 +7897,15 @@ SDValue PPCTargetLowering::LowerBITCAST(
+ SDLoc dl(Op);
+ SDValue Op0 = Op->getOperand(0);
+
++ if (Subtarget.hasSPE()) {
++ if (Op.getValueType() == MVT::f64 &&
++ Op0.getOpcode() == ISD::BUILD_PAIR &&
++ (Op0.getOperand(1).getValueType() == MVT::i32) &&
++ (Op0.getOperand(0).getValueType() == MVT::i32))
++ return DAG.getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, Op0.getOperand(0),
++ Op0.getOperand(1));
++ }
++
+ if (!EnableQuadPrecision ||
+ (Op.getValueType() != MVT::f128 ) ||
+ (Op0.getOpcode() != ISD::BUILD_PAIR) ||
+@@ -7897,6 +7917,26 @@ SDValue PPCTargetLowering::LowerBITCAST(
+ Op0.getOperand(1));
+ }
+
++// Lower EXTRACT_ELEMENT (i64 BITCAST f64), 0/1 to evmerge*
++SDValue PPCTargetLowering::LowerEXTRACT_ELEMENT(SDValue Op, SelectionDAG &DAG) const {
++
++ SDLoc dl(Op);
++ SDValue Op0 = Op->getOperand(0);
++
++ if (!Subtarget.hasSPE())
++ return SDValue();
++
++ if (!(Op.getValueType() == MVT::i32 &&
++ Op0.getOpcode() == ISD::BITCAST))
++ return SDValue();
++
++ assert(Op0.getNumOperands() > 0 && "WTF?");
++ if (Op->getConstantOperandVal(1) == 0)
++ return DAG.getNode(PPCISD::EXTRACT_SPE_LO, dl, MVT::i32, Op0.getOperand(0));
++
++ return DAG.getNode(PPCISD::EXTRACT_SPE_HI, dl, MVT::i32, Op0.getOperand(0));
++}
++
+ // 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
+@@ -9680,6 +9720,8 @@ SDValue PPCTargetLowering::LowerOperatio
+ return LowerBSWAP(Op, DAG);
+ case ISD::ATOMIC_CMP_SWAP:
+ return LowerATOMIC_CMP_SWAP(Op, DAG);
++ case ISD::EXTRACT_ELEMENT:
++ return LowerEXTRACT_ELEMENT(Op, DAG);
+ }
+ }
+
+Index: llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCISelLowering.h
+===================================================================
+--- llvm-toolchain-snapshot_8~svn350421.orig/lib/Target/PowerPC/PPCISelLowering.h
++++ llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCISelLowering.h
+@@ -196,6 +196,15 @@ namespace llvm {
+ /// Direct move of 2 consective GPR to a VSX register.
+ BUILD_FP128,
+
++ /// Merge 2 GPRs to a single SPE register
++ BUILD_SPE64,
++
++ /// Extract high SPE register component
++ EXTRACT_SPE_HI,
++
++ /// Extract low SPE register component
++ EXTRACT_SPE_LO,
++
+ /// Extract a subvector from signed integer vector and convert to FP.
+ /// It is primarily used to convert a (widened) illegal integer vector
+ /// type to a legal floating point vector type.
+@@ -1110,6 +1119,7 @@ namespace llvm {
+ SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
++ SDValue LowerEXTRACT_ELEMENT(SDValue Op, SelectionDAG &DAG) const;
+
+ SDValue DAGCombineExtBoolTrunc(SDNode *N, DAGCombinerInfo &DCI) const;
+ SDValue DAGCombineBuildVector(SDNode *N, DAGCombinerInfo &DCI) const;
+Index: llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCInstrInfo.td
+===================================================================
+--- llvm-toolchain-snapshot_8~svn350421.orig/lib/Target/PowerPC/PPCInstrInfo.td
++++ llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCInstrInfo.td
+@@ -231,6 +231,22 @@ def PPCbuild_fp128: SDNode<"PPCISD::BUIL
+ SDTCisSameAs<1,2>]>,
+ []>;
+
++def PPCbuild_spe64: SDNode<"PPCISD::BUILD_SPE64",
++ SDTypeProfile<1, 2,
++ [SDTCisFP<0>, SDTCisSameSizeAs<1,2>,
++ SDTCisSameAs<1,2>]>,
++ []>;
++
++def PPCextract_spe_hi : SDNode<"PPCISD::EXTRACT_SPE_HI",
++ SDTypeProfile<1, 1,
++ [SDTCisInt<0>, SDTCisFP<1>]>,
++ []>;
++
++def PPCextract_spe_lo : SDNode<"PPCISD::EXTRACT_SPE_LO",
++ SDTypeProfile<1, 1,
++ [SDTCisInt<0>, SDTCisFP<1>]>,
++ []>;
++
+ // These are target-independent nodes, but have target-specific formats.
+ def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeqStart,
+ [SDNPHasChain, SDNPOutGlue]>;
+Index: llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCInstrSPE.td
+===================================================================
+--- llvm-toolchain-snapshot_8~svn350421.orig/lib/Target/PowerPC/PPCInstrSPE.td
++++ llvm-toolchain-snapshot_8~svn350421/lib/Target/PowerPC/PPCInstrSPE.td
+@@ -512,7 +512,7 @@ def EVLWWSPLATX : EVXForm_1<792, (out
+
+ def EVMERGEHI : EVXForm_1<556, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+ "evmergehi $RT, $RA, $RB", IIC_VecGeneral, []>;
+-def EVMERGELO : EVXForm_1<557, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
++def EVMERGELO : EVXForm_1<557, (outs sperc:$RT), (ins gprc:$RA, gprc:$RB),
+ "evmergelo $RT, $RA, $RB", IIC_VecGeneral, []>;
+ def EVMERGEHILO : EVXForm_1<558, (outs sperc:$RT), (ins sperc:$RA, sperc:$RB),
+ "evmergehilo $RT, $RA, $RB", IIC_VecGeneral, []>;
+@@ -887,4 +887,15 @@ def : Pat<(f64 (selectcc i1:$lhs, i1:$rh
+ (SELECT_SPE (CRANDC $lhs, $rhs), $tval, $fval)>;
+ def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
+ (SELECT_SPE (CRXOR $lhs, $rhs), $tval, $fval)>;
++
++
++def : Pat<(f64 (PPCbuild_spe64 i32:$rB, i32:$rA)),
++ (f64 (COPY_TO_REGCLASS (EVMERGELO $rA, $rB), SPERC))>;
++
++def : Pat<(i32 (PPCextract_spe_hi f64:$rA)),
++ (i32 (EXTRACT_SUBREG (EVMERGEHI $rA, $rA), sub_32))>;
++
++def : Pat<(i32 (PPCextract_spe_lo f64:$rA)),
++ (i32 (EXTRACT_SUBREG $rA, sub_32))>;
++
+ }
+Index: llvm-toolchain-snapshot_8~svn350421/test/CodeGen/PowerPC/spe.ll
+===================================================================
+--- llvm-toolchain-snapshot_8~svn350421.orig/test/CodeGen/PowerPC/spe.ll
++++ llvm-toolchain-snapshot_8~svn350421/test/CodeGen/PowerPC/spe.ll
+@@ -472,10 +472,8 @@ entry:
+ ; CHECK-LABEL: test_dselect
+ ; CHECK: andi.
+ ; CHECK: bc
+-; CHECK: evldd
+-; CHECK: b
+-; CHECK: evldd
+-; CHECK: evstdd
++; CHECK: evor
++; CHECK: evmergehi
+ ; CHECK: blr
+ }
+
+@@ -519,7 +517,7 @@ entry:
+ %1 = call i32 asm sideeffect "efdctsi $0, $1", "=d,d"(double %0)
+ ret i32 %1
+ ; CHECK-LABEL: test_dasmconst
+-; CHECK: evldd
++; CHECK: evmergelo
+ ; CHECK: #APP
+ ; CHECK: efdctsi
+ ; CHECK: #NO_APP
+@@ -541,7 +539,7 @@ entry:
+ %a4.addr = alloca i32*, align 4
+ %a5.addr = alloca i32*, align 4
+ %ptr = alloca i32*, align 4
+- %v1 = alloca [8 x i32], align 4
++ %v1 = alloca [9 x i32], align 4
+ %v2 = alloca [7 x i32], align 4
+ %v3 = alloca [5 x i32], align 4
+ store i32 %a1, i32* %a1.addr, align 4
+@@ -554,7 +552,7 @@ entry:
+ call void asm sideeffect "","~{s0},~{s3},~{s4},~{s5},~{s6},~{s7},~{s8},~{s9},~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19},~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29},~{s30},~{s31}"() nounwind
+ %1 = fadd double %0, 3.14159
+ %2 = load i32*, i32** %ptr, align 4
+- %3 = bitcast [8 x i32]* %v1 to i8*
++ %3 = bitcast [9 x i32]* %v1 to i8*
+ call void @llvm.memset.p0i8.i32(i8* align 4 %3, i8 0, i32 24, i1 true)
+ %4 = load i32*, i32** %a5.addr, align 4
+ store i32 0, i32* %4, align 4