@@ -346,6 +346,15 @@ void CustomSafeOptPass::visitCallInst(CallInst &C)
346346 break ;
347347 }
348348
349+ case GenISAIntrinsic::GenISA_ldptr:
350+ {
351+ if (IGC_IS_FLAG_ENABLED (UseHDCTypedRead))
352+ {
353+ visitLdptr (inst);
354+ }
355+ break ;
356+ }
357+
349358 default :
350359 break ;
351360 }
@@ -734,6 +743,86 @@ void CustomSafeOptPass::visitBinaryOperator(BinaryOperator &I)
734743 }
735744}
736745
746+ void IGC::CustomSafeOptPass::visitLdptr (llvm::CallInst* inst)
747+ {
748+ // change
749+ // % 10 = call fast <4 x float> @llvm.genx.GenISA.ldptr.v4f32.p196608v4f32(i32 %_s1.i, i32 %_s14.i, i32 0, i32 0, <4 x float> addrspace(196608)* null, i32 0, i32 0, i32 0), !dbg !123
750+ // to
751+ // % 10 = call fast <4 x float> @llvm.genx.GenISA.typedread.p196608v4f32(<4 x float> addrspace(196608)* null, i32 %_s1.i, i32 %_s14.i, i32 0, i32 0), !dbg !123
752+ // when the index comes directly from threadid
753+
754+ bool isSrc2Src3Zero = 0 ;
755+ if (Constant *src2 = dyn_cast<Constant>(inst->getOperand (2 )))
756+ {
757+ if (Constant *src3 = dyn_cast<Constant>(inst->getOperand (3 )))
758+ {
759+ if (src2->isZeroValue () && src3->isZeroValue ())
760+ {
761+ isSrc2Src3Zero = true ;
762+ }
763+ }
764+ }
765+
766+ if (!isSrc2Src3Zero)
767+ {
768+ return ;
769+ }
770+
771+ Instruction* AddInst0 = dyn_cast<Instruction>(inst->getOperand (0 ));
772+ Instruction* AddInst1 = dyn_cast<Instruction>(inst->getOperand (1 ));
773+ if (!AddInst0 || !AddInst1 ||
774+ AddInst0->getOpcode () != Instruction::Add ||
775+ AddInst1->getOpcode () != Instruction::Add)
776+ {
777+ return ;
778+ }
779+
780+ Instruction* ShlInst0 = dyn_cast<Instruction>(AddInst0->getOperand (0 ));
781+ Instruction* ShlInst1 = dyn_cast<Instruction>(AddInst1->getOperand (0 ));
782+ if (!ShlInst0 || !ShlInst1 ||
783+ ShlInst0->getOpcode () != Instruction::Shl ||
784+ ShlInst1->getOpcode () != Instruction::Shl)
785+ {
786+ return ;
787+ }
788+
789+ BitCastInst* bitcastInst0 = dyn_cast<BitCastInst>(ShlInst0->getOperand (0 ));
790+ BitCastInst* bitcastInst1 = dyn_cast<BitCastInst>(ShlInst1->getOperand (0 ));
791+ if (!bitcastInst0 || !bitcastInst1)
792+ {
793+ return ;
794+ }
795+
796+ GenIntrinsicInst *CI0 = dyn_cast<GenIntrinsicInst>(bitcastInst0->getOperand (0 ));
797+ GenIntrinsicInst *CI1 = dyn_cast<GenIntrinsicInst>(bitcastInst1->getOperand (0 ));
798+ if (!CI0 || !CI1 ||
799+ CI0->getIntrinsicID () != GenISAIntrinsic::GenISA_DCL_SystemValue ||
800+ CI1->getIntrinsicID () != GenISAIntrinsic::GenISA_DCL_SystemValue)
801+ {
802+ return ;
803+ }
804+
805+ llvm::IRBuilder<> builder (inst);
806+ Module *M = inst->getParent ()->getParent ()->getParent ();
807+
808+ Function* pLdIntrinsic = llvm::GenISAIntrinsic::getDeclaration (
809+ M,
810+ GenISAIntrinsic::GenISA_typedread,
811+ inst->getOperand (4 )->getType ());
812+
813+ SmallVector<Value*, 5 > ld_FunctionArgList (5 );
814+ ld_FunctionArgList[0 ] = inst->getOperand (4 );
815+ ld_FunctionArgList[1 ] = inst->getOperand (0 );
816+ ld_FunctionArgList[2 ] = inst->getOperand (1 );
817+ ld_FunctionArgList[3 ] = inst->getOperand (2 );
818+ ld_FunctionArgList[4 ] = inst->getOperand (3 );
819+
820+ llvm::CallInst* pNewCallInst = builder.CreateCall (
821+ pLdIntrinsic, ld_FunctionArgList);
822+
823+ inst->replaceAllUsesWith (pNewCallInst);
824+ }
825+
737826void IGC::CustomSafeOptPass::visitSampleBptr (llvm::SampleIntrinsic* sampleInst)
738827{
739828 // sampleB with bias_value==0 -> sample
0 commit comments