mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
Teach getCastOpcode about element-by-element vector casts. For example, "trunc"
can be used to turn a <4 x i64> into a <4 x i32> but getCastOpcode would assert if you passed these types to it. Note that this strictly extends the previous functionality: if getCastOpcode previously accepted two vector types (i.e. didn't assert) then it still will and returns the same opcode (BitCast). That's because before it would only accept vectors with the same bitwidth, and the new code only touches vectors with the same length. However if two vectors have both the same bitwidth and the same length then their element types have the same bitwidth, so the new logic will return BitCast as before. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131530 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2a8eb722c7
commit
117feba971
@ -2254,6 +2254,14 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
|
||||
if (SrcTy == DestTy)
|
||||
return true;
|
||||
|
||||
if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
|
||||
if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
|
||||
if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
|
||||
// An element by element cast. Valid if casting the elements is valid.
|
||||
SrcTy = SrcVecTy->getElementType();
|
||||
DestTy = DestVecTy->getElementType();
|
||||
}
|
||||
|
||||
// Get the bit sizes, we'll need these
|
||||
unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
|
||||
unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
|
||||
@ -2322,14 +2330,27 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
|
||||
Instruction::CastOps
|
||||
CastInst::getCastOpcode(
|
||||
const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
|
||||
// Get the bit sizes, we'll need these
|
||||
const Type *SrcTy = Src->getType();
|
||||
unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
|
||||
unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
|
||||
|
||||
assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
|
||||
"Only first class types are castable!");
|
||||
|
||||
if (SrcTy == DestTy)
|
||||
return BitCast;
|
||||
|
||||
if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
|
||||
if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
|
||||
if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
|
||||
// An element by element cast. Find the appropriate opcode based on the
|
||||
// element types.
|
||||
SrcTy = SrcVecTy->getElementType();
|
||||
DestTy = DestVecTy->getElementType();
|
||||
}
|
||||
|
||||
// Get the bit sizes, we'll need these
|
||||
unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
|
||||
unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
|
||||
|
||||
// Run through the possibilities ...
|
||||
if (DestTy->isIntegerTy()) { // Casting to integral
|
||||
if (SrcTy->isIntegerTy()) { // Casting from integral
|
||||
@ -2384,7 +2405,7 @@ CastInst::getCastOpcode(
|
||||
if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
|
||||
assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
|
||||
"Casting vector to vector of different widths");
|
||||
SrcPTy = NULL;
|
||||
(void)SrcPTy;
|
||||
return BitCast; // vector -> vector
|
||||
} else if (DestPTy->getBitWidth() == SrcBits) {
|
||||
return BitCast; // float/int -> vector
|
||||
|
@ -114,11 +114,19 @@ TEST(InstructionsTest, CastInst) {
|
||||
const Type* Int8Ty = Type::getInt8Ty(C);
|
||||
const Type* Int64Ty = Type::getInt64Ty(C);
|
||||
const Type* V8x8Ty = VectorType::get(Int8Ty, 8);
|
||||
const Type* V8x64Ty = VectorType::get(Int64Ty, 8);
|
||||
const Type* X86MMXTy = Type::getX86_MMXTy(C);
|
||||
|
||||
const Constant* c8 = Constant::getNullValue(V8x8Ty);
|
||||
const Constant* c64 = Constant::getNullValue(V8x64Ty);
|
||||
|
||||
EXPECT_TRUE(CastInst::isCastable(V8x8Ty, X86MMXTy));
|
||||
EXPECT_TRUE(CastInst::isCastable(X86MMXTy, V8x8Ty));
|
||||
EXPECT_FALSE(CastInst::isCastable(Int64Ty, X86MMXTy));
|
||||
EXPECT_TRUE(CastInst::isCastable(V8x64Ty, V8x8Ty));
|
||||
EXPECT_TRUE(CastInst::isCastable(V8x8Ty, V8x64Ty));
|
||||
EXPECT_EQ(CastInst::getCastOpcode(c64, true, V8x8Ty, true), CastInst::Trunc);
|
||||
EXPECT_EQ(CastInst::getCastOpcode(c8, true, V8x64Ty, true), CastInst::SExt);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
Loading…
Reference in New Issue
Block a user