summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCISelLowering.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-11-29 19:58:49 +0000
committerChris Lattner <sabre@nondot.org>2006-11-29 19:58:49 +0000
commit15eb329dae1dea7a5a38cf0c1074aaa3e0f78ab6 (patch)
treed318fd18ab678b3025b6bc30b74963cd85a2ed39 /lib/Target/PowerPC/PPCISelLowering.cpp
parent7e68724f48f9d3a61e9888920a79457d3ad0a605 (diff)
downloadllvm-15eb329dae1dea7a5a38cf0c1074aaa3e0f78ab6.tar.gz
llvm-15eb329dae1dea7a5a38cf0c1074aaa3e0f78ab6.tar.bz2
llvm-15eb329dae1dea7a5a38cf0c1074aaa3e0f78ab6.tar.xz
Fix bug codegen'ing FP constant vectors with integer splats. Make sure the
created intrinsics have the right integer types. This fixes PowerPC/2006-11-29-AltivecFPSplat.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32024 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp36
1 files changed, 22 insertions, 14 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index d26bfb53cd..4df521aef4 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1973,6 +1973,7 @@ static SDOperand BuildSplatI(int Val, unsigned SplatSize, MVT::ValueType VT,
Ops.assign(MVT::getVectorNumElements(CanonicalVT), Elt);
SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT,
&Ops[0], Ops.size());
+ if (VT == MVT::Other) return Res;
return DAG.getNode(ISD::BIT_CONVERT, VT, Res);
}
@@ -2086,6 +2087,7 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
-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, 13, 14, -14, 15, -15, -16
};
+
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_0000). 'vsplti -1'
@@ -2097,43 +2099,47 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
// vsplti + shl self.
if (SextVal == (i << (int)TypeShiftAmt)) {
- Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+ SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, 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 BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+ Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+ return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
}
// vsplti + srl self.
if (SextVal == (int)((unsigned)i >> TypeShiftAmt)) {
- Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+ SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, DAG);
static const unsigned IIDs[] = { // Intrinsic to use for each size.
Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
Intrinsic::ppc_altivec_vsrw
};
- return BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+ Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+ return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
}
// vsplti + sra self.
if (SextVal == (int)((unsigned)i >> TypeShiftAmt)) {
- Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+ SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, DAG);
static const unsigned IIDs[] = { // Intrinsic to use for each size.
Intrinsic::ppc_altivec_vsrab, Intrinsic::ppc_altivec_vsrah, 0,
Intrinsic::ppc_altivec_vsraw
};
- return BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+ Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+ return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
}
// vsplti + rol self.
if (SextVal == (int)(((unsigned)i << TypeShiftAmt) |
((unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
- Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+ SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, DAG);
static const unsigned IIDs[] = { // Intrinsic to use for each size.
Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
Intrinsic::ppc_altivec_vrlw
};
- return BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+ Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+ return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
}
// t = vsplti c, result = vsldoi t, t, 1
@@ -2157,15 +2163,17 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
// Odd, in range [17,31]: (vsplti C)-(vsplti -16).
if (SextVal >= 0 && SextVal <= 31) {
- SDOperand LHS = BuildSplatI(SextVal-16, SplatSize, Op.getValueType(),DAG);
- SDOperand RHS = BuildSplatI(-16, SplatSize, Op.getValueType(), DAG);
- return DAG.getNode(ISD::SUB, Op.getValueType(), LHS, RHS);
+ SDOperand LHS = BuildSplatI(SextVal-16, SplatSize, MVT::Other, DAG);
+ SDOperand RHS = BuildSplatI(-16, SplatSize, MVT::Other, DAG);
+ LHS = DAG.getNode(ISD::SUB, Op.getValueType(), LHS, RHS);
+ return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), LHS);
}
// Odd, in range [-31,-17]: (vsplti C)+(vsplti -16).
if (SextVal >= -31 && SextVal <= 0) {
- SDOperand LHS = BuildSplatI(SextVal+16, SplatSize, Op.getValueType(),DAG);
- SDOperand RHS = BuildSplatI(-16, SplatSize, Op.getValueType(), DAG);
- return DAG.getNode(ISD::ADD, Op.getValueType(), LHS, RHS);
+ SDOperand LHS = BuildSplatI(SextVal+16, SplatSize, MVT::Other, DAG);
+ SDOperand RHS = BuildSplatI(-16, SplatSize, MVT::Other, DAG);
+ LHS = DAG.getNode(ISD::ADD, Op.getValueType(), LHS, RHS);
+ return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), LHS);
}
}