Skip to content

Commit 94a0dd5

Browse files
SahilPatidarSahilPatidar
and
SahilPatidar
authored
[InstCombine] Fix Failure to convert vector fp comparisons that can be represented as integers #82241 (#83274)
Resolve #82241 --------- Co-authored-by: SahilPatidar <[email protected]>
1 parent 2089596 commit 94a0dd5

File tree

4 files changed

+159
-45
lines changed

4 files changed

+159
-45
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7286,8 +7286,9 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
72867286
Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
72877287
Instruction *LHSI,
72887288
Constant *RHSC) {
7289-
if (!isa<ConstantFP>(RHSC)) return nullptr;
7290-
const APFloat &RHS = cast<ConstantFP>(RHSC)->getValueAPF();
7289+
const APFloat *RHS;
7290+
if (!match(RHSC, m_APFloat(RHS)))
7291+
return nullptr;
72917292

72927293
// Get the width of the mantissa. We don't want to hack on conversions that
72937294
// might lose information from the integer, e.g. "i64 -> float"
@@ -7302,20 +7303,20 @@ Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
73027303
FCmpInst::Predicate P = I.getPredicate();
73037304
bool IsExact = false;
73047305
APSInt RHSCvt(IntWidth, LHSUnsigned);
7305-
RHS.convertToInteger(RHSCvt, APFloat::rmNearestTiesToEven, &IsExact);
7306+
RHS->convertToInteger(RHSCvt, APFloat::rmNearestTiesToEven, &IsExact);
73067307

73077308
// If the floating point constant isn't an integer value, we know if we will
73087309
// ever compare equal / not equal to it.
73097310
if (!IsExact) {
73107311
// TODO: Can never be -0.0 and other non-representable values
7311-
APFloat RHSRoundInt(RHS);
7312+
APFloat RHSRoundInt(*RHS);
73127313
RHSRoundInt.roundToIntegral(APFloat::rmNearestTiesToEven);
7313-
if (RHS != RHSRoundInt) {
7314+
if (*RHS != RHSRoundInt) {
73147315
if (P == FCmpInst::FCMP_OEQ || P == FCmpInst::FCMP_UEQ)
7315-
return replaceInstUsesWith(I, Builder.getFalse());
7316+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
73167317

73177318
assert(P == FCmpInst::FCMP_ONE || P == FCmpInst::FCMP_UNE);
7318-
return replaceInstUsesWith(I, Builder.getTrue());
7319+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
73197320
}
73207321
}
73217322

@@ -7332,9 +7333,9 @@ Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
73327333
// to distinguish it from one less than that value.
73337334
if ((int)IntWidth > MantissaWidth) {
73347335
// Conversion would lose accuracy. Check if loss can impact comparison.
7335-
int Exp = ilogb(RHS);
7336+
int Exp = ilogb(*RHS);
73367337
if (Exp == APFloat::IEK_Inf) {
7337-
int MaxExponent = ilogb(APFloat::getLargest(RHS.getSemantics()));
7338+
int MaxExponent = ilogb(APFloat::getLargest(RHS->getSemantics()));
73387339
if (MaxExponent < (int)IntWidth - !LHSUnsigned)
73397340
// Conversion could create infinity.
73407341
return nullptr;
@@ -7350,7 +7351,7 @@ Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
73507351
// Otherwise, we can potentially simplify the comparison. We know that it
73517352
// will always come through as an integer value and we know the constant is
73527353
// not a NAN (it would have been previously simplified).
7353-
assert(!RHS.isNaN() && "NaN comparison not already folded!");
7354+
assert(!RHS->isNaN() && "NaN comparison not already folded!");
73547355

73557356
ICmpInst::Predicate Pred;
73567357
switch (I.getPredicate()) {
@@ -7380,9 +7381,9 @@ Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
73807381
Pred = ICmpInst::ICMP_NE;
73817382
break;
73827383
case FCmpInst::FCMP_ORD:
7383-
return replaceInstUsesWith(I, Builder.getTrue());
7384+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
73847385
case FCmpInst::FCMP_UNO:
7385-
return replaceInstUsesWith(I, Builder.getFalse());
7386+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
73867387
}
73877388

73887389
// Now we know that the APFloat is a normal number, zero or inf.
@@ -7392,50 +7393,50 @@ Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
73927393
if (!LHSUnsigned) {
73937394
// If the RHS value is > SignedMax, fold the comparison. This handles +INF
73947395
// and large values.
7395-
APFloat SMax(RHS.getSemantics());
7396+
APFloat SMax(RHS->getSemantics());
73967397
SMax.convertFromAPInt(APInt::getSignedMaxValue(IntWidth), true,
73977398
APFloat::rmNearestTiesToEven);
7398-
if (SMax < RHS) { // smax < 13123.0
7399+
if (SMax < *RHS) { // smax < 13123.0
73997400
if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SLT ||
74007401
Pred == ICmpInst::ICMP_SLE)
7401-
return replaceInstUsesWith(I, Builder.getTrue());
7402-
return replaceInstUsesWith(I, Builder.getFalse());
7402+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
7403+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
74037404
}
74047405
} else {
74057406
// If the RHS value is > UnsignedMax, fold the comparison. This handles
74067407
// +INF and large values.
7407-
APFloat UMax(RHS.getSemantics());
7408+
APFloat UMax(RHS->getSemantics());
74087409
UMax.convertFromAPInt(APInt::getMaxValue(IntWidth), false,
74097410
APFloat::rmNearestTiesToEven);
7410-
if (UMax < RHS) { // umax < 13123.0
7411+
if (UMax < *RHS) { // umax < 13123.0
74117412
if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_ULT ||
74127413
Pred == ICmpInst::ICMP_ULE)
7413-
return replaceInstUsesWith(I, Builder.getTrue());
7414-
return replaceInstUsesWith(I, Builder.getFalse());
7414+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
7415+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
74157416
}
74167417
}
74177418

74187419
if (!LHSUnsigned) {
74197420
// See if the RHS value is < SignedMin.
7420-
APFloat SMin(RHS.getSemantics());
7421+
APFloat SMin(RHS->getSemantics());
74217422
SMin.convertFromAPInt(APInt::getSignedMinValue(IntWidth), true,
74227423
APFloat::rmNearestTiesToEven);
7423-
if (SMin > RHS) { // smin > 12312.0
7424+
if (SMin > *RHS) { // smin > 12312.0
74247425
if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_SGT ||
74257426
Pred == ICmpInst::ICMP_SGE)
7426-
return replaceInstUsesWith(I, Builder.getTrue());
7427-
return replaceInstUsesWith(I, Builder.getFalse());
7427+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
7428+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
74287429
}
74297430
} else {
74307431
// See if the RHS value is < UnsignedMin.
7431-
APFloat UMin(RHS.getSemantics());
7432+
APFloat UMin(RHS->getSemantics());
74327433
UMin.convertFromAPInt(APInt::getMinValue(IntWidth), false,
74337434
APFloat::rmNearestTiesToEven);
7434-
if (UMin > RHS) { // umin > 12312.0
7435+
if (UMin > *RHS) { // umin > 12312.0
74357436
if (Pred == ICmpInst::ICMP_NE || Pred == ICmpInst::ICMP_UGT ||
74367437
Pred == ICmpInst::ICMP_UGE)
7437-
return replaceInstUsesWith(I, Builder.getTrue());
7438-
return replaceInstUsesWith(I, Builder.getFalse());
7438+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
7439+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
74397440
}
74407441
}
74417442

@@ -7445,66 +7446,66 @@ Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
74457446
// Don't do this for zero, because -0.0 is not fractional.
74467447
APSInt RHSInt(IntWidth, LHSUnsigned);
74477448
bool IsExact;
7448-
RHS.convertToInteger(RHSInt, APFloat::rmTowardZero, &IsExact);
7449-
if (!RHS.isZero()) {
7449+
RHS->convertToInteger(RHSInt, APFloat::rmTowardZero, &IsExact);
7450+
if (!RHS->isZero()) {
74507451
if (!IsExact) {
74517452
// If we had a comparison against a fractional value, we have to adjust
74527453
// the compare predicate and sometimes the value. RHSC is rounded towards
74537454
// zero at this point.
74547455
switch (Pred) {
74557456
default: llvm_unreachable("Unexpected integer comparison!");
74567457
case ICmpInst::ICMP_NE: // (float)int != 4.4 --> true
7457-
return replaceInstUsesWith(I, Builder.getTrue());
7458+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
74587459
case ICmpInst::ICMP_EQ: // (float)int == 4.4 --> false
7459-
return replaceInstUsesWith(I, Builder.getFalse());
7460+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
74607461
case ICmpInst::ICMP_ULE:
74617462
// (float)int <= 4.4 --> int <= 4
74627463
// (float)int <= -4.4 --> false
7463-
if (RHS.isNegative())
7464-
return replaceInstUsesWith(I, Builder.getFalse());
7464+
if (RHS->isNegative())
7465+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
74657466
break;
74667467
case ICmpInst::ICMP_SLE:
74677468
// (float)int <= 4.4 --> int <= 4
74687469
// (float)int <= -4.4 --> int < -4
7469-
if (RHS.isNegative())
7470+
if (RHS->isNegative())
74707471
Pred = ICmpInst::ICMP_SLT;
74717472
break;
74727473
case ICmpInst::ICMP_ULT:
74737474
// (float)int < -4.4 --> false
74747475
// (float)int < 4.4 --> int <= 4
7475-
if (RHS.isNegative())
7476-
return replaceInstUsesWith(I, Builder.getFalse());
7476+
if (RHS->isNegative())
7477+
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
74777478
Pred = ICmpInst::ICMP_ULE;
74787479
break;
74797480
case ICmpInst::ICMP_SLT:
74807481
// (float)int < -4.4 --> int < -4
74817482
// (float)int < 4.4 --> int <= 4
7482-
if (!RHS.isNegative())
7483+
if (!RHS->isNegative())
74837484
Pred = ICmpInst::ICMP_SLE;
74847485
break;
74857486
case ICmpInst::ICMP_UGT:
74867487
// (float)int > 4.4 --> int > 4
74877488
// (float)int > -4.4 --> true
7488-
if (RHS.isNegative())
7489-
return replaceInstUsesWith(I, Builder.getTrue());
7489+
if (RHS->isNegative())
7490+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
74907491
break;
74917492
case ICmpInst::ICMP_SGT:
74927493
// (float)int > 4.4 --> int > 4
74937494
// (float)int > -4.4 --> int >= -4
7494-
if (RHS.isNegative())
7495+
if (RHS->isNegative())
74957496
Pred = ICmpInst::ICMP_SGE;
74967497
break;
74977498
case ICmpInst::ICMP_UGE:
74987499
// (float)int >= -4.4 --> true
74997500
// (float)int >= 4.4 --> int > 4
7500-
if (RHS.isNegative())
7501-
return replaceInstUsesWith(I, Builder.getTrue());
7501+
if (RHS->isNegative())
7502+
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
75027503
Pred = ICmpInst::ICMP_UGT;
75037504
break;
75047505
case ICmpInst::ICMP_SGE:
75057506
// (float)int >= -4.4 --> int >= -4
75067507
// (float)int >= 4.4 --> int > 4
7507-
if (!RHS.isNegative())
7508+
if (!RHS->isNegative())
75087509
Pred = ICmpInst::ICMP_SGT;
75097510
break;
75107511
}
@@ -7513,7 +7514,8 @@ Instruction *InstCombinerImpl::foldFCmpIntToFPConst(FCmpInst &I,
75137514

75147515
// Lower this FP comparison into an appropriate integer version of the
75157516
// comparison.
7516-
return new ICmpInst(Pred, LHSI->getOperand(0), Builder.getInt(RHSInt));
7517+
return new ICmpInst(Pred, LHSI->getOperand(0),
7518+
ConstantInt::get(LHSI->getOperand(0)->getType(), RHSInt));
75177519
}
75187520

75197521
/// Fold (C / X) < 0.0 --> X < 0.0 if possible. Swap predicate if necessary.

llvm/test/Transforms/InstCombine/cast-int-fcmp-eq-0.ll

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,3 +509,61 @@ define i1 @i128_cast_cmp_oeq_int_inf_uitofp(i128 %i) {
509509
%cmp = fcmp oeq float %f, 0x7FF0000000000000
510510
ret i1 %cmp
511511
}
512+
513+
define <2 x i1> @i32_vec_cast_cmp_oeq_vec_int_0_sitofp(<2 x i32> %i) {
514+
; CHECK-LABEL: @i32_vec_cast_cmp_oeq_vec_int_0_sitofp(
515+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[I:%.*]], zeroinitializer
516+
; CHECK-NEXT: ret <2 x i1> [[CMP]]
517+
;
518+
%f = sitofp <2 x i32> %i to <2 x float>
519+
%cmp = fcmp oeq <2 x float> %f, <float 0.0, float 0.0>
520+
ret <2 x i1> %cmp
521+
}
522+
523+
define <2 x i1> @i32_vec_cast_cmp_oeq_vec_int_n0_sitofp(<2 x i32> %i) {
524+
; CHECK-LABEL: @i32_vec_cast_cmp_oeq_vec_int_n0_sitofp(
525+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[I:%.*]], zeroinitializer
526+
; CHECK-NEXT: ret <2 x i1> [[CMP]]
527+
;
528+
%f = sitofp <2 x i32> %i to <2 x float>
529+
%cmp = fcmp oeq <2 x float> %f, <float -0.0, float -0.0>
530+
ret <2 x i1> %cmp
531+
}
532+
533+
define <2 x i1> @i32_vec_cast_cmp_oeq_vec_int_i32imax_sitofp(<2 x i32> %i) {
534+
; CHECK-LABEL: @i32_vec_cast_cmp_oeq_vec_int_i32imax_sitofp(
535+
; CHECK-NEXT: [[F:%.*]] = sitofp <2 x i32> [[I:%.*]] to <2 x float>
536+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <2 x float> [[F]], <float 0x41E0000000000000, float 0x41E0000000000000>
537+
; CHECK-NEXT: ret <2 x i1> [[CMP]]
538+
;
539+
%f = sitofp <2 x i32> %i to <2 x float>
540+
%cmp = fcmp oeq <2 x float> %f, <float 0x41E0000000000000, float 0x41E0000000000000>
541+
ret <2 x i1> %cmp
542+
}
543+
544+
define <2 x i1> @i32_vec_cast_cmp_oeq_vec_int_negi32umax_sitofp(<2 x i32> %i) {
545+
; CHECK-LABEL: @i32_vec_cast_cmp_oeq_vec_int_negi32umax_sitofp(
546+
; CHECK-NEXT: ret <2 x i1> zeroinitializer
547+
;
548+
%f = sitofp <2 x i32> %i to <2 x float>
549+
%cmp = fcmp oeq <2 x float> %f, <float 0xC1F0000000000000, float 0xC1F0000000000000>
550+
ret <2 x i1> %cmp
551+
}
552+
553+
define <2 x i1> @i32_vec_cast_cmp_oeq_vec_half_sitofp(<2 x i32> %i) {
554+
; CHECK-LABEL: @i32_vec_cast_cmp_oeq_vec_half_sitofp(
555+
; CHECK-NEXT: ret <2 x i1> zeroinitializer
556+
;
557+
%f = sitofp <2 x i32> %i to <2 x float>
558+
%cmp = fcmp oeq <2 x float> %f, <float 0.5, float 0.5>
559+
ret <2 x i1> %cmp
560+
}
561+
562+
define <2 x i1> @i32_vec_cast_cmp_oeq_vec_int_inf_sitofp(<2 x i32> %i) {
563+
; CHECK-LABEL: @i32_vec_cast_cmp_oeq_vec_int_inf_sitofp(
564+
; CHECK-NEXT: ret <2 x i1> zeroinitializer
565+
;
566+
%f = sitofp <2 x i32> %i to <2 x float>
567+
%cmp = fcmp oeq <2 x float> %f, <float 0x7FF0000000000000, float 0x7FF0000000000000>
568+
ret <2 x i1> %cmp
569+
}

llvm/test/Transforms/InstCombine/clamp-to-minmax.ll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,3 +566,20 @@ define i32 @mixed_clamp_to_i32_2(float %x) {
566566
%r = select i1 %lo_cmp, i32 1, i32 %i32_min
567567
ret i32 %r
568568
}
569+
570+
571+
define <2 x float> @mixed_clamp_to_float_vec(<2 x i32> %x) {
572+
; CHECK-LABEL: @mixed_clamp_to_float_vec(
573+
; CHECK-NEXT: [[SI_MIN:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 255, i32 255>)
574+
; CHECK-NEXT: [[R1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[SI_MIN]], <2 x i32> <i32 1, i32 1>)
575+
; CHECK-NEXT: [[R:%.*]] = sitofp <2 x i32> [[R1]] to <2 x float>
576+
; CHECK-NEXT: ret <2 x float> [[R]]
577+
;
578+
%si_min_cmp = icmp sgt <2 x i32> %x, <i32 255, i32 255>
579+
%si_min = select <2 x i1> %si_min_cmp, <2 x i32> <i32 255, i32 255>, <2 x i32> %x
580+
%f_min = sitofp <2 x i32> %si_min to <2 x float>
581+
%f_x = sitofp <2 x i32> %x to <2 x float>
582+
%lo_cmp = fcmp ult <2 x float> %f_x, <float 1.0, float 1.0>
583+
%r = select <2 x i1> %lo_cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %f_min
584+
ret <2 x float> %r
585+
}

llvm/test/Transforms/InstCombine/sitofp.ll

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,40 @@ define i12 @u32_half_u12(i32 %x) {
378378
%r = fptoui half %h to i12
379379
ret i12 %r
380380
}
381+
382+
define <2 x i1> @i8_vec_sitofp_test1(<2 x i8> %A) {
383+
; CHECK-LABEL: @i8_vec_sitofp_test1(
384+
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
385+
;
386+
%B = sitofp <2 x i8> %A to <2 x double>
387+
%C = fcmp ult <2 x double> %B, <double 128.0, double 128.0>
388+
ret <2 x i1> %C
389+
}
390+
391+
define <2 x i1> @i8_vec_sitofp_test2(<2 x i8> %A) {
392+
; CHECK-LABEL: @i8_vec_sitofp_test2(
393+
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
394+
;
395+
%B = sitofp <2 x i8> %A to <2 x double>
396+
%C = fcmp ugt <2 x double> %B, <double -128.1, double -128.1>
397+
ret <2 x i1> %C
398+
}
399+
400+
define <2 x i1> @i8_vec_sitofp_test3(<2 x i8> %A) {
401+
; CHECK-LABEL: @i8_vec_sitofp_test3(
402+
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
403+
;
404+
%B = sitofp <2 x i8> %A to <2 x double>
405+
%C = fcmp ule <2 x double> %B, <double 127.0, double 127.0>
406+
ret <2 x i1> %C
407+
}
408+
409+
define <2 x i1> @i8_vec_sitofp_test4(<2 x i8> %A) {
410+
; CHECK-LABEL: @i8_vec_sitofp_test4(
411+
; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], <i8 127, i8 127>
412+
; CHECK-NEXT: ret <2 x i1> [[C]]
413+
;
414+
%B = sitofp <2 x i8> %A to <2 x double>
415+
%C = fcmp ult <2 x double> %B, <double 127.0, double 127.0>
416+
ret <2 x i1> %C
417+
}

0 commit comments

Comments
 (0)