Hrmm.... PromoteVectorOp doesn't seem to follow this at all.
http://llvm.org/svn/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
SDValue VectorLegalizer::PromoteVectorOp(SDValue Op) {
// Vector "promotion" is basically just bitcasting and doing the operation
// in a different type. For example, x86 promotes ISD::AND on v2i32 to
// v1i64.
EVT VT = Op.getValueType();
assert(Op.getNode()->getNumValues() == 1 &&
"Can't promote a vector with multiple results!");
EVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT);
DebugLoc dl = Op.getDebugLoc();
SmallVector<SDValue, 4> Operands(Op.getNumOperands());
for (unsigned j = 0; j != Op.getNumOperands(); ++j) {
if (Op.getOperand(j).getValueType().isVector())
Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Op.getOperand(j));
else
Operands[j] = Op.getOperand(j);
}
Op = DAG.getNode(Op.getOpcode(), dl, NVT, &Operands[0], Operands.size());
return DAG.getNode(ISD::BITCAST, dl, VT, Op);
}
The input Op is <4 x i8> = and <4 x i8>, <4 x i8>.
The result of TLI.getTypeToPromoteTo(ISD::AND, MVT::v4i8) is MVT::v2i32;
The reason why this occurs is:
// See if this has an explicit type specified.
std::map<std::pair<unsigned, MVT::SimpleValueType>,
MVT::SimpleValueType>::const_iterator PTTI =
PromoteToType.find(std::make_pair(Op, VT.getSimpleVT().SimpleTy));
if (PTTI != PromoteToType.end()) return PTTI->second;
assert((VT.isInteger() || VT.isFloatingPoint()) &&
"Cannot autopromote this type, add it with AddPromotedToType.");
EVT NVT = VT;
do {
NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1);
assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid &&
"Didn't find type to promote to!");
} while (!isTypeLegal(NVT) ||
getOperationAction(Op, NVT) == Promote);
The first line in the do while loop is important, it just increments the type, starting at MVT::v4i8 until it hits a legal type.
This seems broken to me.
Here is what TOT LLVM has for its MVT list:
v4i8 = 14, // 4 x i8
v8i8 = 15, // 8 x i8
v16i8 = 16, // 16 x i8
v32i8 = 17, // 32 x i8
v2i16 = 18, // 2 x i16
v4i16 = 19, // 4 x i16
v8i16 = 20, // 8 x i16
v16i16 = 21, // 16 x i16
v2i32 = 22, // 2 x i32
So, for my platform with the 'and' I promote all i8 and i16 types, so the first type that is legal is v2i32.
If I add the v1i32 then it works, however, it breaks when I added v1i16(which I need for the v2i8 case).
So I set AddPromotedType(ISD::AND, MVT::v4i8, MVT::v1i32) to get around it. So it seems in this case someone has
hit this issue before and added the ability to override promotion rules.