@@ -115,3 +115,40 @@ void ScalarizerCodeGen::visitBinaryOperator(llvm::BinaryOperator& I)
115115 }
116116 }
117117}
118+
119+ void ScalarizerCodeGen::visitCastInst (llvm::CastInst& I)
120+ {
121+ // Scalarizing vector type Trunc/Ext instructions
122+ if (I.getOpcode () == Instruction::Trunc || I.getOpcode () == Instruction::ZExt || I.getOpcode () == Instruction::SExt)
123+ {
124+ if (I.getType ()->isVectorTy ())
125+ {
126+ IGCLLVM::FixedVectorType* instType = cast<IGCLLVM::FixedVectorType>(I.getType ());
127+ unsigned numElements = int_cast<unsigned >(instType->getNumElements ());
128+ Type* dstType = instType->getScalarType ();
129+ Value* src0 = I.getOperand (0 );
130+ auto castOp = I.getOpcode ();
131+ m_builder->SetInsertPoint (&I);
132+
133+ Value* lastOp = UndefValue::get (instType);
134+ for (unsigned i = 0 ; i < numElements; i++)
135+ {
136+ Value* constIndex = ConstantInt::get (m_builder->getInt32Ty (), i);
137+ Value* eeSrc0 = m_builder->CreateExtractElement (src0, constIndex);
138+ Value* newCastInst = nullptr ;
139+ switch (castOp)
140+ {
141+ case Instruction::Trunc: newCastInst = m_builder->CreateTrunc (eeSrc0, dstType); break ;
142+ case Instruction::ZExt: newCastInst = m_builder->CreateZExt (eeSrc0, dstType); break ;
143+ case Instruction::SExt: newCastInst = m_builder->CreateSExt (eeSrc0, dstType); break ;
144+ default : IGC_ASSERT (0 );
145+ }
146+ lastOp = m_builder->CreateInsertElement (lastOp, newCastInst, constIndex);
147+ }
148+
149+ // Now replace all the instruction users with the newly created instruction
150+ I.replaceAllUsesWith (lastOp);
151+ I.eraseFromParent ();
152+ }
153+ }
154+ }
0 commit comments