Skip to content

Commit bb6c35c

Browse files
committed
[GlobalISel][AArch6] Add G_FPTOSI_SAT/G_FPTOUI_SAT
This is an implementation of the saturating fp to int conversions for GlobalISel. On AArch64 the converstion instrctions work this way, producing saturating results. LegalizerHelper::lowerFPTOINT_SAT is ported from SDAG. AArch64 has a lot of existing tests for fptosi_sat, covering a wide range of types. I have tried to make most of them work all at once, but a few fall back due to other missing features such as f128 handling for min/max.
1 parent bded3b3 commit bb6c35c

16 files changed

+1387
-560
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,11 @@ G_FPTOSI, G_FPTOUI, G_SITOFP, G_UITOFP
504504

505505
Convert between integer and floating point.
506506

507+
G_FPTOSI_SAT, G_FPTOUI_SAT
508+
^^^^^^^^^^^^^^^^^^^^^^^^^^
509+
510+
Saturating convert between integer and floating point.
511+
507512
G_FABS
508513
^^^^^^
509514

llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,8 @@ class GCastOp : public GenericMachineInstr {
823823
case TargetOpcode::G_FPEXT:
824824
case TargetOpcode::G_FPTOSI:
825825
case TargetOpcode::G_FPTOUI:
826+
case TargetOpcode::G_FPTOSI_SAT:
827+
case TargetOpcode::G_FPTOUI_SAT:
826828
case TargetOpcode::G_FPTRUNC:
827829
case TargetOpcode::G_INTTOPTR:
828830
case TargetOpcode::G_PTRTOINT:

llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class LegalizerHelper {
398398
LegalizeResult lowerSITOFP(MachineInstr &MI);
399399
LegalizeResult lowerFPTOUI(MachineInstr &MI);
400400
LegalizeResult lowerFPTOSI(MachineInstr &MI);
401+
LegalizeResult lowerFPTOINT_SAT(MachineInstr &MI);
401402

402403
LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI);
403404
LegalizeResult lowerFPTRUNC(MachineInstr &MI);

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,16 @@ class MachineIRBuilder {
20002000
return buildInstr(TargetOpcode::G_FPTOSI, {Dst}, {Src0});
20012001
}
20022002

2003+
/// Build and insert \p Res = G_FPTOUI_SAT \p Src0
2004+
MachineInstrBuilder buildFPTOUI_SAT(const DstOp &Dst, const SrcOp &Src0) {
2005+
return buildInstr(TargetOpcode::G_FPTOUI_SAT, {Dst}, {Src0});
2006+
}
2007+
2008+
/// Build and insert \p Res = G_FPTOSI_SAT \p Src0
2009+
MachineInstrBuilder buildFPTOSI_SAT(const DstOp &Dst, const SrcOp &Src0) {
2010+
return buildInstr(TargetOpcode::G_FPTOSI_SAT, {Dst}, {Src0});
2011+
}
2012+
20032013
/// Build and insert \p Dst = G_INTRINSIC_ROUNDEVEN \p Src0, \p Src1
20042014
MachineInstrBuilder
20052015
buildIntrinsicRoundeven(const DstOp &Dst, const SrcOp &Src0,

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,12 @@ HANDLE_TARGET_OPCODE(G_SITOFP)
682682
/// Generic unsigned-int to float conversion
683683
HANDLE_TARGET_OPCODE(G_UITOFP)
684684

685+
/// Generic saturating float to signed-int conversion
686+
HANDLE_TARGET_OPCODE(G_FPTOSI_SAT)
687+
688+
/// Generic saturating float to unsigned-int conversion
689+
HANDLE_TARGET_OPCODE(G_FPTOUI_SAT)
690+
685691
/// Generic FP absolute value.
686692
HANDLE_TARGET_OPCODE(G_FABS)
687693

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,18 @@ def G_UITOFP : GenericInstruction {
769769
let hasSideEffects = false;
770770
}
771771

772+
def G_FPTOSI_SAT : GenericInstruction {
773+
let OutOperandList = (outs type0:$dst);
774+
let InOperandList = (ins type1:$src);
775+
let hasSideEffects = false;
776+
}
777+
778+
def G_FPTOUI_SAT : GenericInstruction {
779+
let OutOperandList = (outs type0:$dst);
780+
let InOperandList = (ins type1:$src);
781+
let hasSideEffects = false;
782+
}
783+
772784
def G_FABS : GenericInstruction {
773785
let OutOperandList = (outs type0:$dst);
774786
let InOperandList = (ins type0:$src);

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ def : GINodeEquiv<G_FPTOSI, fp_to_sint>;
9898
def : GINodeEquiv<G_FPTOUI, fp_to_uint>;
9999
def : GINodeEquiv<G_SITOFP, sint_to_fp>;
100100
def : GINodeEquiv<G_UITOFP, uint_to_fp>;
101+
def : GINodeEquiv<G_FPTOSI_SAT, fp_to_sint_sat>;
102+
def : GINodeEquiv<G_FPTOUI_SAT, fp_to_uint_sat>;
101103
def : GINodeEquiv<G_FADD, fadd>;
102104
def : GINodeEquiv<G_FSUB, fsub>;
103105
def : GINodeEquiv<G_FMA, fma>;

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,6 +2340,14 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
23402340
MachineInstr::copyFlagsFromInstruction(CI));
23412341
return true;
23422342
}
2343+
case Intrinsic::fptosi_sat:
2344+
MIRBuilder.buildFPTOSI_SAT(getOrCreateVReg(CI),
2345+
getOrCreateVReg(*CI.getArgOperand(0)));
2346+
return true;
2347+
case Intrinsic::fptoui_sat:
2348+
MIRBuilder.buildFPTOUI_SAT(getOrCreateVReg(CI),
2349+
getOrCreateVReg(*CI.getArgOperand(0)));
2350+
return true;
23432351
case Intrinsic::memcpy_inline:
23442352
return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
23452353
case Intrinsic::memcpy:

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
18801880
}
18811881
case TargetOpcode::G_FPTOUI:
18821882
case TargetOpcode::G_FPTOSI:
1883+
case TargetOpcode::G_FPTOUI_SAT:
1884+
case TargetOpcode::G_FPTOSI_SAT:
18831885
return narrowScalarFPTOI(MI, TypeIdx, NarrowTy);
18841886
case TargetOpcode::G_FPEXT:
18851887
if (TypeIdx != 0)
@@ -2872,6 +2874,47 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
28722874
else
28732875
widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
28742876

