Skip to content

Commit 4e4db7e

Browse files
vchernon-inteligcbot
authored andcommitted
remove non built-in Emulation of int64
int64 emulation was fully moved to BiF we do not need old emulation anymore
1 parent 574cb6b commit 4e4db7e

File tree

1 file changed

+0
-193
lines changed

1 file changed

+0
-193
lines changed

IGC/VectorCompiler/lib/GenXCodeGen/GenXEmulate.cpp

Lines changed: 0 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,6 @@ class GenXEmulate : public ModulePass {
167167

168168
Value *buildRightShift(IVSplitter &SplitBuilder, BinaryOperator &Op);
169169

170-
Value *visitFPToUI(FPToUIInst &);
171-
Value *visitFPToSI(FPToSIInst &);
172-
Value *visitUIToFP(UIToFPInst &);
173-
Value *visitSIToFP(SIToFPInst &);
174-
Value *buildUI64ToFloat(UIToFPInst &Op);
175-
Value *buildSI64ToFloat(SIToFPInst &Op);
176-
Value *buildI64ToHalf(CastInst &Op);
177-
178170
Value *visitZExtInst(ZExtInst &I);
179171
Value *visitSExtInst(SExtInst &I);
180172

@@ -737,191 +729,6 @@ Value *GenXEmulate::Emu64Expander::visitAShr(BinaryOperator &Op) {
737729
return buildRightShift(SplitBuilder, Op);
738730
}
739731

740-
Value *GenXEmulate::Emu64Expander::visitFPToUI(FPToUIInst &Op) {
741-
742-
if (!(Op.getOperand(0)->getType()->getScalarType()->isFloatTy() &&
743-
Op.getType()->getScalarType()->isIntegerTy(64)))
744-
vc::diagnose(Op.getContext(), "GenXEmulate", &Op,
745-
"unsupported (floating point type) -> UI conversion. "
746-
"Only float->i64 is supported");
747-
748-
// TODO: try to detect the case where operand is a constant expression
749-
// and do the covertion manually
750-
auto Builder = getIRBuilder();
751-
const bool IsSigned = false;
752-
auto *V = buildFPToI64(*Op.getModule(), Builder, SplitBuilder,
753-
Op.getOperand(0), IsSigned);
754-
return Builder.CreateBitCast(V, Op.getType(),
755-
Twine(Op.getOpcodeName()) + ".emu");
756-
}
757-
Value *GenXEmulate::Emu64Expander::visitFPToSI(FPToSIInst &Op) {
758-
759-
if (!(Op.getOperand(0)->getType()->getScalarType()->isFloatTy() &&
760-
Op.getType()->getScalarType()->isIntegerTy(64)))
761-
vc::diagnose(Op.getContext(), "GenXEmulate", &Op,
762-
"unsupported (floating point type) -> UI conversion. "
763-
"Only float->i64 is supported");
764-
765-
// TODO: try to detect the case where operand is a constant expression
766-
// and do the covertion manually
767-
auto Builder = getIRBuilder();
768-
const bool IsSigned = true;
769-
auto *V = buildFPToI64(*Op.getModule(), Builder, SplitBuilder,
770-
Op.getOperand(0), IsSigned);
771-
return Builder.CreateBitCast(V, Op.getType(),
772-
Twine(Op.getOpcodeName()) + ".emu");
773-
}
774-
Value *GenXEmulate::Emu64Expander::visitUIToFP(UIToFPInst &Op) {
775-
auto *STy = Op.getType()->getScalarType();
776-
777-
if (STy->isHalfTy())
778-
return buildI64ToHalf(Op);
779-
if (STy->isFloatTy())
780-
return buildUI64ToFloat(Op);
781-
vc::diagnose(Op.getContext(), "GenXEmulate", &Op,
782-
"unsupported UI64 -> (floating point type) conversion. "
783-
"Only UI64->float and UI64->half are supported");
784-
return nullptr; // to suppress warnings
785-
}
786-
Value *GenXEmulate::Emu64Expander::visitSIToFP(SIToFPInst &Op) {
787-
auto *STy = Op.getType()->getScalarType();
788-
789-
if (STy->isHalfTy())
790-
return buildI64ToHalf(Op);
791-
if (STy->isFloatTy())
792-
return buildSI64ToFloat(Op);
793-
vc::diagnose(Op.getContext(), "GenXEmulate", &Op,
794-
"unsupported SI64 -> (floating point type) conversion. "
795-
"Only SI64->float and SI64->half are supported");
796-
return nullptr; // to suppress warnings
797-
}
798-
Value *GenXEmulate::Emu64Expander::buildUI64ToFloat(UIToFPInst &Op) {
799-
IGC_ASSERT_MESSAGE(Op.getType()->getScalarType()->isFloatTy(),
800-
"UI64->fp32 conversion expected");
801-
802-
auto Builder = getIRBuilder();
803-
auto UI64 = SplitBuilder.splitOperandLoHi(0);
804-
ConstantEmitter K(UI64.Lo);
805-
806-
Function *LzdF = GenXIntrinsic::getAnyDeclaration(
807-
Op.getModule(), GenXIntrinsic::genx_lzd, {UI64.Hi->getType()});
808-
Value *Lz = Builder.CreateCall(LzdF, UI64.Hi, "int_emu.ui2fp.lzd.");
809-
// sp: 1|8|23
810-
// we need to get that nice first set bit into bit position 23.
811-
// thus we shift our nice pair of values by 63 - 23 - clz,
812-
// some bits will be dropped by shift thus we'll add 1 bits as R bit.
813-
// uint8_t shift = 39 - lz;
814-
const unsigned kMaxDroppedMantBits = 39;
815-
Value *DroppedBits = Builder.CreateSub(K.getSplat(kMaxDroppedMantBits), Lz);
816-
auto SI = constructShiftInfo(Builder, DroppedBits);
817-
// mantissa = LoPartOf(shr64(data_h, data_l, shift))
818-
Value *Mant = buildPartialRShift(Builder, UI64.Lo, UI64.Hi, SI);
819-
820-
// bool sticky_h = (data_h & ~mask) & ((1 << (shift - 32)) - 1);
821-
auto *TmpShA = Builder.CreateShl(K.getSplat(1), Builder.CreateNeg(SI.Sh32));
822-
auto *TmpMask = Builder.CreateSub(TmpShA, K.getSplat(1));
823-
auto *StickyH = Builder.CreateAnd(UI64.Hi, Builder.CreateNot(SI.Mask1));
824-
StickyH = Builder.CreateAnd(StickyH, TmpMask);
825-
826-
// bool sticky_l = (data_l & ~mask) || ((data_l & (mask >> shift));
827-
auto *SL1 = Builder.CreateAnd(UI64.Lo, Builder.CreateNot(SI.Mask1));
828-
auto *SL2 = Builder.CreateAnd(UI64.Lo, Builder.CreateLShr(SI.Mask1, SI.Sh32));
829-
auto *StickyL = Builder.CreateOr(SL1, SL2);
830-
831-
// Calculate RS
832-
// bool S = sticky_h | sticky_l;
833-
auto *S = Builder.CreateOr(StickyH, StickyL);
834-
S = Builder.CreateICmpEQ(S, K.getZero());
835-
836-
auto *notS = Builder.CreateSelect(S, K.getOnes(), K.getZero());
837-
838-
// R = Mant & 1
839-
auto *R = Builder.CreateAnd(Mant, K.getSplat(1));
840-
// mant = (mant + 0x1) >> 1;
841-
Mant =
842-
Builder.CreateLShr(Builder.CreateAdd(Mant, K.getSplat(1)), K.getSplat(1));
843-
// mant &= ~(!S & R); // R is set but no S, round to even.
844-
auto *RoundMask = Builder.CreateNot(Builder.CreateAnd(notS, R));
845-
Mant = Builder.CreateAnd(Mant, RoundMask);
846-
// 0xbd - Lz
847-
const unsigned kMaxValueExp = 0xbd;
848-
auto *Exp = Builder.CreateSub(K.getSplat(kMaxValueExp), Lz);
849-
auto *ResultLarge = Builder.CreateShl(Exp, K.getSplat(23));
850-
ResultLarge = Builder.CreateAdd(ResultLarge, Mant);
851-
852-
// NOTE: at this point ResultLarge is a integer vector
853-
// Since we calculate "optimized" route through creating yes another
854-
// UIToFP instrucion (on i32) and this shall be a vector operation,
855-
// all further calculatoins assume that we always process vectors
856-
// The cast to the final type (scalar or vector) shall be done at the end
857-
auto *VFPTy = Op.getType();
858-
if (!VFPTy->isVectorTy())
859-
VFPTy = IGCLLVM::FixedVectorType::get(Builder.getFloatTy(), 1);
860-
861-
ResultLarge = Builder.CreateBitCast(
862-
ResultLarge, VFPTy, Twine("int_emu.ui2f.l.") + Op.getOpcodeName());
863-
auto *ResultSmall = Builder.CreateUIToFP(
864-
UI64.Lo, VFPTy, Twine("int_emu.ui2f.s.") + Op.getOpcodeName());
865-
866-
auto *IsSmallPred = Builder.CreateICmpEQ(UI64.Hi, K.getZero());
867-
auto *Result = Builder.CreateSelect(IsSmallPred, ResultSmall, ResultLarge);
868-
// Final cast to the requested type (usually <1 x float> -> float)
869-
if (Op.getType() != VFPTy)
870-
Result = Builder.CreateBitCast(
871-
Result, Op.getType(), Twine("int_emu.ui2fp.") + Op.getOpcodeName());
872-
return Result;
873-
}
874-
Value *GenXEmulate::Emu64Expander::buildSI64ToFloat(SIToFPInst &Op) {
875-
IGC_ASSERT_MESSAGE(Op.getType()->getScalarType()->isFloatTy(),
876-
"SI64->fp32 conversion expected");
877-
878-
// NOTE: SIToFP is special, since it does not do the convert by itself,
879-
// Instead it just creates a sequence of 64.bit operations which
880-
// are then expanded. As such some type convertion trickery is involved.
881-
// Namely, we transform all operands to vector types type as early as possible
882-
auto Builder = getIRBuilder();
883-
auto UI64 = SplitBuilder.splitOperandLoHi(0);
884-
ConstantEmitter K(UI64.Hi);
885-
886-
auto *SignVal = Builder.CreateAnd(UI64.Hi, K.getSplat(1 << 31));
887-
auto *PredSigned = Builder.CreateICmpNE(SignVal, K.getZero());
888-
889-
auto *VOprnd = toVector(Builder, Op.getOperand(0)).V;
890-
// This would be a 64-bit operation on a vector types
891-
auto *NegatedOpnd = Builder.CreateNeg(VOprnd);
892-
NegatedOpnd = ensureEmulated(NegatedOpnd);
893-
894-
auto *AbsVal = Builder.CreateSelect(PredSigned, NegatedOpnd, VOprnd);
895-
AbsVal = ensureEmulated(AbsVal);
896-
897-
Type *CnvType = Op.getType();
898-
if (!Op.getType()->isVectorTy()) {
899-
CnvType = IGCLLVM::FixedVectorType::get(Builder.getFloatTy(), 1);
900-
}
901-
auto *Cnv = Builder.CreateUIToFP(AbsVal, CnvType);
902-
Cnv = ensureEmulated(Cnv);
903-
904-
// we want to set a proper sign, so we cast it to <N x int>,
905-
// set sign bit and cast-away to the final result
906-
Value *AsInt = Builder.CreateBitCast(Cnv, K.getVTy());
907-
auto *Result = Builder.CreateOr(AsInt, SignVal);
908-
return Builder.CreateBitCast(Result, Op.getType());
909-
}
910-
// Expands both UI64->half and SI64->half
911-
Value *GenXEmulate::Emu64Expander::buildI64ToHalf(CastInst &Op) {
912-
IGC_ASSERT_MESSAGE(Op.getType()->getScalarType()->isHalfTy(),
913-
"UI64->half or SI64->half conversion expected");
914-
915-
auto Builder = getIRBuilder();
916-
auto *FloatTy = Type::getFloatTy(Op.getContext());
917-
auto *Conv = cast<Instruction>(
918-
Builder.CreateCast(Op.getOpcode(), Op.getOperand(0),
919-
changeScalarType(Op.getType(), FloatTy)));
920-
auto *EmulatedConv = Emu64Expander{ST, *Conv}.tryExpand();
921-
Conv->eraseFromParent();
922-
return Builder.CreateFPTrunc(EmulatedConv, Op.getType(), "int_emu.truncate");
923-
}
924-
925732
Value *GenXEmulate::Emu64Expander::visitZExtInst(ZExtInst &I) {
926733
auto Builder = getIRBuilder();
927734
auto VOp = toVector(Builder, I.getOperand(0));

0 commit comments

Comments
 (0)