@@ -7,6 +7,7 @@ SPDX-License-Identifier: MIT
77============================= end_copyright_notice ===========================*/
88
99#include " vc/Utils/General/Types.h"
10+ #include " llvmWrapper/Support/TypeSize.h"
1011
1112#include " Probe/Assertion.h"
1213
@@ -57,3 +58,63 @@ Type &vc::fixDegenerateVectorType(Type &Ty) {
5758 return const_cast <Type &>(
5859 fixDegenerateVectorType (static_cast <const Type &>(Ty)));
5960}
61+
62+ // calculates new return type for cast instructions
63+ // * trunc
64+ // * bitcast
65+ // Expect that scalar type of instruction not changed and previous
66+ // combination of OldOutType & OldInType is valid
67+ Type *vc::getNewTypeForCast (Type *OldOutType, Type *OldInType,
68+ Type *NewInType) {
69+ IGC_ASSERT_MESSAGE (OldOutType && NewInType && OldInType,
70+ " Error: nullptr input" );
71+
72+ bool NewInIsVec = isa<IGCLLVM::FixedVectorType>(NewInType);
73+ bool OldOutIsVec = isa<IGCLLVM::FixedVectorType>(OldOutType);
74+ bool OldInIsVec = isa<IGCLLVM::FixedVectorType>(OldInType);
75+
76+ bool NewInIsPtrOrVecPtr = NewInType->isPtrOrPtrVectorTy ();
77+ bool OldOutIsPtrOrVecPtr = OldOutType->isPtrOrPtrVectorTy ();
78+ bool OldInIsPtrOrVecPtr = OldInType->isPtrOrPtrVectorTy ();
79+
80+ // only pointer to pointer
81+ IGC_ASSERT (NewInIsPtrOrVecPtr == OldOutIsPtrOrVecPtr &&
82+ NewInIsPtrOrVecPtr == OldInIsPtrOrVecPtr);
83+ // <2 x char> -> int : < 4 x char> -> ? forbidden
84+ IGC_ASSERT (OldOutIsVec == OldInIsVec && OldOutIsVec == NewInIsVec);
85+ Type *NewOutType = OldOutType;
86+ if (OldOutIsVec) {
87+ // <4 x char> -> <2 x int> : <8 x char> -> <4 x int>
88+ // <4 x char> -> <2 x int> : <2 x char> -> <1 x int>
89+ auto NewInEC = cast<IGCLLVM::FixedVectorType>(NewInType)->getNumElements ();
90+ auto OldOutEC =
91+ cast<IGCLLVM::FixedVectorType>(OldOutType)->getNumElements ();
92+ auto OldInEC = cast<IGCLLVM::FixedVectorType>(OldInType)->getNumElements ();
93+ auto NewOutEC = OldOutEC * NewInEC / OldInEC;
94+ // <4 x char> -> <2 x int> : <5 x char> -> ? forbidden
95+ IGC_ASSERT_MESSAGE ((OldOutEC * NewInEC) % OldInEC == 0 ,
96+ " Error: wrong combination of input/output" );
97+ // element count changed, scalar type as previous
98+ NewOutType = IGCLLVM::FixedVectorType::get (
99+ OldOutType->getVectorElementType (), IGCLLVM::getElementCount (NewOutEC));
100+ }
101+
102+ IGC_ASSERT (NewOutType);
103+
104+ if (NewInIsPtrOrVecPtr) {
105+ // <4 x char*> -> <2 x half*> : < 2 x int*> - ? forbidden
106+ // char* -> half* : int* -> ? forbidden
107+ IGC_ASSERT_MESSAGE (OldInType->getScalarType ()->getPointerElementType () ==
108+ NewInType->getScalarType ()->getPointerElementType (),
109+ " Error: unexpected type change" );
110+ // address space from new
111+ // element count calculated as for vector
112+ // element type expect address space similar
113+ auto AddressSpace = getAddrSpace (NewInType);
114+ return changeAddrSpace (NewOutType, AddressSpace);
115+ }
116+ // <4 x char> -> <2 x half> : < 2 x int> - ? forbiddeb
117+ IGC_ASSERT_MESSAGE (OldInType->getScalarType () == NewInType->getScalarType (),
118+ " Error: unexpected type change" );
119+ return NewOutType;
120+ }
0 commit comments