2877+
Observer.changedInstr(MI);
2878+
return Legalized;
2879+
case TargetOpcode::G_FPTOSI_SAT:
2880+
case TargetOpcode::G_FPTOUI_SAT:
2881+
Observer.changingInstr(MI);
2882+
2883+
if (TypeIdx == 0) {
2884+
Register OldDst = MI.getOperand(0).getReg();
2885+
LLT Ty = MRI.getType(OldDst);
2886+
Register ExtReg = MRI.createGenericVirtualRegister(WideTy);
2887+
Register NewDst;
2888+
MI.getOperand(0).setReg(ExtReg);
2889+
uint64_t ShortBits = Ty.getScalarSizeInBits();
2890+
uint64_t WideBits = WideTy.getScalarSizeInBits();
2891+
MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
2892+
if (Opcode == TargetOpcode::G_FPTOSI_SAT) {
2893+
// z = i16 fptosi_sat(a)
2894+
// ->
2895+
// x = i32 fptosi_sat(a)
2896+
// y = smin(x, 32767)
2897+
// z = smax(y, -32768)
2898+
auto MaxVal = MIRBuilder.buildConstant(
2899+
WideTy, APInt::getSignedMaxValue(ShortBits).sext(WideBits));
2900+
auto MinVal = MIRBuilder.buildConstant(
2901+
WideTy, APInt::getSignedMinValue(ShortBits).sext(WideBits));
2902+
Register MidReg =
2903+
MIRBuilder.buildSMin(WideTy, ExtReg, MaxVal).getReg(0);
2904+
NewDst = MIRBuilder.buildSMax(WideTy, MidReg, MinVal).getReg(0);
2905+
} else {
2906+
// z = i16 fptoui_sat(a)
2907+
// ->
2908+
// x = i32 fptoui_sat(a)
2909+
// y = smin(x, 65535)
2910+
auto MaxVal = MIRBuilder.buildConstant(
2911+
WideTy, APInt::getAllOnes(ShortBits).zext(WideBits));
2912+
NewDst = MIRBuilder.buildUMin(WideTy, ExtReg, MaxVal).getReg(0);
2913+
}
2914+
MIRBuilder.buildTrunc(OldDst, NewDst);
2915+
} else
2916+
widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
2917+
28752918
Observer.changedInstr(MI);
28762919
return Legalized;
28772920
case TargetOpcode::G_LOAD:
@@ -4170,6 +4213,9 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
41704213
return lowerFPTOUI(MI);
41714214
case G_FPTOSI:
41724215
return lowerFPTOSI(MI);
4216+
case G_FPTOUI_SAT:
4217+
case G_FPTOSI_SAT:
4218+
return lowerFPTOINT_SAT(MI);
41734219
case G_FPTRUNC:
41744220
return lowerFPTRUNC(MI);
41754221
case G_FPOWI:
@@ -4986,6 +5032,8 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
49865032
case G_UITOFP:
49875033
case G_FPTOSI:
49885034
case G_FPTOUI:
5035+
case G_FPTOSI_SAT:
5036+
case G_FPTOUI_SAT:
49895037
case G_INTTOPTR:
49905038
case G_PTRTOINT:
49915039
case G_ADDRSPACE_CAST:
@@ -5777,6 +5825,8 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
57775825
case TargetOpcode::G_FPEXT:
57785826
case TargetOpcode::G_FPTOSI:
57795827
case TargetOpcode::G_FPTOUI:
5828+
case TargetOpcode::G_FPTOSI_SAT:
5829+
case TargetOpcode::G_FPTOUI_SAT:
57805830
case TargetOpcode::G_SITOFP:
57815831
case TargetOpcode::G_UITOFP: {
57825832
Observer.changingInstr(MI);
@@ -7285,6 +7335,103 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPTOSI(MachineInstr &MI) {
72857335
return Legalized;
72867336
}
72877337

7338+
LegalizerHelper::LegalizeResult
7339+
LegalizerHelper::lowerFPTOINT_SAT(MachineInstr &MI) {
7340+
auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
7341+
7342+
bool IsSigned = MI.getOpcode() == TargetOpcode::G_FPTOSI_SAT;
7343+
unsigned SatWidth = DstTy.getScalarSizeInBits();
7344+
7345+
// Determine minimum and maximum integer values and their corresponding
7346+
// floating-point values.
7347+
APInt MinInt, MaxInt;
7348+
if (IsSigned) {
7349+
MinInt = APInt::getSignedMinValue(SatWidth);
7350+
MaxInt = APInt::getSignedMaxValue(SatWidth);
7351+
} else {
7352+
MinInt = APInt::getMinValue(SatWidth);
7353+
MaxInt = APInt::getMaxValue(SatWidth);
7354+
}
7355+
7356+
const fltSemantics &Semantics = getFltSemanticForLLT(SrcTy.getScalarType());
7357+
APFloat MinFloat(Semantics);
7358+
APFloat MaxFloat(Semantics);
7359+
7360+
APFloat::opStatus MinStatus =
7361+
MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero);
7362+
APFloat::opStatus MaxStatus =
7363+
MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero);
7364+
bool AreExactFloatBounds = !(MinStatus & APFloat::opStatus::opInexact) &&
7365+
!(MaxStatus & APFloat::opStatus::opInexact);
7366+
7367+
// If the integer bounds are exactly representable as floats and min/max are
7368+
// legal, emit a min+max+fptoi sequence. Otherwise we have to use a sequence
7369+
// of comparisons and selects.
7370+
bool MinMaxLegal = LI.isLegal({TargetOpcode::G_FMINNUM, SrcTy}) &&
7371+
LI.isLegal({TargetOpcode::G_FMAXNUM, SrcTy});
7372+
if (AreExactFloatBounds && MinMaxLegal) {
7373+
// Clamp Src by MinFloat from below. If Src is NaN the result is MinFloat.
7374+
auto Max = MIRBuilder.buildFMaxNum(
7375+
SrcTy, Src, MIRBuilder.buildFConstant(SrcTy, MinFloat));
7376+
// Clamp by MaxFloat from above. NaN cannot occur.
7377+
auto Min = MIRBuilder.buildFMinNum(
7378+
SrcTy, Max, MIRBuilder.buildFConstant(SrcTy, MaxFloat),
7379+
MachineInstr::FmNoNans);
7380+
// Convert clamped value to integer. In the unsigned case we're done,
7381+
// because we mapped NaN to MinFloat, which will cast to zero.
7382+
if (!IsSigned) {
7383+
MIRBuilder.buildFPTOUI(Dst, Min);
7384+
MI.eraseFromParent();
7385+
return Legalized;
7386+
}
7387+
7388+
// Otherwise, select 0 if Src is NaN.
7389+
auto FpToInt = MIRBuilder.buildFPTOSI(DstTy, Min);
7390+
auto IsZero = MIRBuilder.buildFCmp(CmpInst::FCMP_UNO,
7391+
DstTy.changeElementSize(1), Src, Src);
7392+
MIRBuilder.buildSelect(Dst, IsZero, MIRBuilder.buildConstant(DstTy, 0),
7393+
FpToInt);
7394+
MI.eraseFromParent();
7395+
return Legalized;
7396+
}
7397+
7398+
// Result of direct conversion. The assumption here is that the operation is
7399+
// non-trapping and it's fine to apply it to an out-of-range value if we
7400+
// select it away later.
7401+
auto FpToInt = IsSigned ? MIRBuilder.buildFPTOSI(DstTy, Src)
7402+
: MIRBuilder.buildFPTOUI(DstTy, Src);
7403+
7404+
// If Src ULT MinFloat, select MinInt. In particular, this also selects
7405+
// MinInt if Src is NaN.
7406+
auto ULT =
7407+
MIRBuilder.buildFCmp(CmpInst::FCMP_ULT, SrcTy.changeElementSize(1), Src,
7408+
MIRBuilder.buildFConstant(SrcTy, MinFloat));
7409+
auto Max = MIRBuilder.buildSelect(
7410+
DstTy, ULT, MIRBuilder.buildConstant(DstTy, MinInt), FpToInt);
7411+
// If Src OGT MaxFloat, select MaxInt.
7412+
auto OGT =
7413+
MIRBuilder.buildFCmp(CmpInst::FCMP_OGT, SrcTy.changeElementSize(1), Src,
7414+
MIRBuilder.buildFConstant(SrcTy, MaxFloat));
7415+
7416+
// In the unsigned case we are done, because we mapped NaN to MinInt, which
7417+
// is already zero.
7418+
if (!IsSigned) {
7419+
MIRBuilder.buildSelect(Dst, OGT, MIRBuilder.buildConstant(DstTy, MaxInt),
7420+
Max, MachineInstr::FmNoNans);
7421+
MI.eraseFromParent();
7422+
return Legalized;
7423+
}
7424+
7425+
// Otherwise, select 0 if Src is NaN.
7426+
auto Min = MIRBuilder.buildSelect(
7427+
DstTy, OGT, MIRBuilder.buildConstant(DstTy, MaxInt), Max);
7428+
auto IsZero = MIRBuilder.buildFCmp(CmpInst::FCMP_UNO,
7429+
DstTy.changeElementSize(1), Src, Src);
7430+
MIRBuilder.buildSelect(Dst, IsZero, MIRBuilder.buildConstant(DstTy, 0), Min);
7431+
MI.eraseFromParent();
7432+
return Legalized;
7433+
}
7434+
72887435
// f64 -> f16 conversion using round-to-nearest-even rounding mode.
72897436
LegalizerHelper::LegalizeResult
72907437
LegalizerHelper::lowerFPTRUNC_F64_TO_F16(MachineInstr &MI) {

llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,6 +2152,12 @@ bool AArch64InstructionSelector::preISelLower(MachineInstr &I) {
21522152
}
21532153
return false;
21542154
}
2155+
case TargetOpcode::G_FPTOSI_SAT:
2156+
I.setDesc(TII.get(TargetOpcode::G_FPTOSI));
2157+
return true;
2158+
case TargetOpcode::G_FPTOUI_SAT:
2159+
I.setDesc(TII.get(TargetOpcode::G_FPTOUI));
2160+
return true;
21552161
default:
21562162
return false;
21572163
}

llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,55 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
728728
.libcallFor(
729729
{{s32, s128}, {s64, s128}, {s128, s128}, {s128, s32}, {s128, s64}});
730730

731+
getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
732+
.legalFor({{s32, s32},
733+
{s64, s32},
734+
{s32, s64},
735+
{s64, s64},
736+
{v2s64, v2s64},
737+
{v4s32, v4s32},
738+
{v2s32, v2s32}})
739+
.legalIf([=](const LegalityQuery &Query) {
740+
return HasFP16 &&
741+
(Query.Types[1] == s16 || Query.Types[1] == v4s16 ||
742+
Query.Types[1] == v8s16) &&
743+
(Query.Types[0] == s32 || Query.Types[0] == s64 ||
744+
Query.Types[0] == v4s16 || Query.Types[0] == v8s16);
745+
})
746+
// Handle types larger than i64 by scalarizing/lowering.
747+
.scalarizeIf(scalarOrEltWiderThan(0, 64), 0)
748+
.scalarizeIf(scalarOrEltWiderThan(1, 64), 1)
749+
// The range of a fp16 value fits into an i17, so we can lower the width
750+
// to i64.
751+
.narrowScalarIf(
752+
[=](const LegalityQuery &Query) {
753+
return Query.Types[1] == s16 && Query.Types[0].getSizeInBits() > 64;
754+
},
755+
changeTo(0, s64))
756+
.lowerIf(::any(scalarWiderThan(0, 64), scalarWiderThan(1, 64)), 0)
757+
.moreElementsToNextPow2(0)
758+
.widenScalarToNextPow2(0, /*MinSize=*/32)
759+
.minScalar(0, s32)
760+
.widenScalarOrEltToNextPow2OrMinSize(1, /*MinSize=*/HasFP16 ? 16 : 32)
761+
.widenScalarIf(
762+
[=](const LegalityQuery &Query) {
763+
unsigned ITySize = Query.Types[0].getScalarSizeInBits();
764+
return (ITySize == 16 || ITySize == 32 || ITySize == 64) &&
765+
ITySize > Query.Types[1].getScalarSizeInBits();
766+
},
767+
LegalizeMutations::changeElementSizeTo(1, 0))
768+
.widenScalarIf(
769+
[=](const LegalityQuery &Query) {
770+
unsigned FTySize = Query.Types[1].getScalarSizeInBits();
771+
return (FTySize == 16 || FTySize == 32 || FTySize == 64) &&
772+
Query.Types[0].getScalarSizeInBits() < FTySize;
773+
},
774+
LegalizeMutations::changeElementSizeTo(0, 1))
775+
.widenScalarOrEltToNextPow2(0)
776+
.clampNumElements(0, v4s16, v8s16)
777+
.clampNumElements(0, v2s32, v4s32)
778+
.clampMaxNumElements(0, s64, 2);
779+
731780
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
732781
.legalFor({{s32, s32},
733782
{s64, s32},

llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,8 @@ bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
535535
switch (MI.getOpcode()) {
536536
case TargetOpcode::G_FPTOSI:
537537
case TargetOpcode::G_FPTOUI:
538+
case TargetOpcode::G_FPTOSI_SAT:
539+
case TargetOpcode::G_FPTOUI_SAT:
538540
case TargetOpcode::G_FCMP:
539541
case TargetOpcode::G_LROUND:
540542
case TargetOpcode::G_LLROUND:
@@ -799,6 +801,8 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
799801
}
800802
case TargetOpcode::G_FPTOSI:
801803
case TargetOpcode::G_FPTOUI:
804+
case TargetOpcode::G_FPTOSI_SAT:
805+
case TargetOpcode::G_FPTOUI_SAT:
802806
case TargetOpcode::G_INTRINSIC_LRINT:
803807
case TargetOpcode::G_INTRINSIC_LLRINT:
804808
if (MRI.getType(MI.getOperand(0).getReg()).isVector())

llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,13 @@
538538
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
539539
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
540540
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
541+
# DEBUG-NEXT: G_FPTOSI_SAT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
542+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
543+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
544+
# DEBUG-NEXT: G_FPTOUI_SAT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
545+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
546+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
547+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
541548
# DEBUG-NEXT: G_FABS (opcode {{[0-9]+}}): 1 type index, 0 imm indices
542549
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
543550
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected

0 commit comments

Comments
 (0)