@@ -198,6 +198,7 @@ class GenXLowering : public FunctionPass {
198198 bool lowerLoadStore (Instruction *Inst);
199199 bool lowerMulSat (CallInst *CI, unsigned IntrinsicID);
200200 bool lowerMul64 (Instruction *Inst);
201+ bool lowerLzd (Instruction *Inst);
201202 bool lowerTrap (CallInst *CI);
202203 bool generatePredicatedWrrForNewLoad (CallInst *CI);
203204};
@@ -1135,6 +1136,8 @@ bool GenXLowering::processInst(Instruction *Inst) {
11351136 case GenXIntrinsic::genx_usmul_sat:
11361137 case GenXIntrinsic::genx_uumul_sat:
11371138 return lowerMulSat (CI, IntrinsicID);
1139+ case GenXIntrinsic::genx_lzd:
1140+ return lowerLzd (Inst);
11381141 case Intrinsic::trap:
11391142 return lowerTrap (CI);
11401143 case Intrinsic::ctpop:
@@ -2568,7 +2571,6 @@ bool GenXLowering::lowerMul64(Instruction *Inst) {
25682571 return false ;
25692572
25702573 IRBuilder<> Builder (Inst);
2571- Builder.SetCurrentDebugLocation (Inst->getDebugLoc ());
25722574
25732575 auto Src0 = SplitBuilder.splitOperandLoHi (0 );
25742576 auto Src1 = SplitBuilder.splitOperandLoHi (1 );
@@ -2596,6 +2598,38 @@ bool GenXLowering::lowerMul64(Instruction *Inst) {
25962598 ToErase.push_back (Inst);
25972599 return true ;
25982600}
2601+ bool GenXLowering::lowerLzd (Instruction *Inst) {
2602+ const unsigned OpIndex = 0 ;
2603+ IVSplitter SplitBuilder (*Inst, &OpIndex);
2604+ if (!SplitBuilder.IsI64Operation ())
2605+ return false ;
2606+
2607+ IRBuilder<> Builder (Inst);
2608+
2609+ auto Src = SplitBuilder.splitOperandLoHi (0 );
2610+
2611+ auto *VTy32 = cast<VectorType>(Src.Lo ->getType ());
2612+ IGC_ASSERT (VTy32->getScalarType () == Builder.getInt32Ty ());
2613+ auto *Zero = ConstantInt::getNullValue (VTy32);
2614+ auto *K32 = ConstantInt::get (VTy32, 32 );
2615+
2616+ auto *LzdF = GenXIntrinsic::getAnyDeclaration (
2617+ Inst->getModule (), GenXIntrinsic::genx_lzd, {Src.Lo ->getType ()});
2618+
2619+ // Lzd64 is lowered as:
2620+ // LoLzd = lzd(Src.Lo)
2621+ // HiLzd = lzd(Src.Hi)
2622+ // Result = (Src.Hi == 0) ? (LoLzd + 32) : HiLzd
2623+ auto *VlzdLo = Builder.CreateCall (LzdF, Src.Lo , " lower.lzd64.lo." );
2624+ auto *VlzdHi = Builder.CreateCall (LzdF, Src.Hi , " lower.lzd64.hi." );
2625+ auto *FlagHiZero = Builder.CreateICmpEQ (Src.Hi , Zero, " lower.lzd64.hicmp." );
2626+ auto *LoPathResult = Builder.CreateAdd (VlzdLo, K32, " lower.lzd64.lores." );
2627+ auto *Result =
2628+ Builder.CreateSelect (FlagHiZero, LoPathResult, VlzdHi, " lower.lzd64." );
2629+ Inst->replaceAllUsesWith (Result);
2630+ ToErase.push_back (Inst);
2631+ return true ;
2632+ }
25992633/* **********************************************************************
26002634 * widenByteOp : widen a vector byte operation to short if that might
26012635 * improve code
0 commit comments